Index: gclient.py |
diff --git a/gclient.py b/gclient.py |
index 5f40f4ed997e851c1fd9bb85fb85a23082db6852..6ecb941887330266baf2f15804d9b08b9d7ee484 100644 |
--- a/gclient.py |
+++ b/gclient.py |
@@ -346,6 +346,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
sub_target = url.sub_target_name or self.name |
# Make sure the referenced dependency DEPS file is loaded and file the |
# inner referenced dependency. |
+ # TODO(maruel): Shouldn't do that. |
ref.ParseDepsFile() |
found_dep = None |
for d in ref.dependencies: |
@@ -390,16 +391,16 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
if url is None: |
logging.info('LateOverride(%s, %s) -> %s' % (self.name, url, url)) |
return url |
- else: |
- raise gclient_utils.Error('Unknown url type') |
+ |
+ raise gclient_utils.Error('Unknown url type') |
def ParseDepsFile(self): |
"""Parses the DEPS file for this dependency.""" |
- assert self.processed == True |
if self.deps_parsed: |
logging.debug('%s was already parsed' % self.name) |
return |
- # One thing is unintuitive, vars= {} must happen before Var() use. |
+ assert not self.dependencies |
+ # One thing is unintuitive, vars = {} must happen before Var() use. |
local_scope = {} |
var = self.VarImpl(self.custom_vars, local_scope) |
global_scope = { |
@@ -472,45 +473,47 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
self.add_dependency(dep) |
self._mark_as_parsed(hooks) |
+ @staticmethod |
+ def maybeGetParentRevision( |
+ command, options, parsed_url, parent_name, revision_overrides): |
+ """If we are performing an update and --transitive is set, set the |
+ revision to the parent's revision. If we have an explicit revision |
+ do nothing.""" |
+ if command == 'update' and options.transitive and not options.revision: |
+ _, revision = gclient_utils.SplitUrlRevision(parsed_url) |
+ if not revision: |
+ options.revision = revision_overrides.get(parent_name) |
+ if options.verbose and options.revision: |
+ print("Using parent's revision date: %s" % options.revision) |
+ # If the parent has a revision override, then it must have been |
+ # converted to date format. |
+ assert (not options.revision or |
+ gclient_utils.IsDateRevision(options.revision)) |
+ |
+ @staticmethod |
+ def maybeConvertToDateRevision( |
+ command, options, name, scm, revision_overrides): |
+ """If we are performing an update and --transitive is set, convert the |
+ revision to a date-revision (if necessary). Instead of having |
+ -r 101 replace the revision with the time stamp of 101 (e.g. |
+ "{2011-18-04}"). |
+ This way dependencies are upgraded to the revision they had at the |
+ check-in of revision 101.""" |
+ if (command == 'update' and |
+ options.transitive and |
+ options.revision and |
+ not gclient_utils.IsDateRevision(options.revision)): |
+ revision_date = scm.GetRevisionDate(options.revision) |
+ revision = gclient_utils.MakeDateRevision(revision_date) |
+ if options.verbose: |
+ print("Updating revision override from %s to %s." % |
+ (options.revision, revision)) |
+ revision_overrides[name] = revision |
+ |
# Arguments number differs from overridden method |
# pylint: disable=W0221 |
def run(self, revision_overrides, command, args, work_queue, options): |
- """Runs 'command' before parsing the DEPS in case it's a initial checkout |
- or a revert.""" |
- |
- def maybeGetParentRevision(options): |
- """If we are performing an update and --transitive is set, set the |
- revision to the parent's revision. If we have an explicit revision |
- do nothing.""" |
- if command == 'update' and options.transitive and not options.revision: |
- _, revision = gclient_utils.SplitUrlRevision(self.parsed_url) |
- if not revision: |
- options.revision = revision_overrides.get(self.parent.name) |
- if options.verbose and options.revision: |
- print("Using parent's revision date: %s" % options.revision) |
- # If the parent has a revision override, then it must have been |
- # converted to date format. |
- assert (not options.revision or |
- gclient_utils.IsDateRevision(options.revision)) |
- |
- def maybeConvertToDateRevision(options): |
- """If we are performing an update and --transitive is set, convert the |
- revision to a date-revision (if necessary). Instead of having |
- -r 101 replace the revision with the time stamp of 101 (e.g. |
- "{2011-18-04}"). |
- This way dependencies are upgraded to the revision they had at the |
- check-in of revision 101.""" |
- if (command == 'update' and |
- options.transitive and |
- options.revision and |
- not gclient_utils.IsDateRevision(options.revision)): |
- revision_date = scm.GetRevisionDate(options.revision) |
- revision = gclient_utils.MakeDateRevision(revision_date) |
- if options.verbose: |
- print("Updating revision override from %s to %s." % |
- (options.revision, revision)) |
- revision_overrides[self.name] = revision |
- |
+ """Runs |command| then parse the DEPS file.""" |
assert self._file_list == [] |
if not self.should_process: |
return |
@@ -518,52 +521,64 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
# All known hooks are expected to run unconditionally regardless of working |
# copy state, so skip the SCM status check. |
run_scm = command not in ('runhooks', None) |
- self._parsed_url = self.LateOverride(self.url) |
- if run_scm and self.parsed_url: |
- if isinstance(self.parsed_url, self.FileImpl): |
+ parsed_url = self.LateOverride(self.url) |
+ file_list = [] |
+ if run_scm and parsed_url: |
+ if isinstance(parsed_url, self.FileImpl): |
# Special support for single-file checkout. |
if not command in (None, 'cleanup', 'diff', 'pack', 'status'): |
- options.revision = self.parsed_url.GetRevision() |
- scm = gclient_scm.SVNWrapper(self.parsed_url.GetPath(), |
+ # Sadly, pylint doesn't realize that parsed_url is of FileImpl. |
+ # pylint: disable=E1103 |
+ options.revision = parsed_url.GetRevision() |
+ scm = gclient_scm.SVNWrapper(parsed_url.GetPath(), |
self.root.root_dir, |
self.name) |
scm.RunCommand('updatesingle', options, |
- args + [self.parsed_url.GetFilename()], |
- self._file_list) |
+ args + [parsed_url.GetFilename()], |
+ file_list) |
else: |
# Create a shallow copy to mutate revision. |
options = copy.copy(options) |
options.revision = revision_overrides.get(self.name) |
- maybeGetParentRevision(options) |
- scm = gclient_scm.CreateSCM( |
- self.parsed_url, self.root.root_dir, self.name) |
- scm.RunCommand(command, options, args, self._file_list) |
- maybeConvertToDateRevision(options) |
- self._file_list = [os.path.join(self.name, f.strip()) |
- for f in self._file_list] |
+ self.maybeGetParentRevision( |
+ command, options, parsed_url, self.parent.name, revision_overrides) |
+ scm = gclient_scm.CreateSCM(parsed_url, self.root.root_dir, self.name) |
+ scm.RunCommand(command, options, args, file_list) |
+ self.maybeConvertToDateRevision( |
+ command, options, self.name, scm, revision_overrides) |
+ file_list = [os.path.join(self.name, f.strip()) for f in file_list] |
# TODO(phajdan.jr): We should know exactly when the paths are absolute. |
# Convert all absolute paths to relative. |
- for i in range(len(self._file_list)): |
+ for i in range(len(file_list)): |
# It depends on the command being executed (like runhooks vs sync). |
- if not os.path.isabs(self._file_list[i]): |
+ if not os.path.isabs(file_list[i]): |
continue |
prefix = os.path.commonprefix( |
- [self.root.root_dir.lower(), self._file_list[i].lower()]) |
- self._file_list[i] = self._file_list[i][len(prefix):] |
+ [self.root.root_dir.lower(), file_list[i].lower()]) |
+ file_list[i] = file_list[i][len(prefix):] |
# Strip any leading path separators. |
- while (self._file_list[i].startswith('\\') or |
- self._file_list[i].startswith('/')): |
- self._file_list[i] = self._file_list[i][1:] |
- self._processed = True |
+ while file_list[i].startswith(('\\', '/')): |
+ file_list[i] = file_list[i][1:] |
+ |
if self.recursion_limit: |
# Then we can parse the DEPS file. |
self.ParseDepsFile() |
+ self._run_is_done(file_list, parsed_url) |
+ |
+ if self.recursion_limit: |
# Parse the dependencies of this dependency. |
for s in self.dependencies: |
work_queue.enqueue(s) |
+ @gclient_utils.lockedmethod |
+ def _run_is_done(self, file_list, parsed_url): |
+ # Both these are kept for hooks that are run as a separate tree traversal. |
+ self._file_list = file_list |
+ self._parsed_url = parsed_url |
+ self._processed = True |
+ |
def RunHooksRecursively(self, options): |
"""Evaluates all hooks, running actions as needed. run() |
must have been called before to load the DEPS.""" |
@@ -588,7 +603,9 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
# match each hook's pattern. |
for hook_dict in self.deps_hooks: |
pattern = re.compile(hook_dict['pattern']) |
- matching_file_list = [f for f in self.file_list if pattern.search(f)] |
+ matching_file_list = [ |
+ f for f in self.file_list_and_children if pattern.search(f) |
+ ] |
if matching_file_list: |
self._RunHookAction(hook_dict, matching_file_list) |
for s in self.dependencies: |
@@ -656,30 +673,40 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
return tuple(self._dependencies) |
@property |
+ @gclient_utils.lockedmethod |
def deps_hooks(self): |
return tuple(self._deps_hooks) |
@property |
+ @gclient_utils.lockedmethod |
def parsed_url(self): |
return self._parsed_url |
@property |
+ @gclient_utils.lockedmethod |
def deps_parsed(self): |
return self._deps_parsed |
@property |
+ @gclient_utils.lockedmethod |
def processed(self): |
return self._processed |
@property |
+ @gclient_utils.lockedmethod |
def hooks_ran(self): |
return self._hooks_ran |
@property |
+ @gclient_utils.lockedmethod |
def file_list(self): |
- result = self._file_list[:] |
+ return tuple(self._file_list) |
+ |
+ @property |
+ def file_list_and_children(self): |
+ result = list(self.file_list) |
for d in self.dependencies: |
- result.extend(d.file_list) |
+ result.extend(d.file_list_and_children) |
return tuple(result) |
def __str__(self): |