mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
195 lines
6.4 KiB
Python
195 lines
6.4 KiB
Python
# Copyright 2015 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""Functions that configure the shell before it is run manipulating its argument
|
|
list.
|
|
"""
|
|
|
|
import os.path
|
|
import urlparse
|
|
|
|
# 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.
|
|
_LOCAL_ORIGIN_PORT = 31840
|
|
_MAPPINGS_BASE_PORT = 31841
|
|
|
|
# Port on which the mojo:debugger http server will be available on the host
|
|
# machine.
|
|
_MOJO_DEBUGGER_PORT = 7777
|
|
|
|
_SKY_SERVER_PORT = 9998
|
|
|
|
|
|
def _HostLocalUrlDestination(shell, dest_file, port):
|
|
"""Starts a local server to host |dest_file|.
|
|
|
|
Returns:
|
|
Url of the hosted file.
|
|
"""
|
|
directory = os.path.dirname(dest_file)
|
|
if not os.path.exists(directory):
|
|
raise ValueError('local path passed as --map-url destination '
|
|
'does not exist')
|
|
server_url = shell.ServeLocalDirectory(directory, port)
|
|
return server_url + os.path.relpath(dest_file, directory)
|
|
|
|
|
|
def _HostLocalOriginDestination(shell, dest_dir, port):
|
|
"""Starts a local server to host |dest_dir|.
|
|
|
|
Returns:
|
|
Url of the hosted directory.
|
|
"""
|
|
return shell.ServeLocalDirectory(dest_dir, port)
|
|
|
|
|
|
def _Rewrite(mapping, host_destination_functon, shell, port):
|
|
"""Takes a mapping given as <src>=<dest> and rewrites the <dest> part to be
|
|
hosted locally using the given function if <dest> is not a web url.
|
|
"""
|
|
parts = mapping.split('=')
|
|
if len(parts) != 2:
|
|
raise ValueError('each mapping value should be in format '
|
|
'"<url>=<url-or-local-path>"')
|
|
if urlparse.urlparse(parts[1])[0]:
|
|
# The destination is a web url, do nothing.
|
|
return mapping
|
|
|
|
src = parts[0]
|
|
dest = host_destination_functon(shell, parts[1], port)
|
|
return src + '=' + dest
|
|
|
|
|
|
|
|
def ApplyMappings(shell, original_arguments, map_urls, map_origins):
|
|
"""Applies mappings for specified urls and origins. For each local path
|
|
specified as destination a local server will be spawned and the mapping will
|
|
be rewritten accordingly.
|
|
|
|
Args:
|
|
shell: The shell that is being configured.
|
|
original_arguments: Current list of shell arguments.
|
|
map_urls: List of url mappings, each in the form of
|
|
<url>=<url-or-local-path>.
|
|
map_origins: List of origin mappings, each in the form of
|
|
<origin>=<url-or-local-path>.
|
|
|
|
Returns:
|
|
The updated argument list.
|
|
"""
|
|
next_port = _MAPPINGS_BASE_PORT
|
|
args = original_arguments
|
|
if map_urls:
|
|
# Sort the mappings to preserve caching regardless of argument order.
|
|
for map_url in sorted(map_urls):
|
|
mapping = _Rewrite(map_url, _HostLocalUrlDestination, shell, next_port)
|
|
next_port += 1
|
|
# All url mappings need to be coalesced into one shell argument.
|
|
args = AppendToArgument(args, '--url-mappings=', mapping)
|
|
|
|
if map_origins:
|
|
for map_origin in sorted(map_origins):
|
|
mapping = _Rewrite(map_origin, _HostLocalOriginDestination, shell,
|
|
next_port)
|
|
next_port += 1
|
|
# Origin mappings are specified as separate, repeated shell arguments.
|
|
args.append('--map-origin=' + mapping)
|
|
return args
|
|
|
|
|
|
def ConfigureDebugger(shell):
|
|
"""Configures mojo:debugger to run and sets up port forwarding for its http
|
|
server if the shell is running on a device.
|
|
|
|
Returns:
|
|
Arguments that need to be appended to the shell argument list in order to
|
|
run with the debugger.
|
|
"""
|
|
shell.ForwardHostPortToShell(_MOJO_DEBUGGER_PORT)
|
|
return ['mojo:debugger %d' % _MOJO_DEBUGGER_PORT]
|
|
|
|
|
|
def ConfigureSky(shell, root_path, sky_packages_path, sky_target):
|
|
"""Configures additional mappings and a server needed to run the given Sky
|
|
app.
|
|
|
|
Args:
|
|
root_path: Local path to the root from which Sky apps will be served.
|
|
sky_packages_path: Local path to the root from which Sky packages will be
|
|
served.
|
|
sky_target: Path to the Sky app to be run, relative to |root_path|.
|
|
|
|
Returns:
|
|
Arguments that need to be appended to the shell argument list.
|
|
"""
|
|
# Configure a server to serve the checkout root at / (so that Sky examples
|
|
# are accessible using a root-relative path) and Sky packages at /packages.
|
|
# This is independent from the server that potentially serves the origin
|
|
# directory containing the mojo: apps.
|
|
additional_mappings = [
|
|
('packages/', sky_packages_path),
|
|
]
|
|
server_url = shell.ServeLocalDirectory(root_path, port=_SKY_SERVER_PORT,
|
|
additional_mappings=additional_mappings)
|
|
|
|
args = []
|
|
# Configure the content type mappings for the sky_viewer. This is needed
|
|
# only for the Sky apps that do not declare mojo:sky_viewer in a shebang,
|
|
# and it is unfortunate as it configures the shell to map all items of the
|
|
# application/dart content-type as Sky apps.
|
|
# TODO(ppi): drop this part once we can rely on the Sky files declaring
|
|
# correct shebang.
|
|
args = AppendToArgument(args, '--content-handlers=',
|
|
'text/sky,mojo:sky_viewer')
|
|
args = AppendToArgument(args, '--content-handlers=',
|
|
'application/dart,mojo:sky_viewer')
|
|
|
|
# Configure the window manager to embed the sky_viewer.
|
|
sky_url = server_url + sky_target
|
|
args.append('mojo:window_manager %s' % sky_url)
|
|
return args
|
|
|
|
|
|
def ConfigureLocalOrigin(shell, local_dir, fixed_port=True):
|
|
"""Sets up a local http server to serve files in |local_dir| along with
|
|
device port forwarding if needed.
|
|
|
|
Returns:
|
|
The list of arguments to be appended to the shell argument list.
|
|
"""
|
|
|
|
origin_url = shell.ServeLocalDirectory(
|
|
local_dir, _LOCAL_ORIGIN_PORT if fixed_port else 0)
|
|
return ["--origin=" + origin_url]
|
|
|
|
|
|
def AppendToArgument(arguments, key, value, delimiter=","):
|
|
"""Looks for an argument of the form "key=val1,val2" within |arguments| and
|
|
appends |value| to it.
|
|
|
|
If the argument is not present in |arguments| it is added.
|
|
|
|
Args:
|
|
arguments: List of arguments for the shell.
|
|
key: Identifier of the argument, including the equal sign, eg.
|
|
"--content-handlers=".
|
|
value: The value to be appended, after |delimeter|, to the argument.
|
|
delimiter: The string used to separate values within the argument.
|
|
|
|
Returns:
|
|
The updated argument list.
|
|
"""
|
|
assert key and key.endswith('=')
|
|
assert value
|
|
|
|
for i, argument in enumerate(arguments):
|
|
if not argument.startswith(key):
|
|
continue
|
|
arguments[i] = argument + delimiter + value
|
|
break
|
|
else:
|
|
arguments.append(key + value)
|
|
|
|
return arguments
|