Index: build/android/pylib/findbugs.py |
diff --git a/build/android/pylib/findbugs.py b/build/android/pylib/findbugs.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..350678b45ae933a9fe6fb8536271e3c2cbee4b25 |
--- /dev/null |
+++ b/build/android/pylib/findbugs.py |
@@ -0,0 +1,210 @@ |
+#!/usr/bin/python |
bulach
2012/10/25 08:30:06
nit: env
michaelbai
2012/10/25 21:13:26
Done.
|
+# |
+# Copyright (c) 2012 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. |
+ |
+import optparse |
+import os |
+import re |
+import shlex |
+import subprocess |
+import sys |
+ |
bulach
2012/10/25 08:30:06
nit: extra \n
michaelbai
2012/10/25 21:13:26
Done.
|
+def _PrintMessage(warnings, title, action, known_bugs_file): |
+ if warnings: |
+ print '*' * 80 |
+ print '%s warnings.' % title |
+ print '%s %s' % (action, known_bugs_file) |
+ print '-' * 80 |
+ for warning in warnings: |
+ print warning |
+ print '-' * 80 |
+ |
+ |
+def _StripLineNumbers(current_warnings): |
+ re_line = r':\[line.*?\]$' |
+ return [re.sub(re_line, '', x) for x in current_warnings] |
+ |
+ |
+def _DiffKnownWarnings(current_warnings_set, known_bugs_file): |
+ with open(known_bugs_file, 'r') as known_bugs: |
+ known_bugs_set = set(known_bugs.read().splitlines()) |
+ |
+ new_warnings = current_warnings_set - known_bugs_set |
+ _PrintMessage(sorted(new_warnings), 'New', 'Please fix, or perhaps add to', |
+ known_bugs_file) |
+ |
+ obsolete_warnings = known_bugs_set - current_warnings_set |
+ _PrintMessage(sorted(obsolete_warnings), 'Obsolete', 'Please remove from', |
+ known_bugs_file) |
+ |
+ count = len(new_warnings) + len(obsolete_warnings) |
+ if count: |
+ print '*** %d FindBugs warning%s! ***' % (count, 's' * (count > 1)) |
+ if len(new_warnings): |
+ print '*** %d: new ***' % len(new_warnings) |
+ if len(obsolete_warnings): |
+ print '*** %d: obsolete ***' % len(obsolete_warnings) |
+ print 'Alternatively, rebaseline with --rebaseline command option' |
+ else: |
+ print 'No new FindBugs warnings.' |
+ return count |
+ |
+ |
+def _Rebaseline(current_warnings_set, known_bugs_file): |
+ with file(known_bugs_file, 'w') as known_bugs: |
+ for warning in sorted(current_warnings_set): |
+ print >>known_bugs, warning |
+ return 0 |
+ |
+ |
+def _GetChromeClasses(release_version): |
+ chrome_src = os.getenv('CHROME_SRC') |
+ version = 'Debug' |
bulach
2012/10/25 08:30:06
nit: as above, this would probably be better as bu
michaelbai
2012/10/25 21:13:26
As comment's above, it might be better to keep the
|
+ if release_version: |
+ version = 'Release' |
+ path = os.path.join(chrome_src, 'out', version) |
+ cmd = 'find %s -name "*.class"' % path |
+ proc = subprocess.Popen(shlex.split(cmd), |
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
+ out, err = proc.communicate() |
+ |
+ if not out: |
+ print 'No classes found in %s' % path |
+ return out |
+ |
+ |
+def Run(exclude, known_bugs, classes_to_analyze, auxiliary_classes, |
+ rebaseline, release_version, findbug_args): |
+ """Run the FindBugs. |
+ |
+ Args: |
+ exclude: the exclude xml file, refer to FindBugs's -exclude command option. |
+ known_bugs: the text file of known bugs. The bugs in it will not be |
+ reported. |
+ classes_to_analyze: the list of classes need to analyze, refer to FindBug's |
+ -onlyAnalyze command line option. |
+ auxiliary_classes: the classes help to analyze, refer to FindBug's |
+ -auxclasspath command line option. |
+ rebaseline: True if the known_bugs file needs rebaseline. |
+ release_version: True if the release version needs check, otherwise check |
+ debug version. |
+ findbug_args: addtional command line options needs pass to Findbugs. |
+ """ |
+ |
+ chrome_src = os.getenv('CHROME_SRC') |
+ sdk_root = os.getenv('ANDROID_SDK_ROOT') |
+ sdk_version = os.getenv('ANDROID_SDK_VERSION') |
+ if not (chrome_src and sdk_root and sdk_version): |
+ print 'Your build environment is not set up correctly.' |
+ print 'Please source build/android/envsetup.sh.' |
+ return 1 |
+ |
+ system_classes = [] |
+ system_classes.append(os.path.join(sdk_root, 'platforms', |
+ 'android-%s' % sdk_version, 'android.jar')) |
+ if auxiliary_classes: |
+ for classes in auxiliary_classes: |
+ system_classes.append(os.path.abspath(classes)) |
+ |
+ cmd = '%s -textui -sortByClass ' % os.path.join(chrome_src, 'clank', |
+ 'third_party', 'findbugs', |
+ 'bin', 'findbugs') |
+ cmd = '%s -pluginList %s' % (cmd, os.path.join(chrome_src, 'tools', 'android', |
+ 'findbugs_plugin', 'lib', |
+ 'chromiumPlugin.jar')) |
+ if len(system_classes): |
+ cmd = '%s -auxclasspath %s ' % (cmd, ':'.join(system_classes)) |
+ |
+ if classes_to_analyze: |
+ cmd = '%s -onlyAnalyze %s ' % (cmd, classes_to_analyze) |
+ |
+ if exclude: |
+ cmd = '%s -exclude %s ' % (cmd, os.path.abspath(exclude)) |
+ |
+ if findbug_args: |
+ cmd = '%s %s ' % (cmd, fingbug_args) |
+ |
+ |
+ chrome_classes = _GetChromeClasses(release_version) |
+ if not chrome_classes: |
+ return 1 |
+ cmd = '%s %s ' % (cmd, chrome_classes) |
+ |
+ proc = subprocess.Popen(shlex.split(cmd), |
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
+ out, err = proc.communicate() |
+ current_warnings_set = set(_StripLineNumbers(filter(None, out.splitlines()))) |
+ |
+ if rebaseline: |
+ return _Rebaseline(current_warnings_set, known_bugs) |
+ else: |
+ return _DiffKnownWarnings(current_warnings_set, known_bugs) |
+ |
+ |
+def main(argv): |
+ parser = optparse.OptionParser() |
+ parser.add_option('-r', |
+ '--rebaseline', |
+ action='store_true', |
+ default=False, |
bulach
2012/10/25 08:30:06
nit: same nits from above..
michaelbai
2012/10/25 21:13:26
Done.
|
+ dest='rebaseline', |
+ help='Rebaseline known findbugs issues.') |
+ |
+ parser.add_option('-a', |
+ '--auxclasspath', |
+ action='store', |
+ default=None, |
+ dest='auxclasspath', |
+ help='Set aux classpath for analysis.') |
+ |
+ parser.add_option('-o', |
+ '--only-analyze', |
+ action='store', |
+ default=None, |
+ dest='only_analyze', |
+ help='Only analyze the given classes and packages.') |
+ |
+ parser.add_option('-e', |
+ '--exclude', |
+ action='store', |
+ default=None, |
+ dest='exclude', |
+ help='Exclude bugs matching given filter.') |
+ |
+ parser.add_option('-k', |
+ '--known-bugs', |
+ action='store', |
+ default=None, |
+ dest='known_bugs', |
+ help='No report the bugs in the given file.') |
+ |
+ parser.add_option('-l', |
+ '--release', |
+ action='store_true', |
+ default=False, |
+ dest='release_version', |
+ help='Whether check release version.') |
+ |
+ parser.add_option('-f', |
+ '--findbug-args', |
+ action='store', |
+ default=None, |
+ dest='findbug_args', |
+ help='Additoinal findbug arguments.') |
+ |
+ options, _ = parser.parse_args() |
+ |
+ return Run(options.exclude, options.known_bugs, options.only_analyze, |
+ options.auxclasspath.split(':'), options.rebaseline, |
+ options.findbug_args, options.release_version) |
+ |
+ |
+if __name__ == '__main__': |
+ sys.exit(main(sys.argv)) |