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

Side by Side Diff: gclient.py

Issue 2819062: Make file_list recursive so that pattern in hooks will trigger on dependencies too. (Closed)
Patch Set: git diff trunk Created 10 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 """Meta checkout manager supporting both Subversion and GIT. 6 """Meta checkout manager supporting both Subversion and GIT.
7 7
8 Files 8 Files
9 .gclient : Current client configuration, written by 'config' command. 9 .gclient : Current client configuration, written by 'config' command.
10 Format is a Python script defining 'solutions', a list whose 10 Format is a Python script defining 'solutions', a list whose
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 self.parsed_url = None 146 self.parsed_url = None
147 # These 2 are only set in .gclient and not in DEPS files. 147 # These 2 are only set in .gclient and not in DEPS files.
148 self.safesync_url = safesync_url 148 self.safesync_url = safesync_url
149 self.custom_vars = custom_vars or {} 149 self.custom_vars = custom_vars or {}
150 self.custom_deps = custom_deps or {} 150 self.custom_deps = custom_deps or {}
151 self.deps_hooks = [] 151 self.deps_hooks = []
152 self.dependencies = [] 152 self.dependencies = []
153 self.deps_file = deps_file or self.DEPS_FILE 153 self.deps_file = deps_file or self.DEPS_FILE
154 # A cache of the files affected by the current operation, necessary for 154 # A cache of the files affected by the current operation, necessary for
155 # hooks. 155 # hooks.
156 self.file_list = [] 156 self._file_list = []
157 # If it is not set to True, the dependency wasn't processed for its child 157 # If it is not set to True, the dependency wasn't processed for its child
158 # dependency, i.e. its DEPS wasn't read. 158 # dependency, i.e. its DEPS wasn't read.
159 self.deps_parsed = False 159 self.deps_parsed = False
160 # A direct reference is dependency that is referenced by a deps, deps_os or 160 # A direct reference is dependency that is referenced by a deps, deps_os or
161 # solution. A indirect one is one that was loaded with From() or that 161 # solution. A indirect one is one that was loaded with From() or that
162 # exceeded recursion limit. 162 # exceeded recursion limit.
163 self.direct_reference = False 163 self.direct_reference = False
164 164
165 # Sanity checks 165 # Sanity checks
166 if not self.name and self.parent: 166 if not self.name and self.parent:
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 raise 297 raise
298 self.dependencies.append(Dependency(self, name, url)) 298 self.dependencies.append(Dependency(self, name, url))
299 # Sort by name. 299 # Sort by name.
300 self.dependencies.sort(key=lambda x: x.name) 300 self.dependencies.sort(key=lambda x: x.name)
301 logging.info('Loaded: %s' % str(self)) 301 logging.info('Loaded: %s' % str(self))
302 302
303 def RunCommandRecursively(self, options, revision_overrides, 303 def RunCommandRecursively(self, options, revision_overrides,
304 command, args, pm): 304 command, args, pm):
305 """Runs 'command' before parsing the DEPS in case it's a initial checkout 305 """Runs 'command' before parsing the DEPS in case it's a initial checkout
306 or a revert.""" 306 or a revert."""
307 assert self.file_list == [] 307 assert self._file_list == []
308 # When running runhooks, there's no need to consult the SCM. 308 # When running runhooks, there's no need to consult the SCM.
309 # All known hooks are expected to run unconditionally regardless of working 309 # All known hooks are expected to run unconditionally regardless of working
310 # copy state, so skip the SCM status check. 310 # copy state, so skip the SCM status check.
311 run_scm = command not in ('runhooks', None) 311 run_scm = command not in ('runhooks', None)
312 self.LateOverride(self.url) 312 self.LateOverride(self.url)
313 if run_scm and self.parsed_url: 313 if run_scm and self.parsed_url:
314 if isinstance(self.parsed_url, self.FileImpl): 314 if isinstance(self.parsed_url, self.FileImpl):
315 # Special support for single-file checkout. 315 # Special support for single-file checkout.
316 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): 316 if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
317 options.revision = self.parsed_url.GetRevision() 317 options.revision = self.parsed_url.GetRevision()
318 scm = gclient_scm.SVNWrapper(self.parsed_url.GetPath(), 318 scm = gclient_scm.SVNWrapper(self.parsed_url.GetPath(),
319 self.root_dir(), 319 self.root_dir(),
320 self.name) 320 self.name)
321 scm.RunCommand('updatesingle', options, 321 scm.RunCommand('updatesingle', options,
322 args + [self.parsed_url.GetFilename()], 322 args + [self.parsed_url.GetFilename()],
323 self.file_list) 323 self._file_list)
324 else: 324 else:
325 options.revision = revision_overrides.get(self.name) 325 options.revision = revision_overrides.get(self.name)
326 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name) 326 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name)
327 scm.RunCommand(command, options, args, self.file_list) 327 scm.RunCommand(command, options, args, self._file_list)
328 self.file_list = [os.path.join(self.name, f.strip()) 328 self._file_list = [os.path.join(self.name, f.strip())
329 for f in self.file_list] 329 for f in self._file_list]
330 options.revision = None 330 options.revision = None
331 if pm: 331 if pm:
332 # The + 1 comes from the fact that .gclient is considered a step in 332 # The + 1 comes from the fact that .gclient is considered a step in
333 # itself, .i.e. this code is called one time for the .gclient. This is not 333 # itself, .i.e. this code is called one time for the .gclient. This is not
334 # conceptually correct but it simplifies code. 334 # conceptually correct but it simplifies code.
335 pm._total = len(self.tree(False)) + 1 335 pm._total = len(self.tree(False)) + 1
336 pm.update() 336 pm.update()
337 if self.recursion_limit(): 337 if self.recursion_limit():
338 # Then we can parse the DEPS file. 338 # Then we can parse the DEPS file.
339 self.ParseDepsFile(True) 339 self.ParseDepsFile(True)
(...skipping 18 matching lines...) Expand all
358 # that. 358 # that.
359 if (options.force or 359 if (options.force or
360 isinstance(self.parsed_url, self.FileImpl) or 360 isinstance(self.parsed_url, self.FileImpl) or
361 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or 361 gclient_scm.GetScmName(self.parsed_url) in ('git', None) or
362 os.path.isdir(os.path.join(self.root_dir(), self.name, '.git'))): 362 os.path.isdir(os.path.join(self.root_dir(), self.name, '.git'))):
363 for hook_dict in self.deps_hooks: 363 for hook_dict in self.deps_hooks:
364 self._RunHookAction(hook_dict, []) 364 self._RunHookAction(hook_dict, [])
365 else: 365 else:
366 # TODO(phajdan.jr): We should know exactly when the paths are absolute. 366 # TODO(phajdan.jr): We should know exactly when the paths are absolute.
367 # Convert all absolute paths to relative. 367 # Convert all absolute paths to relative.
368 for i in range(len(self.file_list)): 368 file_list = self.file_list()
369 for i in range(len(file_list)):
369 # It depends on the command being executed (like runhooks vs sync). 370 # It depends on the command being executed (like runhooks vs sync).
370 if not os.path.isabs(self.file_list[i]): 371 if not os.path.isabs(file_list[i]):
371 continue 372 continue
372 373
373 prefix = os.path.commonprefix([self.root_dir().lower(), 374 prefix = os.path.commonprefix([self.root_dir().lower(),
374 self.file_list[i].lower()]) 375 file_list[i].lower()])
375 self.file_list[i] = self.file_list[i][len(prefix):] 376 file_list[i] = file_list[i][len(prefix):]
376 377
377 # Strip any leading path separators. 378 # Strip any leading path separators.
378 while (self.file_list[i].startswith('\\') or 379 while (file_list[i].startswith('\\') or
379 self.file_list[i].startswith('/')): 380 file_list[i].startswith('/')):
380 self.file_list[i] = self.file_list[i][1:] 381 file_list[i] = file_list[i][1:]
381 382
382 # Run hooks on the basis of whether the files from the gclient operation 383 # Run hooks on the basis of whether the files from the gclient operation
383 # match each hook's pattern. 384 # match each hook's pattern.
384 for hook_dict in self.deps_hooks: 385 for hook_dict in self.deps_hooks:
385 pattern = re.compile(hook_dict['pattern']) 386 pattern = re.compile(hook_dict['pattern'])
386 matching_file_list = [f for f in self.file_list if pattern.search(f)] 387 matching_file_list = [f for f in file_list if pattern.search(f)]
387 if matching_file_list: 388 if matching_file_list:
388 self._RunHookAction(hook_dict, matching_file_list) 389 self._RunHookAction(hook_dict, matching_file_list)
389 if self.recursion_limit(): 390 if self.recursion_limit():
390 for s in self.dependencies: 391 for s in self.dependencies:
391 s.RunHooksRecursively(options) 392 s.RunHooksRecursively(options)
392 393
393 def _RunHookAction(self, hook_dict, matching_file_list): 394 def _RunHookAction(self, hook_dict, matching_file_list):
394 """Runs the action from a single hook.""" 395 """Runs the action from a single hook."""
395 logging.info(hook_dict) 396 logging.info(hook_dict)
396 logging.info(matching_file_list) 397 logging.info(matching_file_list)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 result.extend(d.subtree(force_all)) 433 result.extend(d.subtree(force_all))
433 return result 434 return result
434 435
435 def get_custom_deps(self, name, url): 436 def get_custom_deps(self, name, url):
436 """Returns a custom deps if applicable.""" 437 """Returns a custom deps if applicable."""
437 if self.parent: 438 if self.parent:
438 url = self.parent.get_custom_deps(name, url) 439 url = self.parent.get_custom_deps(name, url)
439 # None is a valid return value to disable a dependency. 440 # None is a valid return value to disable a dependency.
440 return self.custom_deps.get(name, url) 441 return self.custom_deps.get(name, url)
441 442
443 def file_list(self):
444 result = self._file_list[:]
445 for d in self.dependencies:
446 result.extend(d.file_list())
447 return result
448
442 def __str__(self): 449 def __str__(self):
443 out = [] 450 out = []
444 for i in ('name', 'url', 'safesync_url', 'custom_deps', 'custom_vars', 451 for i in ('name', 'url', 'safesync_url', 'custom_deps', 'custom_vars',
445 'deps_hooks', 'file_list'): 452 'deps_hooks', '_file_list'):
446 # 'deps_file' 453 # 'deps_file'
447 if self.__dict__[i]: 454 if self.__dict__[i]:
448 out.append('%s: %s' % (i, self.__dict__[i])) 455 out.append('%s: %s' % (i, self.__dict__[i]))
449 456
450 for d in self.dependencies: 457 for d in self.dependencies:
451 out.extend([' ' + x for x in str(d).splitlines()]) 458 out.extend([' ' + x for x in str(d).splitlines()])
452 out.append('') 459 out.append('')
453 return '\n'.join(out) 460 return '\n'.join(out)
454 461
455 def __repr__(self): 462 def __repr__(self):
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 return CMDhelp(parser, argv) 1158 return CMDhelp(parser, argv)
1152 except gclient_utils.Error, e: 1159 except gclient_utils.Error, e:
1153 print >> sys.stderr, 'Error: %s' % str(e) 1160 print >> sys.stderr, 'Error: %s' % str(e)
1154 return 1 1161 return 1
1155 1162
1156 1163
1157 if '__main__' == __name__: 1164 if '__main__' == __name__:
1158 sys.exit(Main(sys.argv[1:])) 1165 sys.exit(Main(sys.argv[1:]))
1159 1166
1160 # vim: ts=2:sw=2:tw=80:et: 1167 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698