Support dev servers defined in a mojoconfig file.
This patch allows one to define local servers to be set up by devtools
(`mojo_run` / `mojo_test`) in a config file. Each server is described as a
dictionary defining the host and the mappings:
{
'host': 'https://core.mojoapps.io/',
'mappings': [
('packages/', ['@{BUILD_DIR}/gen/dart-pkg/packages']),
('', ['@{BUILD_DIR}']),
],
},
This allows us to support running 'exploded' dart apps, see
https://github.com/domokit/devtools/issues/30 .
This patch also adds an example config file for the setup we will want to use
in the Mojo repo. As of this CL one has to explicitly pass --config-file
mojoconfig to make use of the config file. We will probably want to make
devtools discover this file automatically.
R=qsr@chromium.org
Review URL: https://codereview.chromium.org/1259793008 .
Cr-Mirrored-From: https://github.com/domokit/mojo
Cr-Mirrored-Commit: 7b674fecee63ca43a90d32a3405eea5e2707883e
diff --git a/devtoolslib/http_server.py b/devtoolslib/http_server.py
index 6afd6a0..a74be0d 100644
--- a/devtoolslib/http_server.py
+++ b/devtoolslib/http_server.py
@@ -203,9 +203,6 @@
http_thread = threading.Thread(target=httpd.serve_forever)
http_thread.daemon = True
http_thread.start()
- print 'Started http://%s:%d to host %s.' % (httpd.server_address[0],
- httpd.server_address[1],
- str(mappings))
return httpd.server_address
except socket.error as v:
error_code = v[0]
diff --git a/devtoolslib/shell_arguments.py b/devtoolslib/shell_arguments.py
index 89d66e4..bd13755 100644
--- a/devtoolslib/shell_arguments.py
+++ b/devtoolslib/shell_arguments.py
@@ -14,6 +14,7 @@
from devtoolslib.android_shell import AndroidShell
from devtoolslib.linux_shell import LinuxShell
+from devtoolslib.shell_config import ShellConfigurationException
# When spinning up servers for local origins, we want to use predictable ports
# so that caching works between subsequent runs with the same command line.
@@ -21,11 +22,6 @@
_MAPPINGS_BASE_PORT = 31841
-class ShellConfigurationException(Exception):
- """Represents an error preventing creating a functional shell abstraction."""
- pass
-
-
def _is_web_url(dest):
return True if urlparse.urlparse(dest).scheme else False
@@ -170,6 +166,26 @@
return arguments
+def _configure_dev_server(shell, shell_args, dev_server_config):
+ """Sets up a dev server on the host according to |dev_server_config|.
+
+ Args:
+ shell: The shell that is being configured.
+ shell_arguments: Current list of shell arguments.
+ dev_server_config: Instance of shell_config.DevServerConfig describing the
+ dev server to be set up.
+
+ Returns:
+ The updated argument list.
+ """
+ server_url = shell.serve_local_directories(dev_server_config.mappings)
+ shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url))
+ print "Configured %s locally as %s" % (dev_server_config.host, server_url)
+ for mapping_prefix, mapping_path in dev_server_config.mappings:
+ print " /%s -> %s" % (mapping_prefix, mapping_path)
+ return shell_args
+
+
def get_shell(shell_config, shell_args):
"""
Produces a shell abstraction configured according to |shell_config|.
@@ -221,4 +237,7 @@
if shell_config.sky:
shell_args = _configure_sky(shell_args)
+ for dev_server_config in shell_config.dev_servers:
+ shell_args = _configure_dev_server(shell, shell_args, dev_server_config)
+
return shell, shell_args
diff --git a/devtoolslib/shell_config.py b/devtoolslib/shell_config.py
index acc9c61..702be64 100644
--- a/devtoolslib/shell_config.py
+++ b/devtoolslib/shell_config.py
@@ -9,9 +9,16 @@
file, etc.
"""
+import ast
+
from devtoolslib import paths
+class ShellConfigurationException(Exception):
+ """Represents an error preventing creating a functional shell abstraction."""
+ pass
+
+
class ShellConfig(object):
"""Configuration for the shell abstraction."""
@@ -19,8 +26,9 @@
self.android = None
self.shell_path = None
self.origin = None
- self.map_url_list = None
- self.map_origin_list = None
+ self.map_url_list = []
+ self.map_origin_list = []
+ self.dev_servers = []
self.sky = None
self.verbose = None
@@ -33,6 +41,15 @@
self.use_osmesa = None
+class DevServerConfig(object):
+ """Configuration for a development server running on a host and available to
+ the shell.
+ """
+ def __init__(self):
+ self.host = None
+ self.mappings = None
+
+
def add_shell_arguments(parser):
"""Adds argparse arguments allowing to configure shell abstraction using
configure_shell() below.
@@ -68,22 +85,37 @@
help='Configure the native viewport service '
'for off-screen rendering.')
- # Arguments allowing to indicate the configuration we are targeting when
- # running within a Chromium-like checkout. These will go away once we have
- # devtools config files, see https://github.com/domokit/devtools/issues/28.
- chromium_config_group = parser.add_argument_group('Chromium configuration',
+ config_file_group = parser.add_argument_group('Configuration file',
+ 'These arguments allow to modify the behavior regarding the mojoconfig '
+ 'file.')
+ config_file_group.add_argument('--config-file', type=file,
+ help='Path of the configuration file to use.')
+
+ # Arguments allowing to indicate the build directory we are targeting when
+ # running within a Chromium-like checkout (e.g. Mojo checkout). These will go
+ # away once we have devtools config files, see
+ # https://github.com/domokit/devtools/issues/28.
+ chromium_checkout_group = parser.add_argument_group(
+ 'Chromium-like checkout configuration',
'These arguments allow to infer paths to tools and build results '
- 'when running withing a Chromium-like checkout')
- debug_group = chromium_config_group.add_mutually_exclusive_group()
+ 'when running within a Chromium-like checkout')
+ debug_group = chromium_checkout_group.add_mutually_exclusive_group()
debug_group.add_argument('--debug', help='Debug build (default)',
default=True, action='store_true')
debug_group.add_argument('--release', help='Release build', default=False,
dest='debug', action='store_false')
- chromium_config_group.add_argument('--target-cpu',
+ chromium_checkout_group.add_argument('--target-cpu',
help='CPU architecture to run for.',
choices=['x64', 'x86', 'arm'])
+def _read_config_file(config_file, aliases):
+ spec = config_file.read()
+ for alias_pattern, alias_value in aliases:
+ spec = spec.replace(alias_pattern, alias_value)
+ return ast.literal_eval(spec)
+
+
def get_shell_config(script_args):
"""Processes command-line options defined in add_shell_arguments(), applying
any inferred default paths and produces an instance of ShellConfig.
@@ -95,7 +127,6 @@
# (--debug/--release, etc.), if running within a Chromium-like checkout.
inferred_paths = paths.infer_paths(script_args.android, script_args.debug,
script_args.target_cpu)
-
shell_config = ShellConfig()
shell_config.android = script_args.android
@@ -118,4 +149,31 @@
if (shell_config.android and not shell_config.origin and
inferred_paths['build_dir_path']):
shell_config.origin = inferred_paths['build_dir_path']
+
+ # Read the mojoconfig file.
+ if script_args.config_file:
+ config_file_aliases = []
+ if inferred_paths['build_dir_path']:
+ config_file_aliases.append(('@{BUILD_DIR}',
+ inferred_paths['build_dir_path']))
+
+ mojoconfig = None
+ try:
+ mojoconfig = _read_config_file(script_args.config_file,
+ config_file_aliases)
+ except SyntaxError:
+ raise ShellConfigurationException('Failed to parse the mojoconfig file.')
+
+ if 'dev_servers' in mojoconfig:
+ try:
+ for dev_server_spec in mojoconfig['dev_servers']:
+ dev_server_config = DevServerConfig()
+ dev_server_config.host = dev_server_spec['host']
+ dev_server_config.mappings = []
+ for prefix, path in dev_server_spec['mappings']:
+ dev_server_config.mappings.append((prefix, path))
+ shell_config.dev_servers.append(dev_server_config)
+ except (ValueError, KeyError):
+ raise ShellConfigurationException('Failed to parse dev_servers in '
+ 'the mojoconfig file.')
return shell_config
diff --git a/mojo_run b/mojo_run
index 1457fb2..554eeab 100755
--- a/mojo_run
+++ b/mojo_run
@@ -65,11 +65,11 @@
_DEFAULT_WINDOW_MANAGER)
script_args, shell_args = parser.parse_known_args()
- config = shell_config.get_shell_config(script_args)
try:
+ config = shell_config.get_shell_config(script_args)
shell, shell_args = shell_arguments.get_shell(config, shell_args)
- except shell_arguments.ShellConfigurationException as e:
+ except shell_config.ShellConfigurationException as e:
print e
return 1
diff --git a/mojo_test b/mojo_test
index e2100dd..2cf84b9 100755
--- a/mojo_test
+++ b/mojo_test
@@ -59,11 +59,11 @@
shell_config.add_shell_arguments(parser)
script_args, shell_args = parser.parse_known_args()
- config = shell_config.get_shell_config(script_args)
try:
+ config = shell_config.get_shell_config(script_args)
shell, common_shell_args = shell_arguments.get_shell(config, shell_args)
- except shell_arguments.ShellConfigurationException as e:
+ except shell_config.ShellConfigurationException as e:
print e
return 1