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 """Top-level presubmit script for Chromium. | 5 """Top-level presubmit script for Chromium. |
6 | 6 |
7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts | 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts |
8 for more details about the presubmit API built into gcl. | 8 for more details about the presubmit API built into gcl. |
9 """ | 9 """ |
10 | 10 |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 previous_line = line | 547 previous_line = line |
548 previous_line_num = line_num | 548 previous_line_num = line_num |
549 | 549 |
550 warnings = [] | 550 warnings = [] |
551 for (line_num, previous_line_num) in problem_linenums: | 551 for (line_num, previous_line_num) in problem_linenums: |
552 if line_num in changed_linenums or previous_line_num in changed_linenums: | 552 if line_num in changed_linenums or previous_line_num in changed_linenums: |
553 warnings.append(' %s:%d' % (file_path, line_num)) | 553 warnings.append(' %s:%d' % (file_path, line_num)) |
554 return warnings | 554 return warnings |
555 | 555 |
556 | 556 |
557 def _CheckIncludeOrderInFile(input_api, output_api, f, is_source, | 557 def _CheckIncludeOrderInFile(input_api, f, is_source, changed_linenums): |
558 changed_linenums): | |
559 """Checks the #include order for the given file f.""" | 558 """Checks the #include order for the given file f.""" |
560 | 559 |
561 include_pattern = input_api.re.compile(r'\s*#include.*') | 560 system_include_pattern = input_api.re.compile(r'\s*#include \<.*') |
561 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"') | |
562 if_pattern = input_api.re.compile(r'\s*#if.*') | 562 if_pattern = input_api.re.compile(r'\s*#if.*') |
563 endif_pattern = input_api.re.compile(r'\s*#endif.*') | 563 endif_pattern = input_api.re.compile(r'\s*#endif.*') |
564 | 564 |
565 contents = f.NewContents() | 565 contents = f.NewContents() |
566 warnings = [] | 566 warnings = [] |
567 line_num = 0 | 567 line_num = 0 |
568 | 568 |
569 # Handle the special first include for source files. | 569 # Handle the special first include for source files. If the header file is |
570 # some/path/file.h, the corresponding source file can be some/path/file.cc, | |
571 # some/other/path/file.cc, some/path/file_platform.cc etc. It's also possible | |
572 # that no special first include exists. | |
570 if is_source: | 573 if is_source: |
571 for line in contents: | 574 for line in contents: |
572 line_num += 1 | 575 line_num += 1 |
573 if include_pattern.match(line): | 576 if system_include_pattern.match(line): |
574 # The file name for the first include needs to be the same as for the | 577 # No special first include -> process the line again along with normal |
575 # file checked; the path can differ. | 578 # includes. |
576 expected_ending = ( | 579 line_num -= 1 |
577 input_api.os_path.basename(f.LocalPath()).replace('.cc', '.h') + | 580 break |
578 '"') | 581 match = custom_include_pattern.match(line) |
579 if not line.endswith(expected_ending): | 582 if match: |
580 # Maybe there was no special first include, and that's fine. Process | 583 match_dict = match.groupdict() |
581 # the line again along with the normal includes. | 584 header_basename = input_api.os_path.basename( |
585 match_dict['FILE']).replace('.h', '') | |
586 if header_basename not in input_api.os_path.basename(f.LocalPath()): | |
587 # No special first include -> process the line again along with normal | |
588 # includes. | |
582 line_num -= 1 | 589 line_num -= 1 |
583 break | 590 break |
584 | 591 |
585 # Split into scopes: Each region between #if and #endif is its own scope. | 592 # Split into scopes: Each region between #if and #endif is its own scope. |
586 scopes = [] | 593 scopes = [] |
587 current_scope = [] | 594 current_scope = [] |
588 for line in contents[line_num:]: | 595 for line in contents[line_num:]: |
589 line_num += 1 | 596 line_num += 1 |
590 if if_pattern.match(line) or endif_pattern.match(line): | 597 if if_pattern.match(line) or endif_pattern.match(line): |
591 scopes.append(current_scope) | 598 scopes.append(current_scope) |
592 current_scope = [] | 599 current_scope = [] |
593 elif include_pattern.match(line): | 600 elif (system_include_pattern.match(line) or |
601 custom_include_pattern.match(line)): | |
594 current_scope.append((line_num, line)) | 602 current_scope.append((line_num, line)) |
595 scopes.append(current_scope) | 603 scopes.append(current_scope) |
596 | 604 |
597 for scope in scopes: | 605 for scope in scopes: |
598 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(), | 606 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(), |
599 changed_linenums)) | 607 changed_linenums)) |
600 return warnings | 608 return warnings |
601 | 609 |
602 | 610 |
603 def _CheckIncludeOrder(input_api, output_api): | 611 def _CheckIncludeOrder(input_api, output_api): |
604 """Checks that the #include order is correct. | 612 """Checks that the #include order is correct. |
605 | 613 |
606 1. The corresponding header for source files. | 614 1. The corresponding header for source files. |
607 2. C system files in alphabetical order | 615 2. C system files in alphabetical order |
608 3. C++ system files in alphabetical order | 616 3. C++ system files in alphabetical order |
609 4. Project's .h files in alphabetical order | 617 4. Project's .h files in alphabetical order |
610 | 618 |
611 Each region between #if and #endif follows these rules separately. | 619 Each region between #if and #endif follows these rules separately. |
612 """ | 620 """ |
613 | 621 |
614 warnings = [] | 622 warnings = [] |
615 for f in input_api.AffectedFiles(): | 623 for f in input_api.AffectedFiles(): |
616 changed_linenums = set([line_num for line_num, _ in f.ChangedContents()]) | 624 changed_linenums = set([line_num for line_num, _ in f.ChangedContents()]) |
617 if f.LocalPath().endswith('.cc'): | 625 if f.LocalPath().endswith('.cc'): |
618 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, True, | 626 warnings.extend(_CheckIncludeOrderInFile(input_api, f, True, |
619 changed_linenums) | 627 changed_linenums)) |
620 elif f.LocalPath().endswith('.h'): | 628 elif f.LocalPath().endswith('.h'): |
621 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, False, | 629 warnings.extend(_CheckIncludeOrderInFile(input_api, f, False, |
622 changed_linenums) | 630 changed_linenums)) |
623 | 631 |
624 results = [] | 632 results = [] |
625 if warnings: | 633 if warnings: |
626 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING, | 634 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING, |
627 warnings)) | 635 warnings)) |
628 return results | 636 return results |
629 | 637 |
630 | 638 |
631 def _CommonChecks(input_api, output_api): | 639 def _CommonChecks(input_api, output_api): |
632 """Checks common to both upload and commit.""" | 640 """Checks common to both upload and commit.""" |
633 results = [] | 641 results = [] |
634 results.extend(input_api.canned_checks.PanProjectChecks( | 642 results.extend(input_api.canned_checks.PanProjectChecks( |
635 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) | 643 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) |
636 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) | 644 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) |
637 results.extend( | 645 results.extend( |
638 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) | 646 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) |
639 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) | 647 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) |
640 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api)) | 648 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api)) |
641 results.extend(_CheckNoNewWStrings(input_api, output_api)) | 649 results.extend(_CheckNoNewWStrings(input_api, output_api)) |
642 results.extend(_CheckNoDEPSGIT(input_api, output_api)) | 650 results.extend(_CheckNoDEPSGIT(input_api, output_api)) |
643 results.extend(_CheckNoBannedFunctions(input_api, output_api)) | 651 results.extend(_CheckNoBannedFunctions(input_api, output_api)) |
644 results.extend(_CheckNoPragmaOnce(input_api, output_api)) | 652 results.extend(_CheckNoPragmaOnce(input_api, output_api)) |
645 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api)) | 653 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api)) |
646 results.extend(_CheckUnwantedDependencies(input_api, output_api)) | 654 results.extend(_CheckUnwantedDependencies(input_api, output_api)) |
647 results.extend(_CheckFilePermissions(input_api, output_api)) | 655 results.extend(_CheckFilePermissions(input_api, output_api)) |
648 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) | 656 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) |
649 results.extend(_CheckIncludeOrder(input_api, output_api)) | 657 results.extend(_CheckIncludeOrder(input_api, output_api)) |
658 | |
659 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()): | |
660 results.extend(input_api.canned_checks.RunUnitTestsInDirectory( | |
661 input_api, output_api, | |
662 input_api.PresubmitLocalPath(), | |
663 whitelist=[r'.+_test\.py$'])) | |
Isaac (away)
2013/01/06 10:35:48
This seems overly broad. Could we change this to
M-A Ruel
2013/01/07 15:27:04
Oh right, it should be r'[^\\/]+_test\.py$'.
| |
650 return results | 664 return results |
651 | 665 |
652 | 666 |
653 def _CheckSubversionConfig(input_api, output_api): | 667 def _CheckSubversionConfig(input_api, output_api): |
654 """Verifies the subversion config file is correctly setup. | 668 """Verifies the subversion config file is correctly setup. |
655 | 669 |
656 Checks that autoprops are enabled, returns an error otherwise. | 670 Checks that autoprops are enabled, returns an error otherwise. |
657 """ | 671 """ |
658 join = input_api.os_path.join | 672 join = input_api.os_path.join |
659 if input_api.platform == 'win32': | 673 if input_api.platform == 'win32': |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 | 801 |
788 # Match things like path/aura/file.cc and path/file_aura.cc. | 802 # Match things like path/aura/file.cc and path/file_aura.cc. |
789 # Same for ash and chromeos. | 803 # Same for ash and chromeos. |
790 if any(re.search('[/_](ash|aura)', f) for f in files): | 804 if any(re.search('[/_](ash|aura)', f) for f in files): |
791 trybots += ['linux_chromeos_clang:compile', 'win_aura', | 805 trybots += ['linux_chromeos_clang:compile', 'win_aura', |
792 'linux_chromeos_asan'] | 806 'linux_chromeos_asan'] |
793 elif any(re.search('[/_]chromeos', f) for f in files): | 807 elif any(re.search('[/_]chromeos', f) for f in files): |
794 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] | 808 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] |
795 | 809 |
796 return trybots | 810 return trybots |
OLD | NEW |