OLD | NEW |
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 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 ### Description checks | 7 ### Description checks |
8 | 8 |
9 def CheckChangeHasTestField(input_api, output_api): | 9 def CheckChangeHasTestField(input_api, output_api): |
10 """Requires that the changelist have a TEST= field.""" | 10 """Requires that the changelist have a TEST= field.""" |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 # Discard the output if returncode == 0 | 443 # Discard the output if returncode == 0 |
444 if subproc.returncode: | 444 if subproc.returncode: |
445 outputs.append('Test \'%s\' failed with code %d\n%s\n%s\n' % ( | 445 outputs.append('Test \'%s\' failed with code %d\n%s\n%s\n' % ( |
446 unit_test_name, subproc.returncode, stdoutdata, stderrdata)) | 446 unit_test_name, subproc.returncode, stdoutdata, stderrdata)) |
447 if outputs: | 447 if outputs: |
448 return [message_type('%d unit tests failed.' % len(outputs), | 448 return [message_type('%d unit tests failed.' % len(outputs), |
449 long_text='\n'.join(outputs))] | 449 long_text='\n'.join(outputs))] |
450 return [] | 450 return [] |
451 | 451 |
452 | 452 |
453 def RunPylint(input_api, output_api, source_file_filter=None): | 453 def RunPylint(input_api, output_api, white_list=None, black_list=None): |
454 """Run pylint on python files.""" | 454 """Run pylint on python files. |
455 import warnings | 455 |
| 456 The default white_list enforces looking only a *.py files. |
| 457 """ |
| 458 white_list = white_list or ['.*\.py$'] |
| 459 black_list = black_list or input_api.DEFAULT_BLACK_LIST |
| 460 |
| 461 # Only trigger if there is at least one python file affected. |
| 462 src_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list) |
| 463 if not input_api.AffectedSourceFiles(src_filter): |
| 464 return [] |
| 465 |
456 # On certain pylint/python version combination, running pylint throws a lot of | 466 # On certain pylint/python version combination, running pylint throws a lot of |
457 # warning messages. | 467 # warning messages. |
| 468 import warnings |
458 warnings.filterwarnings('ignore', category=DeprecationWarning) | 469 warnings.filterwarnings('ignore', category=DeprecationWarning) |
459 try: | 470 try: |
460 if not source_file_filter: | 471 # We cannot use AffectedFiles here because we want to test every python |
461 source_file_filter = lambda f: f.LocalPath().endswith('.py') | 472 # file on each single python change. It's because a change in a python file |
462 files = [f.LocalPath() | 473 # can break another unmodified file. |
463 for f in input_api.AffectedSourceFiles(source_file_filter)] | 474 # Use code similar to InputApi.FilterSourceFile() |
| 475 def Find(filepath, filters): |
| 476 for item in filters: |
| 477 if input_api.re.match(item, filepath): |
| 478 return True |
| 479 return False |
| 480 |
| 481 import os |
| 482 files = [] |
| 483 for dirpath, dirnames, filenames in os.walk(input_api.PresubmitLocalPath()): |
| 484 # Passes dirnames in black list to speed up search. |
| 485 for item in dirnames[:]: |
| 486 if Find(input_api.os_path.join(dirpath, item), black_list): |
| 487 dirnames.remove(item) |
| 488 for item in filenames: |
| 489 filepath = input_api.os_path.join(dirpath, item) |
| 490 if Find(filepath, white_list) and not Find(filepath, black_list): |
| 491 files.append(filepath) |
| 492 |
| 493 # Now that at least one python file was modified and all the python files |
| 494 # were listed, try to run pylint. |
464 try: | 495 try: |
465 from pylint import lint | 496 from pylint import lint |
466 if lint.Run(sorted(files)): | 497 if lint.Run(sorted(files)): |
467 return [output_api.PresubmitPromptWarning('Fix pylint errors first.')] | 498 return [output_api.PresubmitPromptWarning('Fix pylint errors first.')] |
468 return [] | 499 return [] |
469 except ImportError: | 500 except ImportError: |
470 if input_api.platform == 'win32': | 501 if input_api.platform == 'win32': |
471 return [output_api.PresubmitNotifyResult( | 502 return [output_api.PresubmitNotifyResult( |
472 'Warning: Can\'t run pylint because it is not installed. Please ' | 503 'Warning: Can\'t run pylint because it is not installed. Please ' |
473 'install manually\n' | 504 'install manually\n' |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 pending_builds_len = len(builder.get('pending_builds', [])) | 587 pending_builds_len = len(builder.get('pending_builds', [])) |
557 if pending_builds_len > max_pendings: | 588 if pending_builds_len > max_pendings: |
558 out.append('%s has %d build(s) pending' % | 589 out.append('%s has %d build(s) pending' % |
559 (builder_name, pending_builds_len)) | 590 (builder_name, pending_builds_len)) |
560 if out: | 591 if out: |
561 return [output_api.PresubmitPromptWarning( | 592 return [output_api.PresubmitPromptWarning( |
562 'Build(s) pending. It is suggested to wait that no more than %d ' | 593 'Build(s) pending. It is suggested to wait that no more than %d ' |
563 'builds are pending.' % max_pendings, | 594 'builds are pending.' % max_pendings, |
564 long_text='\n'.join(out))] | 595 long_text='\n'.join(out))] |
565 return [] | 596 return [] |
OLD | NEW |