OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Produces configured shell abstractions. | 5 """Produces configured shell abstractions. |
6 | 6 |
7 This module knows how to produce a configured shell abstraction based on | 7 This module knows how to produce a configured shell abstraction based on |
8 shell_config.ShellConfig. | 8 shell_config.ShellConfig. |
9 """ | 9 """ |
10 | 10 |
11 import os.path | 11 import os.path |
12 import sys | 12 import sys |
13 import urlparse | 13 import urlparse |
14 | 14 |
15 from devtoolslib.android_shell import AndroidShell | 15 from devtoolslib.android_shell import AndroidShell |
16 from devtoolslib.linux_shell import LinuxShell | 16 from devtoolslib.linux_shell import LinuxShell |
17 from devtoolslib.shell_config import ShellConfigurationException | 17 from devtoolslib.shell_config import ShellConfigurationException |
18 | 18 |
19 # When spinning up servers for local origins, we want to use predictable ports | 19 # When spinning up servers for local origins, we want to use predictable ports |
20 # so that caching works between subsequent runs with the same command line. | 20 # so that caching works between subsequent runs with the same command line. |
21 _LOCAL_ORIGIN_PORT = 31840 | 21 _LOCAL_ORIGIN_PORT = 31840 |
22 _MAPPINGS_BASE_PORT = 31841 | 22 _MAPPINGS_BASE_PORT = 31841 |
23 | 23 |
24 | 24 |
25 def _is_web_url(dest): | 25 def _is_web_url(dest): |
26 return True if urlparse.urlparse(dest).scheme else False | 26 return True if urlparse.urlparse(dest).scheme else False |
27 | 27 |
28 | 28 |
29 def _host_local_url_destination(shell, dest_file, port, free_host_port): | 29 def _host_local_url_destination(shell, dest_file, port, reuse_servers): |
30 """Starts a local server to host |dest_file|. | 30 """Starts a local server to host |dest_file|. |
31 | 31 |
32 Returns: | 32 Returns: |
33 Url of the hosted file. | 33 Url of the hosted file. |
34 """ | 34 """ |
35 directory = os.path.dirname(dest_file) | 35 directory = os.path.dirname(dest_file) |
36 if not os.path.exists(directory): | 36 if not os.path.exists(directory): |
37 raise ValueError('local path passed as --map-url destination ' | 37 raise ValueError('local path passed as --map-url destination ' |
38 'does not exist') | 38 'does not exist') |
39 mappings = [('', [directory])] | 39 mappings = [('', [directory])] |
40 server_url = shell.serve_local_directories(mappings, port, free_host_port) | 40 server_url = shell.serve_local_directories(mappings, port, reuse_servers) |
41 return server_url + os.path.relpath(dest_file, directory) | 41 return server_url + os.path.relpath(dest_file, directory) |
42 | 42 |
43 | 43 |
44 def _host_local_origin_destination(shell, dest_dir, port, free_host_port): | 44 def _host_local_origin_destination(shell, dest_dir, port, reuse_servers): |
45 """Starts a local server to host |dest_dir|. | 45 """Starts a local server to host |dest_dir|. |
46 | 46 |
47 Returns: | 47 Returns: |
48 Url of the hosted directory. | 48 Url of the hosted directory. |
49 """ | 49 """ |
50 mappings = [('', [dest_dir])] | 50 mappings = [('', [dest_dir])] |
51 return shell.serve_local_directories(mappings, port, free_host_port) | 51 return shell.serve_local_directories(mappings, port, reuse_servers) |
52 | 52 |
53 | 53 |
54 def _rewrite(mapping, host_destination_functon, shell, port, free_host_port): | 54 def _rewrite(mapping, host_destination_functon, shell, port, reuse_servers): |
55 """Takes a mapping given as <src>=<dest> and rewrites the <dest> part to be | 55 """Takes a mapping given as <src>=<dest> and rewrites the <dest> part to be |
56 hosted locally using the given function if <dest> is not a web url. | 56 hosted locally using the given function if <dest> is not a web url. |
57 """ | 57 """ |
58 parts = mapping.split('=') | 58 parts = mapping.split('=') |
59 if len(parts) != 2: | 59 if len(parts) != 2: |
60 raise ValueError('each mapping value should be in format ' | 60 raise ValueError('each mapping value should be in format ' |
61 '"<url>=<url-or-local-path>"') | 61 '"<url>=<url-or-local-path>"') |
62 if _is_web_url(parts[1]): | 62 if _is_web_url(parts[1]): |
63 # The destination is a web url, do nothing. | 63 # The destination is a web url, do nothing. |
64 return mapping | 64 return mapping |
65 | 65 |
66 src = parts[0] | 66 src = parts[0] |
67 dest = host_destination_functon(shell, parts[1], port, free_host_port) | 67 dest = host_destination_functon(shell, parts[1], port, reuse_servers) |
68 return src + '=' + dest | 68 return src + '=' + dest |
69 | 69 |
70 | 70 |
71 def _apply_mappings(shell, original_arguments, map_urls, map_origins, | 71 def _apply_mappings(shell, original_arguments, map_urls, map_origins, |
72 free_ports, free_host_ports): | 72 reuse_servers): |
73 """Applies mappings for specified urls and origins. For each local path | 73 """Applies mappings for specified urls and origins. For each local path |
74 specified as destination a local server will be spawned and the mapping will | 74 specified as destination a local server will be spawned and the mapping will |
75 be rewritten accordingly. | 75 be rewritten accordingly. |
76 | 76 |
77 Args: | 77 Args: |
78 shell: The shell that is being configured. | 78 shell: The shell that is being configured. |
79 original_arguments: Current list of shell arguments. | 79 original_arguments: Current list of shell arguments. |
80 map_urls: List of url mappings, each in the form of | 80 map_urls: List of url mappings, each in the form of |
81 <url>=<url-or-local-path>. | 81 <url>=<url-or-local-path>. |
82 map_origins: List of origin mappings, each in the form of | 82 map_origins: List of origin mappings, each in the form of |
83 <origin>=<url-or-local-path>. | 83 <origin>=<url-or-local-path>. |
84 free_ports: Iff True, run local development servers on system-allocated | 84 reuse_servers: Assume that the development servers are already running and |
85 ports. This defeats any performance benefits from caching. | 85 do not spawn any. |
86 free_host_ports: Only applicable on Android. Iff True, local development | |
87 servers are run on system-allocated ports, but are still forwarded from | |
88 fixed ports on the device. | |
89 | 86 |
90 Returns: | 87 Returns: |
91 The updated argument list. | 88 The updated argument list. |
92 """ | 89 """ |
93 next_port = 0 if free_ports else _MAPPINGS_BASE_PORT | 90 next_port = _MAPPINGS_BASE_PORT |
94 args = original_arguments | 91 args = original_arguments |
95 if map_urls: | 92 if map_urls: |
96 # Sort the mappings to preserve caching regardless of argument order. | 93 # Sort the mappings to preserve caching regardless of argument order. |
97 for map_url in sorted(map_urls): | 94 for map_url in sorted(map_urls): |
98 mapping = _rewrite(map_url, _host_local_url_destination, shell, next_port, | 95 mapping = _rewrite(map_url, _host_local_url_destination, shell, next_port, |
99 free_host_ports) | 96 reuse_servers) |
100 if not free_ports: | 97 next_port += 1 |
101 next_port += 1 | |
102 # All url mappings need to be coalesced into one shell argument. | 98 # All url mappings need to be coalesced into one shell argument. |
103 args = append_to_argument(args, '--url-mappings=', mapping) | 99 args = append_to_argument(args, '--url-mappings=', mapping) |
104 | 100 |
105 if map_origins: | 101 if map_origins: |
106 for map_origin in sorted(map_origins): | 102 for map_origin in sorted(map_origins): |
107 mapping = _rewrite(map_origin, _host_local_origin_destination, shell, | 103 mapping = _rewrite(map_origin, _host_local_origin_destination, shell, |
108 next_port, free_host_ports) | 104 next_port, reuse_servers) |
109 if not free_ports: | 105 next_port += 1 |
110 next_port += 1 | |
111 # Origin mappings are specified as separate, repeated shell arguments. | 106 # Origin mappings are specified as separate, repeated shell arguments. |
112 args.append('--map-origin=' + mapping) | 107 args.append('--map-origin=' + mapping) |
113 return args | 108 return args |
114 | 109 |
115 | 110 |
116 def configure_local_origin(shell, local_dir, port, free_host_port): | 111 def configure_local_origin(shell, local_dir, port, reuse_servers): |
117 """Sets up a local http server to serve files in |local_dir| along with | 112 """Sets up a local http server to serve files in |local_dir| along with |
118 device port forwarding if needed. | 113 device port forwarding if needed. |
119 | 114 |
120 Returns: | 115 Returns: |
121 The list of arguments to be appended to the shell argument list. | 116 The list of arguments to be appended to the shell argument list. |
122 """ | 117 """ |
123 mappings = [('', [local_dir])] | 118 mappings = [('', [local_dir])] |
124 origin_url = shell.serve_local_directories(mappings, port, free_host_port) | 119 origin_url = shell.serve_local_directories(mappings, port, reuse_servers) |
125 return ["--origin=" + origin_url] | 120 return ["--origin=" + origin_url] |
126 | 121 |
127 | 122 |
128 def append_to_argument(arguments, key, value, delimiter=","): | 123 def append_to_argument(arguments, key, value, delimiter=","): |
129 """Looks for an argument of the form "key=val1,val2" within |arguments| and | 124 """Looks for an argument of the form "key=val1,val2" within |arguments| and |
130 appends |value| to it. | 125 appends |value| to it. |
131 | 126 |
132 If the argument is not present in |arguments| it is added. | 127 If the argument is not present in |arguments| it is added. |
133 | 128 |
134 Args: | 129 Args: |
(...skipping 13 matching lines...) Expand all Loading... |
148 if not argument.startswith(key): | 143 if not argument.startswith(key): |
149 continue | 144 continue |
150 arguments[i] = argument + delimiter + value | 145 arguments[i] = argument + delimiter + value |
151 break | 146 break |
152 else: | 147 else: |
153 arguments.append(key + value) | 148 arguments.append(key + value) |
154 | 149 |
155 return arguments | 150 return arguments |
156 | 151 |
157 | 152 |
158 def _configure_dev_server(shell, shell_args, dev_server_config, free_host_port, | 153 def _configure_dev_server(shell, shell_args, dev_server_config, reuse_servers, |
159 verbose): | 154 verbose): |
160 """Sets up a dev server on the host according to |dev_server_config|. | 155 """Sets up a dev server on the host according to |dev_server_config|. |
161 | 156 |
162 Args: | 157 Args: |
163 shell: The shell that is being configured. | 158 shell: The shell that is being configured. |
164 shell_arguments: Current list of shell arguments. | 159 shell_arguments: Current list of shell arguments. |
165 dev_server_config: Instance of shell_config.DevServerConfig describing the | 160 dev_server_config: Instance of shell_config.DevServerConfig describing the |
166 dev server to be set up. | 161 dev server to be set up. |
167 | 162 |
168 Returns: | 163 Returns: |
169 The updated argument list. | 164 The updated argument list. |
170 """ | 165 """ |
171 port = dev_server_config.port if dev_server_config.port else 0 | 166 port = dev_server_config.port if dev_server_config.port else 0 |
172 server_url = shell.serve_local_directories(dev_server_config.mappings, | 167 server_url = shell.serve_local_directories( |
173 port=port, | 168 dev_server_config.mappings, port, reuse_servers) |
174 free_host_port=free_host_port) | |
175 shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url)) | 169 shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url)) |
176 | 170 |
177 if verbose: | 171 if verbose: |
178 print "Configured %s locally at %s to serve:" % (dev_server_config.host, | 172 print "Configured %s locally at %s to serve:" % (dev_server_config.host, |
179 server_url) | 173 server_url) |
180 for mapping_prefix, mapping_path in dev_server_config.mappings: | 174 for mapping_prefix, mapping_path in dev_server_config.mappings: |
181 print " /%s -> %s" % (mapping_prefix, mapping_path) | 175 print " /%s -> %s" % (mapping_prefix, mapping_path) |
182 return shell_args | 176 return shell_args |
183 | 177 |
184 | 178 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 else: | 210 else: |
217 if not shell_config.shell_path: | 211 if not shell_config.shell_path: |
218 raise ShellConfigurationException('Can not run without a shell binary. ' | 212 raise ShellConfigurationException('Can not run without a shell binary. ' |
219 'Please pass --shell-path.') | 213 'Please pass --shell-path.') |
220 shell = LinuxShell(shell_config.shell_path) | 214 shell = LinuxShell(shell_config.shell_path) |
221 if shell_config.use_osmesa: | 215 if shell_config.use_osmesa: |
222 shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa') | 216 shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa') |
223 | 217 |
224 shell_args = _apply_mappings(shell, shell_args, shell_config.map_url_list, | 218 shell_args = _apply_mappings(shell, shell_args, shell_config.map_url_list, |
225 shell_config.map_origin_list, | 219 shell_config.map_origin_list, |
226 shell_config.free_ports, | 220 shell_config.reuse_servers) |
227 shell_config.free_host_ports) | |
228 | 221 |
229 if shell_config.origin: | 222 if shell_config.origin: |
230 if _is_web_url(shell_config.origin): | 223 if _is_web_url(shell_config.origin): |
231 shell_args.append('--origin=' + shell_config.origin) | 224 shell_args.append('--origin=' + shell_config.origin) |
232 else: | 225 else: |
233 local_origin_port = 0 if shell_config.free_ports else _LOCAL_ORIGIN_PORT | 226 local_origin_port = _LOCAL_ORIGIN_PORT |
234 shell_args.extend(configure_local_origin(shell, shell_config.origin, | 227 shell_args.extend(configure_local_origin(shell, shell_config.origin, |
235 local_origin_port, | 228 local_origin_port, |
236 shell_config.free_host_ports)) | 229 shell_config.reuse_servers)) |
237 | 230 |
238 if shell_config.content_handlers: | 231 if shell_config.content_handlers: |
239 for (mime_type, | 232 for (mime_type, |
240 content_handler_url) in shell_config.content_handlers.iteritems(): | 233 content_handler_url) in shell_config.content_handlers.iteritems(): |
241 shell_args = append_to_argument(shell_args, '--content-handlers=', | 234 shell_args = append_to_argument(shell_args, '--content-handlers=', |
242 '%s,%s' % (mime_type, | 235 '%s,%s' % (mime_type, |
243 content_handler_url)) | 236 content_handler_url)) |
244 | 237 |
245 for dev_server_config in shell_config.dev_servers: | 238 for dev_server_config in shell_config.dev_servers: |
246 shell_args = _configure_dev_server(shell, shell_args, dev_server_config, | 239 shell_args = _configure_dev_server(shell, shell_args, dev_server_config, |
247 shell_config.free_host_ports, | 240 shell_config.reuse_servers, |
248 shell_config.verbose) | 241 shell_config.verbose) |
249 | 242 |
250 return shell, shell_args | 243 return shell, shell_args |
OLD | NEW |