| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python | |
| 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 | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 # To integrate dartanalyze with our build system, we take an input file, run | |
| 7 # the analyzer on it, and write a stamp file if it passed. | |
| 8 | |
| 9 # This script analyzes a set of entrypoints specified with the --entrypoints | |
| 10 # flag. The location of the Dart SDK must be specified with the --dart-sdk | |
| 11 # flag. A stamp file can optionally be written with the location given by the | |
| 12 # --stamp-file flag. Any command line arguments not recognized by this script | |
| 13 # are passed on to the Dart analyzer. | |
| 14 | |
| 15 import argparse | |
| 16 import glob | |
| 17 import os | |
| 18 import re | |
| 19 import shutil | |
| 20 import subprocess | |
| 21 import sys | |
| 22 import tempfile | |
| 23 | |
| 24 _IGNORED_PATTERNS = [ | |
| 25 # Ignored because they're not indicative of specific errors. | |
| 26 re.compile(r'^$'), | |
| 27 re.compile(r'^Analyzing \['), | |
| 28 re.compile(r'^No issues found'), | |
| 29 re.compile(r'^[0-9]+ errors? and [0-9]+ warnings? found.'), | |
| 30 re.compile(r'^([0-9]+|No) (error|warning|issue)s? found.'), | |
| 31 | |
| 32 # TODO: It seems like this should be re-enabled evenutally. | |
| 33 re.compile(r'.*is a part and can not|^Only libraries can be analyzed'), | |
| 34 # TODO: Remove this once dev SDK includes Uri.directory constructor. | |
| 35 re.compile(r'.*The class \'Uri\' does not have a constructor \'directory\''), | |
| 36 # TODO: Remove this once Sky no longer generates this warning. | |
| 37 # dartbug.com/22836 | |
| 38 re.compile(r'.*cannot both be unnamed'), | |
| 39 | |
| 40 # The Dart SDK seems to generate some hints and lints. | |
| 41 re.compile(r'.*\/dart-sdk\/'), | |
| 42 ] | |
| 43 | |
| 44 | |
| 45 def _success(stamp_file): | |
| 46 # We passed cleanly, so touch the stamp file so that we don't run again. | |
| 47 with open(stamp_file, 'a'): | |
| 48 os.utime(stamp_file, None) | |
| 49 return 0 | |
| 50 | |
| 51 | |
| 52 def analyze_and_filter(cmd, temp_dir=None, dirname=None): | |
| 53 errors = None | |
| 54 try: | |
| 55 subprocess.check_output(cmd, shell=False, stderr=subprocess.STDOUT) | |
| 56 except subprocess.CalledProcessError as e: | |
| 57 errors = set(l for l in e.output.split('\n') | |
| 58 if not any(p.match(l) for p in _IGNORED_PATTERNS)) | |
| 59 for error in sorted(errors): | |
| 60 if dirname is None: | |
| 61 print >> sys.stderr, error | |
| 62 else: | |
| 63 print >> sys.stderr, error.replace(temp_dir + "/", dirname) | |
| 64 return errors | |
| 65 | |
| 66 | |
| 67 def analyze_entrypoints(dart_sdk, entrypoints, args): | |
| 68 cmd = [ os.path.join(dart_sdk, 'bin', 'dartanalyzer') ] | |
| 69 cmd.extend(entrypoints) | |
| 70 cmd.extend(args) | |
| 71 cmd.append("--fatal-warnings") | |
| 72 cmd.append("--fatal-lints") | |
| 73 cmd.append("--fatal-hints") | |
| 74 errors = analyze_and_filter(cmd) | |
| 75 if errors is None: | |
| 76 return 0 | |
| 77 return min(255, len(errors)) | |
| 78 | |
| 79 | |
| 80 def main(): | |
| 81 parser = argparse.ArgumentParser(description='Run the Dart analyzer.') | |
| 82 parser.add_argument('--dart-sdk', | |
| 83 action='store', | |
| 84 type=str, | |
| 85 metavar='dart_sdk', | |
| 86 help='Path to the Dart SDK', | |
| 87 required=True) | |
| 88 parser.add_argument('--stamp-file', | |
| 89 action='store', | |
| 90 type=str, | |
| 91 metavar='stamp_file', | |
| 92 help='Stamp file to write on success.', | |
| 93 default=None) | |
| 94 parser.add_argument('--entrypoints', | |
| 95 help='Entry points to analyze', | |
| 96 nargs='*', | |
| 97 default=[]) | |
| 98 args, remainder = parser.parse_known_args() | |
| 99 | |
| 100 if args.entrypoints == []: | |
| 101 parser.print_help() | |
| 102 return 1 | |
| 103 | |
| 104 return analyze_entrypoints(args.dart_sdk, args.entrypoints, remainder) | |
| 105 | |
| 106 if __name__ == '__main__': | |
| 107 sys.exit(main()) | |
| OLD | NEW |