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 |