Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Checks protobuf files for illegal imports.""" | |
| 6 | |
| 7 import codecs | |
| 8 import os | |
| 9 import re | |
| 10 | |
| 11 import results | |
| 12 from rules import Rule, MessageRule | |
| 13 | |
| 14 | |
| 15 class ProtoChecker(object): | |
| 16 | |
| 17 EXTENSIONS = [ | |
| 18 '.proto', | |
| 19 ] | |
| 20 | |
| 21 # The maximum number of non-import lines we can see before giving up. | |
| 22 _MAX_UNINTERESTING_LINES = 50 | |
| 23 | |
| 24 # The maximum line length, this is to be efficient in the case of very long | |
| 25 # lines (which can't be import). | |
| 26 _MAX_LINE_LENGTH = 128 | |
| 27 | |
| 28 # This regular expression will be used to extract filenames from import | |
| 29 # statements. | |
| 30 _EXTRACT_IMPORT_PATH = re.compile( | |
| 31 '[ \t]*[ \t]*import[ \t]+"(.*)"') | |
| 32 | |
| 33 def __init__(self, verbose, resolve_dotdot=False, root_dir=''): | |
| 34 self._verbose = verbose | |
| 35 self._resolve_dotdot = resolve_dotdot | |
| 36 self._root_dir = root_dir | |
| 37 | |
| 38 def CheckLine(self, rules, line, dependee_path, fail_on_temp_allow=False): | |
| 39 """Checks the given line with the given rule set. | |
| 40 | |
| 41 Returns a tuple (is_import, dependency_violation) where | |
| 42 is_import is True only if the line is an import | |
| 43 statement, and dependency_violation is an instance of | |
| 44 results.DependencyViolation if the line violates a rule, or None | |
| 45 if it does not. | |
| 46 """ | |
| 47 found_item = self._EXTRACT_IMPORT_PATH.match(line) | |
| 48 if not found_item: | |
| 49 return False, None # Not a match | |
| 50 | |
| 51 import_path = found_item.group(1) | |
| 52 | |
| 53 if '\\' in import_path: | |
| 54 return True, results.DependencyViolation( | |
| 55 import_path, | |
| 56 MessageRule('Import paths may not include backslashes.'), | |
| 57 rules) | |
| 58 | |
| 59 if '/' not in import_path: | |
| 60 # Don't fail when no directory is specified. We may want to be more | |
| 61 # strict about this in the future. | |
| 62 if self._verbose: | |
| 63 print ' WARNING: import specified with no directory: ' + import_path | |
| 64 return True, None | |
| 65 | |
| 66 if self._resolve_dotdot and '../' in import_path: | |
| 67 dependee_dir = os.path.dirname(dependee_path) | |
| 68 import_path = os.path.join(dependee_dir, import_path) | |
| 69 import_path = os.path.relpath(import_path, self._root_dir) | |
| 70 | |
| 71 rule = rules.RuleApplyingTo(import_path, dependee_path) | |
| 72 if (rule.allow == Rule.DISALLOW or | |
| 73 (fail_on_temp_allow and rule.allow == Rule.TEMP_ALLOW)): | |
| 74 return True, results.DependencyViolation(import_path, rule, rules) | |
| 75 return True, None | |
| 76 | |
| 77 def CheckFile(self, rules, filepath): | |
| 78 if self._verbose: | |
| 79 print 'Checking: ' + filepath | |
| 80 | |
| 81 dependee_status = results.DependeeStatus(filepath) | |
| 82 last_import = 0 | |
| 83 with codecs.open(filepath, encoding='utf-8') as f: | |
| 84 for line_num, line in enumerate(f): | |
| 85 if line_num - last_import > self._MAX_UNINTERESTING_LINES: | |
| 86 break | |
| 87 | |
| 88 line = line.strip() | |
| 89 | |
| 90 is_import, violation = self.CheckLine(rules, line, filepath) | |
| 91 if is_import: | |
| 92 last_import = line_num | |
| 93 if violation: | |
| 94 dependee_status.AddViolation(violation) | |
| 95 | |
| 96 return dependee_status | |
| 97 | |
| 98 @staticmethod | |
| 99 def IsProtoFile(file_path): | |
| 100 """Returns True iff the given path ends in one of the extensions | |
|
brettw
2017/01/25 21:12:18
I find "iff" harder to read and unnecessary (in pr
| |
| 101 handled by this checker. | |
| 102 """ | |
| 103 return os.path.splitext(file_path)[1] in ProtoChecker.EXTENSIONS | |
| 104 | |
| 105 def ShouldCheck(self, file_path): | |
| 106 """Check if the new #include file path should be presubmit checked. | |
| 107 | |
| 108 Args: | |
| 109 file_path: file path to be checked | |
| 110 | |
| 111 Return: | |
| 112 bool: True if the file should be checked; False otherwise. | |
| 113 """ | |
| 114 return self.IsProtoFile(file_path) | |
| OLD | NEW |