OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 from skypy.skyserver import SkyServer | 6 from skypy.skyserver import SkyServer |
7 import argparse | 7 import argparse |
8 import json | 8 import json |
9 import logging | 9 import logging |
10 import os | 10 import os |
11 import pipes | 11 import pipes |
12 import requests | 12 import requests |
13 import signal | 13 import signal |
14 import skypy.paths | 14 import skypy.paths |
15 import StringIO | 15 import StringIO |
16 import subprocess | 16 import subprocess |
17 import sys | 17 import sys |
18 import time | 18 import time |
19 import urlparse | 19 import urlparse |
20 import re | |
qsr
2015/01/16 19:22:46
Alphabetize.
| |
20 | 21 |
21 SRC_ROOT = skypy.paths.Paths('ignored').src_root | 22 SRC_ROOT = skypy.paths.Paths('ignored').src_root |
22 sys.path.insert(0, os.path.join(SRC_ROOT, 'build', 'android')) | 23 sys.path.insert(0, os.path.join(SRC_ROOT, 'build', 'android')) |
23 from pylib import android_commands | 24 from pylib import android_commands |
24 from pylib import constants | 25 from pylib import constants |
25 from pylib import forwarder | 26 from pylib import forwarder |
26 | 27 |
27 | 28 |
28 SUPPORTED_MIME_TYPES = [ | 29 SUPPORTED_MIME_TYPES = [ |
29 'text/html', | 30 'text/html', |
30 'text/sky', | 31 'text/sky', |
31 'text/plain', | 32 'text/plain', |
32 ] | 33 ] |
33 | 34 |
34 DEFAULT_SKY_COMMAND_PORT = 7777 | 35 DEFAULT_SKY_COMMAND_PORT = 7777 |
35 GDB_PORT = 8888 | 36 GDB_PORT = 8888 |
36 SKY_SERVER_PORT = 9999 | 37 SKY_SERVER_PORT = 9999 |
37 PID_FILE_PATH = "/tmp/skydb.pids" | 38 PID_FILE_PATH = "/tmp/skydb.pids" |
38 DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/example s/home.sky" | 39 DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/example s/home.sky" |
39 | 40 |
40 ANDROID_PACKAGE = "org.chromium.mojo.shell" | 41 ANDROID_PACKAGE = "org.chromium.mojo.shell" |
41 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE | 42 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE |
42 | 43 |
44 | |
43 # FIXME: Move this into mopy.config | 45 # FIXME: Move this into mopy.config |
44 def gn_args_from_build_dir(build_dir): | 46 def gn_args_from_build_dir(build_dir): |
45 gn_cmd = [ | 47 gn_cmd = [ |
46 'gn', 'args', | 48 'gn', 'args', |
47 build_dir, | 49 build_dir, |
48 '--list', '--short' | 50 '--list', '--short' |
49 ] | 51 ] |
50 config = {} | 52 config = {} |
51 for line in subprocess.check_output(gn_cmd).strip().split('\n'): | 53 for line in subprocess.check_output(gn_cmd).strip().split('\n'): |
52 # FIXME: This doesn't handle = in values. | 54 # FIXME: This doesn't handle = in values. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 'am', 'start', | 92 'am', 'start', |
91 '-W', | 93 '-W', |
92 '-S', | 94 '-S', |
93 '-a', 'android.intent.action.VIEW', | 95 '-a', 'android.intent.action.VIEW', |
94 '-n', ANDROID_ACTIVITY, | 96 '-n', ANDROID_ACTIVITY, |
95 # FIXME: This quoting is very error-prone. Perhaps we should read | 97 # FIXME: This quoting is very error-prone. Perhaps we should read |
96 # our args from a file instead? | 98 # our args from a file instead? |
97 '--esa', 'parameters', ','.join(escaped_args), | 99 '--esa', 'parameters', ','.join(escaped_args), |
98 ] | 100 ] |
99 | 101 |
100 def _build_mojo_shell_command(self, args): | 102 def _build_mojo_shell_command(self, args, is_android): |
101 content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') | 103 content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') |
102 for mime_type in SUPPORTED_MIME_TYPES] | 104 for mime_type in SUPPORTED_MIME_TYPES] |
103 | 105 |
104 remote_command_port = self.pids.get('remote_sky_command_port', self.pids ['sky_command_port']) | 106 remote_command_port = self.pids.get('remote_sky_command_port', self.pids ['sky_command_port']) |
105 | 107 |
106 shell_args = [ | 108 shell_args = [ |
107 '--v=1', | 109 '--v=1', |
108 '--content-handlers=%s' % ','.join(content_handlers), | 110 '--content-handlers=%s' % ','.join(content_handlers), |
109 '--url-mappings=mojo:window_manager=mojo:sky_debugger', | 111 '--url-mappings=mojo:window_manager=mojo:sky_debugger', |
110 '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port, | 112 '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port, |
111 'mojo:window_manager', | 113 'mojo:window_manager', |
112 ] | 114 ] |
113 | 115 |
116 # Desktop-only work-around for mojo crashing under chromoting. | |
117 if not is_android and args.use_osmesa: | |
118 shell_args.append( | |
119 '--args-for=mojo:native_viewport_service --use-osmesa') | |
120 | |
121 if is_android and args.gdb: | |
122 shell_args.append('--wait_for_debugger') | |
123 | |
114 if 'remote_sky_server_port' in self.pids: | 124 if 'remote_sky_server_port' in self.pids: |
115 shell_command = self._wrap_for_android(shell_args) | 125 shell_command = self._wrap_for_android(shell_args) |
116 else: | 126 else: |
117 shell_command = [self.paths.mojo_shell_path] + shell_args | 127 shell_command = [self.paths.mojo_shell_path] + shell_args |
118 | 128 |
119 return shell_command | 129 return shell_command |
120 | 130 |
121 def _connect_to_device(self): | 131 def _connect_to_device(self): |
122 device = android_commands.AndroidCommands( | 132 device = android_commands.AndroidCommands( |
123 android_commands.GetAttachedDevices()[0]) | 133 android_commands.GetAttachedDevices()[0]) |
124 device.EnableAdbRoot() | 134 device.EnableAdbRoot() |
125 return device | 135 return device |
126 | 136 |
127 def sky_server_for_args(self, args): | 137 def sky_server_for_args(self, args): |
128 # FIXME: This is a hack. sky_server should just take a build_dir | 138 # FIXME: This is a hack. sky_server should just take a build_dir |
129 # not a magical "configuration" name. | 139 # not a magical "configuration" name. |
130 configuration = os.path.basename(os.path.normpath(args.build_dir)) | 140 configuration = os.path.basename(os.path.normpath(args.build_dir)) |
131 server_root = self._server_root_for_url(args.url_or_path) | 141 server_root = self._server_root_for_url(args.url_or_path) |
132 sky_server = SkyServer(self.paths, SKY_SERVER_PORT, | 142 sky_server = SkyServer(self.paths, SKY_SERVER_PORT, |
133 configuration, server_root) | 143 configuration, server_root) |
134 return sky_server | 144 return sky_server |
135 | 145 |
136 def _create_paths_for_build_dir(self, build_dir): | 146 def _create_paths_for_build_dir(self, build_dir): |
137 # skypy.paths.Paths takes a root-relative build_dir argument. :( | 147 # skypy.paths.Paths takes a root-relative build_dir argument. :( |
138 abs_build_dir = os.path.abspath(build_dir) | 148 abs_build_dir = os.path.abspath(build_dir) |
139 root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT) | 149 root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT) |
140 return skypy.paths.Paths(root_relative_build_dir) | 150 return skypy.paths.Paths(root_relative_build_dir) |
141 | 151 |
152 def _find_remote_pid_for_package(self, package): | |
153 ps_output = subprocess.check_output(['adb', 'shell', 'ps']) | |
154 for line in ps_output.split('\n'): | |
155 fields = line.split() | |
156 if fields and fields[-1] == package: | |
157 return fields[1] | |
158 return None | |
159 | |
160 def _find_install_location_for_package(self, package): | |
161 pm_command = ['adb', 'shell', 'pm', 'path', package] | |
162 pm_output = subprocess.check_output(pm_command) | |
163 # e.g. package:/data/app/org.chromium.mojo.shell-1/base.apk | |
164 return pm_output.split(':')[-1] | |
165 | |
142 def start_command(self, args): | 166 def start_command(self, args): |
143 # FIXME: Lame that we use self for a command-specific variable. | 167 # FIXME: Lame that we use self for a command-specific variable. |
144 self.paths = self._create_paths_for_build_dir(args.build_dir) | 168 self.paths = self._create_paths_for_build_dir(args.build_dir) |
145 self.stop_command(None) # Quit any existing process. | 169 self.stop_command(None) # Quit any existing process. |
146 | 170 |
147 if not os.path.exists(self.paths.mojo_shell_path): | 171 if not os.path.exists(self.paths.mojo_shell_path): |
148 print "mojo_shell not found in build_dir '%s'" % args.build_dir | 172 print "mojo_shell not found in build_dir '%s'" % args.build_dir |
149 print "Are you sure you sure that's a valid build_dir location?" | 173 print "Are you sure you sure that's a valid build_dir location?" |
150 print "See skydb start --help for more info" | 174 print "See skydb start --help for more info" |
151 sys.exit(2) | 175 sys.exit(2) |
(...skipping 22 matching lines...) Expand all Loading... | |
174 device_http_port = forwarder.Forwarder.DevicePortForHostPort( | 198 device_http_port = forwarder.Forwarder.DevicePortForHostPort( |
175 sky_server.port) | 199 sky_server.port) |
176 self.pids['remote_sky_server_port'] = device_http_port | 200 self.pids['remote_sky_server_port'] = device_http_port |
177 | 201 |
178 port_string = 'tcp:%s' % args.command_port | 202 port_string = 'tcp:%s' % args.command_port |
179 subprocess.check_call([ | 203 subprocess.check_call([ |
180 'adb', 'forward', port_string, port_string | 204 'adb', 'forward', port_string, port_string |
181 ]) | 205 ]) |
182 self.pids['remote_sky_command_port'] = args.command_port | 206 self.pids['remote_sky_command_port'] = args.command_port |
183 | 207 |
184 shell_command = self._build_mojo_shell_command(args) | 208 shell_command = self._build_mojo_shell_command(args, is_android) |
185 | 209 |
186 if not is_android: | 210 # On android we can't launch inside gdb, but rather have to attach. |
187 # Desktop-only work-around for mojo crashing under chromoting. | 211 if not is_android and args.gdb: |
188 if args.use_osmesa: | 212 shell_command = ['gdbserver', ':%d' % GDB_PORT] + shell_command |
189 shell_command.append( | |
190 '--args-for=mojo:native_viewport_service --use-osmesa') | |
191 | |
192 # On android we can't launch inside gdb, but rather have to attach. | |
193 if args.gdb: | |
194 shell_command = ['gdbserver', ':%s' % GDB_PORT] + shell_command | |
195 | 213 |
196 print ' '.join(map(pipes.quote, shell_command)) | 214 print ' '.join(map(pipes.quote, shell_command)) |
197 self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid | 215 # This pid is meaningless on android (it's the adb shell pid) |
216 start_command_pid = subprocess.Popen(shell_command).pid | |
217 | |
218 if is_android: | |
219 # TODO(eseidel): am start -W does not seem to work? | |
220 pid_tries = 0 | |
221 while True: | |
222 pid = self._find_remote_pid_for_package(ANDROID_PACKAGE) | |
223 if pid or pid_tries > 3: | |
224 break | |
225 logging.debug('No pid for %s yet, waiting' % ANDROID_PACKAGE) | |
226 time.sleep(5) | |
227 pid_tries += 1 | |
228 | |
229 if not pid: | |
230 logging.error('Failed to find mojo_shell pid on device!') | |
231 return | |
232 self.pids['mojo_shell_pid'] = pid | |
233 else: | |
234 self.pids['mojo_shell_pid'] = start_command_pid | |
198 | 235 |
199 if args.gdb and is_android: | 236 if args.gdb and is_android: |
200 gdbserver_cmd = ['gdbserver', '--attach', ':%s' % GDB_PORT] | 237 # We push our own copy of gdbserver with the package since |
201 self.pids['remote_gdbserver_pid'] = subprocess.Popen(shell_command). pid | 238 # the default gdbserver is a different version from our gdb. |
239 package_path = \ | |
240 self._find_install_location_for_package(ANDROID_PACKAGE) | |
241 gdb_server_path = os.path.join( | |
242 os.path.dirname(package_path), 'lib/arm/gdbserver') | |
243 gdbserver_cmd = [ | |
244 'adb', 'shell', | |
245 gdb_server_path, '--attach', | |
246 ':%d' % GDB_PORT, | |
247 str(self.pids['mojo_shell_pid']) | |
248 ] | |
249 print ' '.join(map(pipes.quote, gdbserver_cmd)) | |
250 self.pids['adb_shell_gdbserver_pid'] = \ | |
251 subprocess.Popen(gdbserver_cmd).pid | |
202 | 252 |
203 port_string = 'tcp:%s' % GDB_PORT | 253 port_string = 'tcp:%d' % GDB_PORT |
204 subprocess.check_call([ | 254 subprocess.check_call([ |
205 'adb', 'forward', port_string, port_string | 255 'adb', 'forward', port_string, port_string |
206 ]) | 256 ]) |
207 self.pids['remote_gdbserver_port'] = GDB_PORT | 257 self.pids['remote_gdbserver_port'] = GDB_PORT |
208 | 258 |
209 if not args.gdb: | 259 if not args.gdb: |
210 if not self._wait_for_sky_command_port(): | 260 if not self._wait_for_sky_command_port(): |
211 logging.error('Failed to start sky') | 261 logging.error('Failed to start sky') |
212 self.stop_command(None) | 262 self.stop_command(None) |
213 else: | 263 else: |
214 self.load_command(args) | 264 self.load_command(args) |
215 else: | 265 else: |
216 print 'No load issued, connect with gdb first and then run load.' | 266 print 'No load issued, connect with gdb first and then run load.' |
217 | 267 |
218 def _kill_if_exists(self, key, name): | 268 def _kill_if_exists(self, key, name): |
219 pid = self.pids.pop(key, None) | 269 pid = self.pids.pop(key, None) |
220 if not pid: | 270 if not pid: |
221 logging.info('No pid for %s, nothing to do.' % name) | 271 logging.info('No pid for %s, nothing to do.' % name) |
222 return | 272 return |
223 logging.info('Killing %s (%s).' % (name, pid)) | 273 logging.info('Killing %s (%d).' % (name, pid)) |
224 try: | 274 try: |
225 os.kill(pid, signal.SIGTERM) | 275 os.kill(pid, signal.SIGTERM) |
226 except OSError: | 276 except OSError: |
227 logging.info('%s (%s) already gone.' % (name, pid)) | 277 logging.info('%s (%d) already gone.' % (name, pid)) |
228 | 278 |
229 def stop_command(self, args): | 279 def stop_command(self, args): |
230 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. | 280 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. |
231 # self._send_command_to_sky('/quit') | 281 # self._send_command_to_sky('/quit') |
232 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') | |
233 | 282 |
234 self._kill_if_exists('sky_server_pid', 'sky_server') | 283 self._kill_if_exists('sky_server_pid', 'sky_server') |
284 | |
235 # We could be much more surgical here: | 285 # We could be much more surgical here: |
236 if 'remote_sky_server_port' in self.pids: | 286 if 'remote_sky_server_port' in self.pids: |
237 device = android_commands.AndroidCommands( | 287 device = android_commands.AndroidCommands( |
238 self.pids['device_serial']) | 288 self.pids['device_serial']) |
239 forwarder.Forwarder.UnmapAllDevicePorts(device) | 289 forwarder.Forwarder.UnmapAllDevicePorts(device) |
240 | 290 |
241 if 'remote_sky_command_port' in self.pids: | 291 if 'remote_sky_command_port' in self.pids: |
242 # adb forward --remove takes the *host* port, not the remote port. | 292 # adb forward --remove takes the *host* port, not the remote port. |
243 port_string = 'tcp:%s' % self.pids['sky_command_port'] | 293 port_string = 'tcp:%s' % self.pids['sky_command_port'] |
244 subprocess.call(['adb', 'forward', '--remove', port_string]) | 294 subprocess.call(['adb', 'forward', '--remove', port_string]) |
245 | 295 |
246 subprocess.call([ | 296 subprocess.call([ |
247 'adb', 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) | 297 'adb', 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) |
298 else: | |
299 # Only try to kill mojo_shell if it's running locally. | |
300 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') | |
248 | 301 |
249 if 'remote_gdbserver_port' in self.pids: | 302 if 'remote_gdbserver_port' in self.pids: |
303 self._kill_if_exists('adb_shell_gdbserver_pid', | |
304 'adb shell gdbserver') | |
305 | |
250 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] | 306 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] |
251 subprocess.call(['adb', 'forward', '--remove', port_string]) | 307 subprocess.call(['adb', 'forward', '--remove', port_string]) |
252 self.pids = {} # Clear out our pid file. | 308 self.pids = {} # Clear out our pid file. |
253 | 309 |
310 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
311 | |
254 def load_command(self, args): | 312 def load_command(self, args): |
255 if not urlparse.urlparse(args.url_or_path).scheme: | 313 if not urlparse.urlparse(args.url_or_path).scheme: |
256 # The load happens on the remote device, use the remote port. | 314 # The load happens on the remote device, use the remote port. |
257 remote_sky_server_port = self.pids.get('remote_sky_server_port', | 315 remote_sky_server_port = self.pids.get('remote_sky_server_port', |
258 self.pids['sky_server_port']) | 316 self.pids['sky_server_port']) |
259 url = SkyServer.url_for_path(remote_sky_server_port, | 317 url = SkyServer.url_for_path(remote_sky_server_port, |
260 self.pids['sky_server_root'], args.url_or_path) | 318 self.pids['sky_server_root'], args.url_or_path) |
261 else: | 319 else: |
262 url = args.url_or_path | 320 url = args.url_or_path |
263 self._send_command_to_sky('/load', url) | 321 self._send_command_to_sky('/load', url) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 'AndroidHandler', | 374 'AndroidHandler', |
317 'MojoMain', | 375 'MojoMain', |
318 'MojoShellActivity', | 376 'MojoShellActivity', |
319 'MojoShellApplication', | 377 'MojoShellApplication', |
320 'chromium', | 378 'chromium', |
321 ] | 379 ] |
322 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) | 380 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) |
323 | 381 |
324 def gdb_attach_command(self, args): | 382 def gdb_attach_command(self, args): |
325 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) | 383 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) |
384 | |
385 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
386 | |
387 links_path = '/tmp/mojo_cache_links' | |
388 if not os.path.exists(links_path): | |
389 os.makedirs(links_path) | |
390 shell_link_path = os.path.join(links_path, 'libmojo_shell.so') | |
391 if os.path.lexists(shell_link_path): | |
392 os.unlink(shell_link_path) | |
393 os.symlink(self.paths.mojo_shell_path, shell_link_path) | |
394 | |
395 logcat_cmd = ['adb', 'logcat'] | |
396 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | |
397 | |
398 mojo_cache_linker_path = os.path.join( | |
399 self.paths.sky_tools_directory, 'mojo_cache_linker.py') | |
400 cache_linker_cmd = [ | |
401 mojo_cache_linker_path, | |
402 links_path, | |
403 self.pids['build_dir'], | |
404 'http://localhost:%s' % self.pids['remote_sky_server_port'] | |
405 ] | |
406 self.pids['mojo_cache_linker_pid'] = \ | |
407 subprocess.Popen(cache_linker_cmd, stdin=logcat.stdout).pid | |
408 | |
409 # Write out our pid file before we exec ourselves. | |
410 self._write_pid_file(PID_FILE_PATH, self.pids) | |
411 | |
412 # TODO(eseidel): Need to sync down system libraries into a directory. | |
413 symbol_search_paths = [ | |
414 links_path, | |
415 self.pids['build_dir'], | |
416 ] | |
417 # TODO(eseidel): We need to look up the toolchain somehow? | |
418 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' | |
419 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' | |
420 'bin/arm-linux-androideabi-gdb') | |
326 gdb_command = [ | 421 gdb_command = [ |
327 '/usr/bin/gdb', self.paths.mojo_shell_path, | 422 gdb_path, |
328 '--eval-command', 'target remote localhost:%s' % GDB_PORT | 423 '--eval-command', 'file %s' % self.paths.mojo_shell_path, |
424 '--eval-command', 'directory %s' % self.paths.src_root, | |
425 '--eval-command', 'target remote localhost:%s' % GDB_PORT, | |
426 '--eval-command', 'set solib-search-path %s' % | |
427 ':'.join(symbol_search_paths), | |
329 ] | 428 ] |
330 print " ".join(gdb_command) | 429 print " ".join(gdb_command) |
331 # We don't want python listenting for signals or anything, so exec | 430 # We don't want python listening for signals or anything, so exec |
332 # gdb and let it take the entire process. | 431 # gdb and let it take the entire process. |
333 os.execv(gdb_command[0], gdb_command) | 432 os.execv(gdb_command[0], gdb_command) |
334 | 433 |
335 def print_crash_command(self, args): | 434 def print_crash_command(self, args): |
336 logcat_cmd = ['adb', 'logcat', '-d'] | 435 logcat_cmd = ['adb', 'logcat', '-d'] |
337 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | 436 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) |
338 | 437 |
339 stack_path = os.path.join(SRC_ROOT, | 438 stack_path = os.path.join(SRC_ROOT, |
340 'tools', 'android_stack_parser', 'stack') | 439 'tools', 'android_stack_parser', 'stack') |
341 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) | 440 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) |
342 logcat.wait() | 441 logcat.wait() |
343 stack.wait() | 442 stack.wait() |
344 | 443 |
345 def main(self): | 444 def main(self): |
346 logging.basicConfig(level=logging.INFO) | 445 logging.basicConfig(level=logging.WARNING) |
347 logging.getLogger("requests").setLevel(logging.WARNING) | 446 logging.getLogger("requests").setLevel(logging.WARNING) |
348 | 447 |
349 self.pids = self._load_pid_file(PID_FILE_PATH) | 448 self.pids = self._load_pid_file(PID_FILE_PATH) |
350 | 449 |
351 parser = argparse.ArgumentParser(description='Sky launcher/debugger') | 450 parser = argparse.ArgumentParser(description='Sky launcher/debugger') |
352 subparsers = parser.add_subparsers(help='sub-command help') | 451 subparsers = parser.add_subparsers(help='sub-command help') |
353 | 452 |
354 start_parser = subparsers.add_parser('start', | 453 start_parser = subparsers.add_parser('start', |
355 help='launch a new mojo_shell with sky') | 454 help='launch a new mojo_shell with sky') |
356 start_parser.add_argument('--gdb', action='store_true') | 455 start_parser.add_argument('--gdb', action='store_true') |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 load_parser.set_defaults(func=self.load_command) | 497 load_parser.set_defaults(func=self.load_command) |
399 | 498 |
400 args = parser.parse_args() | 499 args = parser.parse_args() |
401 args.func(args) | 500 args.func(args) |
402 | 501 |
403 self._write_pid_file(PID_FILE_PATH, self.pids) | 502 self._write_pid_file(PID_FILE_PATH, self.pids) |
404 | 503 |
405 | 504 |
406 if __name__ == '__main__': | 505 if __name__ == '__main__': |
407 SkyDebugger().main() | 506 SkyDebugger().main() |
OLD | NEW |