| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Generic presubmit checks that can be reused by other presubmit checks.""" | 5 """Generic presubmit checks that can be reused by other presubmit checks.""" |
| 6 | 6 |
| 7 import os as _os | 7 import os as _os |
| 8 _HERE = _os.path.dirname(_os.path.abspath(__file__)) | 8 _HERE = _os.path.dirname(_os.path.abspath(__file__)) |
| 9 | 9 |
| 10 | 10 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 if cr_files: | 220 if cr_files: |
| 221 outputs.append(output_api.PresubmitPromptWarning( | 221 outputs.append(output_api.PresubmitPromptWarning( |
| 222 'Found a CR character in these files:', items=cr_files)) | 222 'Found a CR character in these files:', items=cr_files)) |
| 223 if eof_files: | 223 if eof_files: |
| 224 outputs.append(output_api.PresubmitPromptWarning( | 224 outputs.append(output_api.PresubmitPromptWarning( |
| 225 'These files should end in one (and only one) newline character:', | 225 'These files should end in one (and only one) newline character:', |
| 226 items=eof_files)) | 226 items=eof_files)) |
| 227 return outputs | 227 return outputs |
| 228 | 228 |
| 229 | 229 |
| 230 def _ReportErrorFileAndLine(filename, line_num, line): | 230 def _ReportErrorFileAndLine(filename, line_num, dummy_line): |
| 231 """Default error formatter for _FindNewViolationsOfRule.""" | 231 """Default error formatter for _FindNewViolationsOfRule.""" |
| 232 return '%s, line %s' % (filename, line_num) | 232 return '%s, line %s' % (filename, line_num) |
| 233 | 233 |
| 234 | 234 |
| 235 def _FindNewViolationsOfRule(callable_rule, input_api, source_file_filter=None, | 235 def _FindNewViolationsOfRule(callable_rule, input_api, source_file_filter=None, |
| 236 error_formatter=_ReportErrorFileAndLine): | 236 error_formatter=_ReportErrorFileAndLine): |
| 237 """Find all newly introduced violations of a per-line rule (a callable). | 237 """Find all newly introduced violations of a per-line rule (a callable). |
| 238 | 238 |
| 239 Arguments: | 239 Arguments: |
| 240 callable_rule: a callable taking a file extension and line of input and | 240 callable_rule: a callable taking a file extension and line of input and |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 filepath = input_api.os_path.join(dirpath, item)[path_len + 1:] | 615 filepath = input_api.os_path.join(dirpath, item)[path_len + 1:] |
| 616 if Find(filepath, white_list) and not Find(filepath, black_list): | 616 if Find(filepath, white_list) and not Find(filepath, black_list): |
| 617 files.append(filepath) | 617 files.append(filepath) |
| 618 return files | 618 return files |
| 619 | 619 |
| 620 | 620 |
| 621 def RunPylint(input_api, output_api, white_list=None, black_list=None, | 621 def RunPylint(input_api, output_api, white_list=None, black_list=None, |
| 622 disabled_warnings=None): | 622 disabled_warnings=None): |
| 623 """Run pylint on python files. | 623 """Run pylint on python files. |
| 624 | 624 |
| 625 The default white_list enforces looking only a *.py files. | 625 The default white_list enforces looking only at *.py files. |
| 626 """ | 626 """ |
| 627 white_list = tuple(white_list or ('.*\.py$',)) | 627 white_list = tuple(white_list or ('.*\.py$',)) |
| 628 black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST) | 628 black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST) |
| 629 if input_api.is_committing: | 629 if input_api.is_committing: |
| 630 error_type = output_api.PresubmitError | 630 error_type = output_api.PresubmitError |
| 631 else: | 631 else: |
| 632 error_type = output_api.PresubmitPromptWarning | 632 error_type = output_api.PresubmitPromptWarning |
| 633 | 633 |
| 634 # Only trigger if there is at least one python file affected. | 634 # Only trigger if there is at least one python file affected. |
| 635 src_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list) | 635 src_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list) |
| 636 if not input_api.AffectedSourceFiles(src_filter): | 636 if not input_api.AffectedSourceFiles(src_filter): |
| 637 return [] | 637 return [] |
| 638 | 638 |
| 639 extra_args = ['--rcfile=%s' % input_api.os_path.join(_HERE, 'pylintrc')] | 639 extra_args = ['--rcfile=%s' % input_api.os_path.join(_HERE, 'pylintrc')] |
| 640 if disabled_warnings: | 640 if disabled_warnings: |
| 641 extra_args.extend(['-d', ','.join(disabled_warnings)]) | 641 extra_args.extend(['-d', ','.join(disabled_warnings)]) |
| 642 | 642 |
| 643 # On certain pylint/python version combination, running pylint throws a lot of | 643 # On certain pylint/python version combination, running pylint throws a lot of |
| 644 # warning messages. | 644 # warning messages. |
| 645 import warnings | 645 import warnings |
| 646 warnings.filterwarnings('ignore', category=DeprecationWarning) | 646 warnings.filterwarnings('ignore', category=DeprecationWarning) |
| 647 try: | 647 try: |
| 648 files = _FetchAllFiles(input_api, white_list, black_list) | 648 files = _FetchAllFiles(input_api, white_list, black_list) |
| 649 if not files: | 649 if not files: |
| 650 return [] | 650 return [] |
| 651 # Now that at least one python file was modified and all the python files | |
| 652 # were listed, try to run pylint. | |
| 653 try: | |
| 654 from pylint import lint | |
| 655 from pylint.utils import UnknownMessage | |
| 656 input_api.logging.debug( | |
| 657 'Using pylint v%s from %s' % (lint.version, lint.__file__)) | |
| 658 except ImportError: | |
| 659 if input_api.platform == 'win32': | |
| 660 return [output_api.PresubmitNotifyResult( | |
| 661 'Warning: Can\'t run pylint because it is not installed. Please ' | |
| 662 'install manually\n' | |
| 663 'Cannot do static analysis of python files.')] | |
| 664 return [output_api.PresubmitError( | |
| 665 'Please install pylint with "sudo apt-get install python-setuptools; ' | |
| 666 'sudo easy_install pylint"\n' | |
| 667 'or visit http://pypi.python.org/pypi/setuptools.\n' | |
| 668 'Cannot do static analysis of python files.')] | |
| 669 | 651 |
| 670 def run_lint(files): | 652 def run_lint(files): |
| 653 # We can't import pylint directly due to licensing issues, so we run |
| 654 # it in another process. Windows needs help running python files so we |
| 655 # explicitly specify the interpreter to use. |
| 656 command = [input_api.python_executable, |
| 657 input_api.os_path.join(_HERE, 'third_party', 'pylint.py')] |
| 671 try: | 658 try: |
| 672 lint.Run(files + extra_args) | 659 return input_api.subprocess.call(command + files + extra_args) |
| 673 assert False | 660 except OSError: |
| 674 except SystemExit, e: | 661 return 'Pylint failed!' |
| 675 # pylint has the bad habit of calling sys.exit(), trap it here. | |
| 676 return e.code | |
| 677 except UnknownMessage, e: | |
| 678 return 'Please upgrade pylint: %s' % e | |
| 679 | 662 |
| 680 result = None | 663 result = None |
| 681 if not input_api.verbose: | 664 if not input_api.verbose: |
| 682 result = run_lint(sorted(files)) | 665 result = run_lint(sorted(files)) |
| 683 else: | 666 else: |
| 684 for filename in sorted(files): | 667 for filename in sorted(files): |
| 685 print('Running pylint on %s' % filename) | 668 print('Running pylint on %s' % filename) |
| 686 result = run_lint([filename]) or result | 669 result = run_lint([filename]) or result |
| 687 if isinstance(result, basestring): | 670 if isinstance(result, basestring): |
| 688 return [error_type(result)] | 671 return [error_type(result)] |
| 689 elif result: | 672 elif result: |
| 690 return [error_type('Fix pylint errors first.')] | 673 return [error_type('Fix pylint errors first.')] |
| 691 return [] | 674 return [] |
| 692 finally: | 675 finally: |
| 693 warnings.filterwarnings('default', category=DeprecationWarning) | 676 warnings.filterwarnings('default', category=DeprecationWarning) |
| 694 | 677 |
| 695 | 678 |
| 696 # TODO(dpranke): Get the host_url from the input_api instead | 679 # TODO(dpranke): Get the host_url from the input_api instead |
| 697 def CheckRietveldTryJobExecution(input_api, output_api, host_url, platforms, | 680 def CheckRietveldTryJobExecution(dummy_input_api, dummy_output_api, |
| 698 owner): | 681 dummy_host_url, dummy_platforms, |
| 682 dummy_owner): |
| 699 # Temporarily 'fix' the check while the Rietveld API is being upgraded to | 683 # Temporarily 'fix' the check while the Rietveld API is being upgraded to |
| 700 # something sensible. | 684 # something sensible. |
| 701 return [] | 685 return [] |
| 702 | 686 |
| 703 | 687 |
| 704 def CheckBuildbotPendingBuilds(input_api, output_api, url, max_pendings, | 688 def CheckBuildbotPendingBuilds(input_api, output_api, url, max_pendings, |
| 705 ignored): | 689 ignored): |
| 706 try: | 690 try: |
| 707 connection = input_api.urllib2.urlopen(url) | 691 connection = input_api.urllib2.urlopen(url) |
| 708 raw_data = connection.read() | 692 raw_data = connection.read() |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( | 933 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( |
| 950 input_api, output_api)) | 934 input_api, output_api)) |
| 951 snapshot("checking license") | 935 snapshot("checking license") |
| 952 results.extend(input_api.canned_checks.CheckLicense( | 936 results.extend(input_api.canned_checks.CheckLicense( |
| 953 input_api, output_api, license_header, source_file_filter=sources)) | 937 input_api, output_api, license_header, source_file_filter=sources)) |
| 954 snapshot("checking was uploaded") | 938 snapshot("checking was uploaded") |
| 955 results.extend(input_api.canned_checks.CheckChangeWasUploaded( | 939 results.extend(input_api.canned_checks.CheckChangeWasUploaded( |
| 956 input_api, output_api)) | 940 input_api, output_api)) |
| 957 snapshot("done") | 941 snapshot("done") |
| 958 return results | 942 return results |
| OLD | NEW |