Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: tools/checkdeps/builddeps.py

Issue 244313005: Fix a few typos and style in checkdeps (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Python style fixes too Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/checkdeps/checkdeps.py » ('j') | tools/checkdeps/checkdeps.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Traverses the source tree, parses all found DEPS files, and constructs 6 """Traverses the source tree, parses all found DEPS files, and constructs
7 a dependency rule table to be used by subclasses. 7 a dependency rule table to be used by subclasses.
8 8
9 The format of the deps file: 9 The format of the deps file:
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 so you can modify or remove it using the normal include rules. 68 so you can modify or remove it using the normal include rules.
69 69
70 The rules are processed in order. This means you can explicitly allow a higher 70 The rules are processed in order. This means you can explicitly allow a higher
71 directory and then take away permissions from sub-parts, or the reverse. 71 directory and then take away permissions from sub-parts, or the reverse.
72 72
73 Note that all directory separators must be slashes (Unix-style) and not 73 Note that all directory separators must be slashes (Unix-style) and not
74 backslashes. All directories should be relative to the source root and use 74 backslashes. All directories should be relative to the source root and use
75 only lowercase. 75 only lowercase.
76 """ 76 """
77 77
78 import copy
78 import os 79 import os
79 import subprocess 80 import subprocess
80 import copy
81 81
82 from rules import Rule, Rules 82 from rules import Rule, Rules
83 83
84 84
85 # Variable name used in the DEPS file to add or subtract include files from 85 # Variable name used in the DEPS file to add or subtract include files from
86 # the module-level deps. 86 # the module-level deps.
87 INCLUDE_RULES_VAR_NAME = 'include_rules' 87 INCLUDE_RULES_VAR_NAME = 'include_rules'
88 88
89 # Variable name used in the DEPS file to add or subtract include files 89 # Variable name used in the DEPS file to add or subtract include files
90 # from module-level deps specific to files whose basename (last 90 # from module-level deps specific to files whose basename (last
(...skipping 18 matching lines...) Expand all
109 def __init__(self, 109 def __init__(self,
110 base_directory=None, 110 base_directory=None,
111 verbose=False, 111 verbose=False,
112 being_tested=False, 112 being_tested=False,
113 ignore_temp_rules=False, 113 ignore_temp_rules=False,
114 ignore_specific_rules=False): 114 ignore_specific_rules=False):
115 """Creates a new DepsBuilder. 115 """Creates a new DepsBuilder.
116 116
117 Args: 117 Args:
118 base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src. 118 base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src.
119 verbose: Set to true for debug output. 119 verbose: Set to True for debug output.
120 being_tested: Set to true to ignore the DEPS file at tools/checkdeps/DEPS. 120 being_tested: Set to True to ignore the DEPS file at tools/checkdeps/DEPS.
121 ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!"). 121 ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!").
122 """ 122 """
123 base_directory = (base_directory or 123 base_directory = (base_directory or
124 os.path.join(os.path.dirname(__file__), '..', '..')) 124 os.path.join(os.path.dirname(__file__), '..', '..'))
125 self.base_directory = os.path.abspath(base_directory) 125 self.base_directory = os.path.abspath(base_directory)
126 self.verbose = verbose 126 self.verbose = verbose
127 self._under_test = being_tested 127 self._under_test = being_tested
128 self._ignore_temp_rules = ignore_temp_rules 128 self._ignore_temp_rules = ignore_temp_rules
129 self._ignore_specific_rules = ignore_specific_rules 129 self._ignore_specific_rules = ignore_specific_rules
130 130
(...skipping 15 matching lines...) Expand all
146 from the "specific_include_rules" section of DEPS. 146 from the "specific_include_rules" section of DEPS.
147 cur_dir: The current directory, normalized path. We will create an 147 cur_dir: The current directory, normalized path. We will create an
148 implicit rule that allows inclusion from this directory. 148 implicit rule that allows inclusion from this directory.
149 149
150 Returns: A new set of rules combining the existing_rules with the other 150 Returns: A new set of rules combining the existing_rules with the other
151 arguments. 151 arguments.
152 """ 152 """
153 rules = copy.deepcopy(existing_rules) 153 rules = copy.deepcopy(existing_rules)
154 154
155 # First apply the implicit "allow" rule for the current directory. 155 # First apply the implicit "allow" rule for the current directory.
156 if cur_dir.startswith( 156 norm_base_dir = NormalizePath(os.path.normpath(self.base_directory))
157 NormalizePath(os.path.normpath(self.base_directory))): 157 if not cur_dir.startswith(norm_base_dir):
158 relative_dir = cur_dir[len(self.base_directory) + 1:] 158 raise Exception(
159 'Internal error: base directory is not at the beginning for\n'
160 ' %s and base dir\n'
161 ' %s' % (cur_dir, norm_base_dir))
162 relative_dir = os.path.relpath(cur_dir, norm_base_dir)
159 163
160 source = relative_dir 164 # Make the help string a little more meaningful.
161 if len(source) == 0: 165 source = relative_dir or 'top level'
162 source = 'top level' # Make the help string a little more meaningful. 166 rules.AddRule('+' + relative_dir,
163 rules.AddRule('+' + relative_dir, 167 relative_dir,
164 relative_dir, 168 'Default rule for ' + source)
165 'Default rule for ' + source)
166 else:
167 raise Exception('Internal error: base directory is not at the beginning' +
168 ' for\n %s and base dir\n %s' %
169 (cur_dir, self.base_directory))
170 169
171 def ApplyOneRule(rule_str, cur_dir, dependee_regexp=None): 170 def ApplyOneRule(rule_str, cur_dir, dependee_regexp=None):
172 """Deduces a sensible description for the rule being added, and 171 """Deduces a sensible description for the rule being added, and
173 adds the rule with its description to |rules|. 172 adds the rule with its description to |rules|.
174 173
175 If we are ignoring temporary rules, this function does nothing 174 If we are ignoring temporary rules, this function does nothing
176 for rules beginning with the Rule.TEMP_ALLOW character. 175 for rules beginning with the Rule.TEMP_ALLOW character.
177 """ 176 """
178 if self._ignore_temp_rules and rule_str.startswith(Rule.TEMP_ALLOW): 177 if self._ignore_temp_rules and rule_str.startswith(Rule.TEMP_ALLOW):
179 return 178 return
180 179
181 rule_block_name = 'include_rules' 180 rule_block_name = 'include_rules'
182 if dependee_regexp: 181 if dependee_regexp:
183 rule_block_name = 'specific_include_rules' 182 rule_block_name = 'specific_include_rules'
184 if not relative_dir: 183 if relative_dir:
184 rule_description = relative_dir + "'s %s" % rule_block_name
185 else:
185 rule_description = 'the top level %s' % rule_block_name 186 rule_description = 'the top level %s' % rule_block_name
186 else:
187 rule_description = relative_dir + "'s %s" % rule_block_name
188 rules.AddRule(rule_str, relative_dir, rule_description, dependee_regexp) 187 rules.AddRule(rule_str, relative_dir, rule_description, dependee_regexp)
189 188
190 # Apply the additional explicit rules. 189 # Apply the additional explicit rules.
191 for (_, rule_str) in enumerate(includes): 190 for rule_str in includes:
192 ApplyOneRule(rule_str, cur_dir) 191 ApplyOneRule(rule_str, cur_dir)
193 192
194 # Finally, apply the specific rules. 193 # Finally, apply the specific rules.
195 if not self._ignore_specific_rules: 194 if not self._ignore_specific_rules:
196 for regexp, specific_rules in specific_includes.iteritems(): 195 for regexp, specific_rules in specific_includes.iteritems():
197 for rule_str in specific_rules: 196 for rule_str in specific_rules:
198 ApplyOneRule(rule_str, cur_dir, regexp) 197 ApplyOneRule(rule_str, cur_dir, regexp)
199 198
200 return rules 199 return rules
201 200
(...skipping 13 matching lines...) Expand all
215 214
216 Returns: A tuple containing: (1) the combined set of rules to apply to the 215 Returns: A tuple containing: (1) the combined set of rules to apply to the
217 sub-tree, and (2) a list of all subdirectories that should NOT be 216 sub-tree, and (2) a list of all subdirectories that should NOT be
218 checked, as specified in the DEPS file (if any). 217 checked, as specified in the DEPS file (if any).
219 """ 218 """
220 norm_dir_name = NormalizePath(dir_name) 219 norm_dir_name = NormalizePath(dir_name)
221 220
222 # Check for a .svn directory in this directory or check this directory is 221 # Check for a .svn directory in this directory or check this directory is
223 # contained in git source direcotries. This will tell us if it's a source 222 # contained in git source direcotries. This will tell us if it's a source
224 # directory and should be checked. 223 # directory and should be checked.
225 if not (os.path.exists(os.path.join(dir_name, ".svn")) or 224 if not (os.path.exists(os.path.join(dir_name, '.svn')) or
226 (norm_dir_name in self.git_source_directories)): 225 (norm_dir_name in self.git_source_directories)):
227 return (None, []) 226 return None, []
228 227
229 # Check the DEPS file in this directory. 228 # Check the DEPS file in this directory.
230 if self.verbose: 229 if self.verbose:
231 print 'Applying rules from', dir_name 230 print 'Applying rules from', dir_name
232 def FromImpl(_unused, _unused2): 231 def FromImpl(*_):
233 pass # NOP function so "From" doesn't fail. 232 pass # NOP function so "From" doesn't fail.
234 233
235 def FileImpl(_unused): 234 def FileImpl(_):
236 pass # NOP function so "File" doesn't fail. 235 pass # NOP function so "File" doesn't fail.
237 236
238 class _VarImpl: 237 class _VarImpl:
239 def __init__(self, local_scope): 238 def __init__(self, local_scope):
240 self._local_scope = local_scope 239 self._local_scope = local_scope
241 240
242 def Lookup(self, var_name): 241 def Lookup(self, var_name):
243 """Implements the Var syntax.""" 242 """Implements the Var syntax."""
244 if var_name in self._local_scope.get('vars', {}): 243 try:
245 return self._local_scope['vars'][var_name] 244 return self._local_scope['vars'][var_name]
246 raise Exception('Var is not defined: %s' % var_name) 245 except KeyError:
246 raise Exception('Var is not defined: %s' % var_name)
247 247
248 local_scope = {} 248 local_scope = {}
249 global_scope = { 249 global_scope = {
250 'File': FileImpl, 250 'File': FileImpl,
251 'From': FromImpl, 251 'From': FromImpl,
252 'Var': _VarImpl(local_scope).Lookup, 252 'Var': _VarImpl(local_scope).Lookup,
253 } 253 }
254 deps_file = os.path.join(dir_name, 'DEPS') 254 deps_file = os.path.join(dir_name, 'DEPS')
255 255
256 # The second conditional here is to disregard the 256 # The second conditional here is to disregard the
257 # tools/checkdeps/DEPS file while running tests. This DEPS file 257 # tools/checkdeps/DEPS file while running tests. This DEPS file
258 # has a skip_child_includes for 'testdata' which is necessary for 258 # has a skip_child_includes for 'testdata' which is necessary for
259 # running production tests, since there are intentional DEPS 259 # running production tests, since there are intentional DEPS
260 # violations under the testdata directory. On the other hand when 260 # violations under the testdata directory. On the other hand when
261 # running tests, we absolutely need to verify the contents of that 261 # running tests, we absolutely need to verify the contents of that
262 # directory to trigger those intended violations and see that they 262 # directory to trigger those intended violations and see that they
263 # are handled correctly. 263 # are handled correctly.
264 if os.path.isfile(deps_file) and ( 264 if os.path.isfile(deps_file) and (
265 not self._under_test or not os.path.split(dir_name)[1] == 'checkdeps'): 265 not self._under_test or not os.path.basename(dir_name) == 'checkdeps'):
266 execfile(deps_file, global_scope, local_scope) 266 execfile(deps_file, global_scope, local_scope)
267 elif self.verbose: 267 elif self.verbose:
268 print ' No deps file found in', dir_name 268 print ' No deps file found in', dir_name
269 269
270 # Even if a DEPS file does not exist we still invoke ApplyRules 270 # Even if a DEPS file does not exist we still invoke ApplyRules
271 # to apply the implicit "allow" rule for the current directory 271 # to apply the implicit "allow" rule for the current directory
272 include_rules = local_scope.get(INCLUDE_RULES_VAR_NAME, []) 272 include_rules = local_scope.get(INCLUDE_RULES_VAR_NAME, [])
273 specific_include_rules = local_scope.get(SPECIFIC_INCLUDE_RULES_VAR_NAME, 273 specific_include_rules = local_scope.get(SPECIFIC_INCLUDE_RULES_VAR_NAME,
274 {}) 274 {})
275 skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, []) 275 skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, [])
(...skipping 27 matching lines...) Expand all
303 """ 303 """
304 norm_dir_path = NormalizePath(dir_path) 304 norm_dir_path = NormalizePath(dir_path)
305 305
306 if not norm_dir_path.startswith( 306 if not norm_dir_path.startswith(
307 NormalizePath(os.path.normpath(self.base_directory))): 307 NormalizePath(os.path.normpath(self.base_directory))):
308 dir_path = os.path.join(self.base_directory, dir_path) 308 dir_path = os.path.join(self.base_directory, dir_path)
309 norm_dir_path = NormalizePath(dir_path) 309 norm_dir_path = NormalizePath(dir_path)
310 310
311 parent_dir = os.path.dirname(dir_path) 311 parent_dir = os.path.dirname(dir_path)
312 parent_rules = None 312 parent_rules = None
313 if not norm_dir_path in self.directory_rules: 313 if norm_dir_path not in self.directory_rules:
314 parent_rules = self.GetDirectoryRules(parent_dir) 314 parent_rules = self.GetDirectoryRules(parent_dir)
315 315
316 # We need to check for an entry for our dir_path again, in case we 316 # We need to check for an entry for our dir_path again, in case we
317 # are at a path e.g. A/B/C where A/B/DEPS specifies the C 317 # are at a path e.g. A/B/C where A/B/DEPS specifies the C
318 # subdirectory to be skipped; in this case, the invocation to 318 # subdirectory to be skipped; in this case, the invocation to
319 # GetDirectoryRules(parent_dir) has already filled in an entry for 319 # GetDirectoryRules(parent_dir) has already filled in an entry for
320 # A/B/C. 320 # A/B/C.
321 if not norm_dir_path in self.directory_rules: 321 if norm_dir_path not in self.directory_rules:
322 if not parent_rules: 322 if parent_rules:
323 self._ApplyDirectoryRulesAndSkipSubdirs(parent_rules, dir_path)
324 else:
323 # If the parent directory should be skipped, then the current 325 # If the parent directory should be skipped, then the current
324 # directory should also be skipped. 326 # directory should also be skipped.
325 self.directory_rules[norm_dir_path] = None 327 self.directory_rules[norm_dir_path] = None
326 else:
327 self._ApplyDirectoryRulesAndSkipSubdirs(parent_rules, dir_path)
328 return self.directory_rules[norm_dir_path] 328 return self.directory_rules[norm_dir_path]
329 329
330 def _AddGitSourceDirectories(self): 330 def _AddGitSourceDirectories(self):
331 """Adds any directories containing sources managed by git to 331 """Adds any directories containing sources managed by git to
332 self.git_source_directories. 332 self.git_source_directories.
333 """ 333 """
334 if not os.path.exists(os.path.join(self.base_directory, '.git')): 334 if not os.path.exists(os.path.join(self.base_directory, '.git')):
335 return 335 return
336 336
337 popen_out = os.popen('cd %s && git ls-files --full-name .' % 337 popen_out = os.popen('cd %s && git ls-files --full-name .' %
338 subprocess.list2cmdline([self.base_directory])) 338 subprocess.list2cmdline([self.base_directory]))
339 for line in popen_out.readlines(): 339 for line in popen_out.readlines():
340 dir_name = os.path.join(self.base_directory, os.path.dirname(line)) 340 dir_name = os.path.join(self.base_directory, os.path.dirname(line))
341 # Add the directory as well as all the parent directories. Use 341 # Add the directory as well as all the parent directories. Use
342 # forward slashes and lower case to normalize paths. 342 # forward slashes and lower case to normalize paths.
343 while dir_name != self.base_directory: 343 while dir_name != self.base_directory:
344 self.git_source_directories.add(NormalizePath(dir_name)) 344 self.git_source_directories.add(NormalizePath(dir_name))
345 dir_name = os.path.dirname(dir_name) 345 dir_name = os.path.dirname(dir_name)
346 self.git_source_directories.add(NormalizePath(self.base_directory)) 346 self.git_source_directories.add(NormalizePath(self.base_directory))
OLDNEW
« no previous file with comments | « no previous file | tools/checkdeps/checkdeps.py » ('j') | tools/checkdeps/checkdeps.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698