OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 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 hashlib | 8 import hashlib |
9 import json | 9 import json |
10 import logging | 10 import logging |
(...skipping 28 matching lines...) Expand all Loading... |
39 'sky_server_pid', | 39 'sky_server_pid', |
40 'sky_server_port', | 40 'sky_server_port', |
41 'sky_server_root', | 41 'sky_server_root', |
42 'build_dir', | 42 'build_dir', |
43 'sky_shell_pid', | 43 'sky_shell_pid', |
44 'remote_gdbserver_port', | 44 'remote_gdbserver_port', |
45 ]) | 45 ]) |
46 | 46 |
47 SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs' | 47 SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs' |
48 | 48 |
49 _IGNORED_PATTERNS = [ | |
50 # Ignored because they're not indicative of specific errors. | |
51 re.compile(r'^$'), | |
52 re.compile(r'^Analyzing \['), | |
53 re.compile(r'^No issues found'), | |
54 re.compile(r'^[0-9]+ errors? and [0-9]+ warnings? found.'), | |
55 re.compile(r'^([0-9]+|No) (error|warning|issue)s? found.'), | |
56 | |
57 # TODO: Remove once sdk-extensions are in place | |
58 re.compile(r'^\[error\] Native functions can only be declared in'), | |
59 # TODO: Remove this once dev SDK includes Uri.directory constructor. | |
60 re.compile(r'.*The class \'Uri\' does not have a constructor \'directory\''), | |
61 # TODO: Remove this once Sky no longer generates this warning. | |
62 # dartbug.com/22836 | |
63 re.compile(r'.*cannot both be unnamed'), | |
64 ] | |
65 | |
66 # This 'strict dictionary' approach is useful for catching typos. | 49 # This 'strict dictionary' approach is useful for catching typos. |
67 class Pids(object): | 50 class Pids(object): |
68 def __init__(self, known_keys, contents=None): | 51 def __init__(self, known_keys, contents=None): |
69 self._known_keys = known_keys | 52 self._known_keys = known_keys |
70 self._dict = contents if contents is not None else {} | 53 self._dict = contents if contents is not None else {} |
71 | 54 |
72 def __len__(self): | 55 def __len__(self): |
73 return len(self._dict) | 56 return len(self._dict) |
74 | 57 |
75 def get(self, key, default=None): | 58 def get(self, key, default=None): |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib') | 131 sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib') |
149 sky_icons_dir = \ | 132 sky_icons_dir = \ |
150 os.path.join(sky_pkg_lib_dir, 'assets', 'material-design-icons') | 133 os.path.join(sky_pkg_lib_dir, 'assets', 'material-design-icons') |
151 if not os.path.isdir(sky_icons_dir): | 134 if not os.path.isdir(sky_icons_dir): |
152 logging.info('NOTE: sky/assets/material-design-icons missing, ' | 135 logging.info('NOTE: sky/assets/material-design-icons missing, ' |
153 'Running `download_material_design_icons` for you.') | 136 'Running `download_material_design_icons` for you.') |
154 subprocess.check_call( | 137 subprocess.check_call( |
155 [os.path.join(sky_pkg_lib_dir, 'download_material_design_icons')]) | 138 [os.path.join(sky_pkg_lib_dir, 'download_material_design_icons')]) |
156 | 139 |
157 | 140 |
| 141 class SetBuildDir(object): |
| 142 def add_subparser(self, subparsers): |
| 143 start_parser = subparsers.add_parser('set_build_dir', |
| 144 help='force the build_dir to a particular value without starting Sky
') |
| 145 start_parser.add_argument('build_dir', type=str) |
| 146 start_parser.set_defaults(func=self.run) |
| 147 |
| 148 def run(self, args, pids): |
| 149 pids['build_dir'] = os.path.abspath(args.build_dir) |
| 150 |
| 151 |
158 class StartSky(object): | 152 class StartSky(object): |
159 def add_subparser(self, subparsers): | 153 def add_subparser(self, subparsers): |
160 start_parser = subparsers.add_parser('start', | 154 start_parser = subparsers.add_parser('start', |
161 help='launch SkyShell.apk on the device') | 155 help='launch SkyShell.apk on the device') |
162 start_parser.add_argument('build_dir', type=str) | 156 start_parser.add_argument('build_dir', type=str) |
163 start_parser.add_argument('--gdb', action="store_true") | 157 start_parser.add_argument('--gdb', action="store_true") |
164 start_parser.add_argument('url_or_path', nargs='?', type=str, | 158 start_parser.add_argument('url_or_path', nargs='?', type=str, |
165 default=DEFAULT_URL) | 159 default=DEFAULT_URL) |
166 start_parser.add_argument('--no_install', action="store_false", | 160 start_parser.add_argument('--no_install', action="store_false", |
167 default=True, dest="install", | 161 default=True, dest="install", |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 ADB_PATH, 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) | 413 ADB_PATH, 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) |
420 | 414 |
421 pids.clear() | 415 pids.clear() |
422 | 416 |
423 | 417 |
424 class Analyze(object): | 418 class Analyze(object): |
425 def add_subparser(self, subparsers): | 419 def add_subparser(self, subparsers): |
426 analyze_parser = subparsers.add_parser('analyze', | 420 analyze_parser = subparsers.add_parser('analyze', |
427 help=('run the dart analyzer with sky url mappings')) | 421 help=('run the dart analyzer with sky url mappings')) |
428 analyze_parser.add_argument('app_path', type=str) | 422 analyze_parser.add_argument('app_path', type=str) |
| 423 analyze_parser.add_argument('--congratulate', action="store_true") |
429 analyze_parser.set_defaults(func=self.run) | 424 analyze_parser.set_defaults(func=self.run) |
430 | 425 |
431 def run(self, args, pids): | 426 def run(self, args, pids): |
432 build_dir = pids.get('build_dir') | 427 build_dir = pids.get('build_dir') |
433 if not build_dir: | 428 if not build_dir: |
434 logging.fatal("pids file missing build_dir. Try 'start' first.") | 429 logging.fatal("pids file missing build_dir. Try 'start' first.") |
435 return 2 | 430 return 2 |
436 ANALYZER_PATH = 'third_party/dart-sdk/dart-sdk/bin/dartanalyzer' | 431 analyzer_path = os.path.join(SRC_ROOT, 'sky/tools/skyanalyzer') |
437 | 432 analyzer_args = [ |
438 bindings_path = os.path.join(build_dir, 'gen/sky/bindings') | 433 analyzer_path, |
439 sky_builtin_path = \ | 434 build_dir, |
440 os.path.join(SRC_ROOT, 'sky/engine/bindings/builtin.dart') | |
441 sky_internals_path = \ | |
442 os.path.join(SRC_ROOT, 'sky/sdk/lib/internals.dart') | |
443 dart_sky_path = os.path.join(bindings_path, 'dart_sky.dart') | |
444 analyzer_args = [ANALYZER_PATH, | |
445 "--url-mapping=dart:sky.internals,%s" % sky_internals_path, | |
446 "--url-mapping=dart:sky,%s" % dart_sky_path, | |
447 "--url-mapping=dart:sky_builtin,%s" % sky_builtin_path, | |
448 "--package-root", dev_packages_root(build_dir), | |
449 "--package-warnings", | |
450 args.app_path | 435 args.app_path |
451 ] | 436 ] |
| 437 if args.congratulate: |
| 438 analyzer_args.append('--congratulate') |
452 try: | 439 try: |
453 subprocess.check_output(analyzer_args, | 440 output = subprocess.check_output(analyzer_args, stderr=subprocess.STDO
UT) |
454 shell=False, | 441 result = 0 |
455 stderr=subprocess.STDOUT) | |
456 except subprocess.CalledProcessError as e: | 442 except subprocess.CalledProcessError as e: |
457 errors = set(l for l in e.output.split('\n') | 443 output = e.output |
458 if not any(p.match(l) for p in _IGNORED_PATTERNS)) | 444 result = e.returncode |
459 # If we do not have any errors left after filtering, return 0. | 445 lines = output.split('\n') |
460 if len(errors) == 0: | 446 lines.pop() |
461 return 0 | 447 for line in lines: |
462 # Print errors. | 448 print >> sys.stderr, line |
463 for error in sorted(errors): | 449 return result |
464 print >> sys.stderr, error | |
465 # Return analyzer error code. | |
466 return e.returncode | |
467 return 0 | |
468 | 450 |
469 | 451 |
470 class StartTracing(object): | 452 class StartTracing(object): |
471 def add_subparser(self, subparsers): | 453 def add_subparser(self, subparsers): |
472 start_tracing_parser = subparsers.add_parser('start_tracing', | 454 start_tracing_parser = subparsers.add_parser('start_tracing', |
473 help=('start tracing a running sky instance')) | 455 help=('start tracing a running sky instance')) |
474 start_tracing_parser.set_defaults(func=self.run) | 456 start_tracing_parser.set_defaults(func=self.run) |
475 | 457 |
476 def run(self, args, pids): | 458 def run(self, args, pids): |
477 subprocess.check_output([ADB_PATH, 'shell', | 459 subprocess.check_output([ADB_PATH, 'shell', |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 | 494 |
513 | 495 |
514 class SkyShellRunner(object): | 496 class SkyShellRunner(object): |
515 def main(self): | 497 def main(self): |
516 logging.basicConfig(level=logging.WARNING) | 498 logging.basicConfig(level=logging.WARNING) |
517 | 499 |
518 parser = argparse.ArgumentParser(description='Sky Shell Runner') | 500 parser = argparse.ArgumentParser(description='Sky Shell Runner') |
519 subparsers = parser.add_subparsers(help='sub-command help') | 501 subparsers = parser.add_subparsers(help='sub-command help') |
520 | 502 |
521 commands = [ | 503 commands = [ |
| 504 SetBuildDir(), |
522 StartSky(), | 505 StartSky(), |
523 StopSky(), | 506 StopSky(), |
524 Analyze(), | 507 Analyze(), |
525 GDBAttach(), | 508 GDBAttach(), |
526 StartTracing(), | 509 StartTracing(), |
527 StopTracing(), | 510 StopTracing(), |
528 ] | 511 ] |
529 | 512 |
530 for command in commands: | 513 for command in commands: |
531 command.add_subparser(subparsers) | 514 command.add_subparser(subparsers) |
532 | 515 |
533 args = parser.parse_args() | 516 args = parser.parse_args() |
534 pids = Pids.read_from(PID_FILE_PATH, PID_FILE_KEYS) | 517 pids = Pids.read_from(PID_FILE_PATH, PID_FILE_KEYS) |
535 exit_code = args.func(args, pids) | 518 exit_code = args.func(args, pids) |
536 # We could do this with an at-exit handler instead? | 519 # We could do this with an at-exit handler instead? |
537 pids.write_to(PID_FILE_PATH) | 520 pids.write_to(PID_FILE_PATH) |
538 sys.exit(exit_code) | 521 sys.exit(exit_code) |
539 | 522 |
540 | 523 |
541 if __name__ == '__main__': | 524 if __name__ == '__main__': |
542 SkyShellRunner().main() | 525 SkyShellRunner().main() |
OLD | NEW |