gclient flatten: add support for hooks_os
Bug: 570091
Change-Id: Ia7f81a81d7df75004c5f8b7560dfd50a14f4cddd
Reviewed-on: https://chromium-review.googlesource.com/549355
Commit-Queue: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
Reviewed-by: Michael Moss <mmoss@chromium.org>
diff --git a/gclient.py b/gclient.py
index 380a2e7..1a063b2 100755
--- a/gclient.py
+++ b/gclient.py
@@ -373,8 +373,10 @@
self._dependencies = []
# Keep track of original values, before post-processing (e.g. deps_os).
self._orig_dependencies = []
+ self._orig_deps_hooks = []
self._vars = {}
self._os_dependencies = {}
+ self._os_deps_hooks = {}
# A cache of the files affected by the current operation, necessary for
# hooks.
@@ -784,8 +786,15 @@
for hook in local_scope.get('hooks', []):
if hook.get('name', '') not in hook_names_to_suppress:
hooks_to_run.append(hook)
+ orig_hooks = gclient_utils.freeze(hooks_to_run)
if 'hooks_os' in local_scope and target_os_list:
hooks_os = local_scope['hooks_os']
+
+ # Keep original contents of hooks_os for flatten.
+ for hook_os, os_hooks in hooks_os.iteritems():
+ self._os_deps_hooks[hook_os] = [
+ Hook.from_dict(hook, variables=self._vars) for hook in os_hooks]
+
# Specifically append these to ensure that hooks_os run after hooks.
for the_target_os in target_os_list:
the_target_os_hooks = hooks_os.get(the_target_os, [])
@@ -802,7 +811,8 @@
local_scope.get('pre_deps_hooks', [])]
self.add_dependencies_and_close(
- deps_to_add, hooks_to_run, orig_deps_to_add=orig_deps_to_add)
+ deps_to_add, hooks_to_run, orig_deps_to_add=orig_deps_to_add,
+ orig_hooks=orig_hooks)
logging.info('ParseDepsFile(%s) done' % self.name)
def _get_option(self, attr, default):
@@ -812,7 +822,7 @@
return getattr(obj._options, attr, default)
def add_dependencies_and_close(
- self, deps_to_add, hooks, orig_deps_to_add=None):
+ self, deps_to_add, hooks, orig_deps_to_add=None, orig_hooks=None):
"""Adds the dependencies, hooks and mark the parsing as done."""
for dep in deps_to_add:
if dep.verify_validity():
@@ -820,7 +830,9 @@
for dep in (orig_deps_to_add or deps_to_add):
self.add_orig_dependency(dep)
self._mark_as_parsed(
- [Hook.from_dict(h, variables=self._vars) for h in hooks])
+ [Hook.from_dict(h, variables=self._vars) for h in hooks],
+ orig_hooks=[Hook.from_dict(h, variables=self._vars)
+ for h in orig_hooks or hooks])
def findDepsFromNotAllowedHosts(self):
"""Returns a list of depenecies from not allowed hosts.
@@ -1030,8 +1042,9 @@
self._orig_dependencies.append(new_dep)
@gclient_utils.lockedmethod
- def _mark_as_parsed(self, new_hooks):
+ def _mark_as_parsed(self, new_hooks, orig_hooks=None):
self._deps_hooks.extend(new_hooks)
+ self._orig_deps_hooks.extend(orig_hooks or new_hooks)
self._deps_parsed = True
@property
@@ -1056,6 +1069,16 @@
@property
@gclient_utils.lockedmethod
+ def orig_deps_hooks(self):
+ return tuple(self._orig_deps_hooks)
+
+ @property
+ @gclient_utils.lockedmethod
+ def os_deps_hooks(self):
+ return dict(self._os_deps_hooks)
+
+ @property
+ @gclient_utils.lockedmethod
def pre_deps_hooks(self):
return tuple(self._pre_deps_hooks)
@@ -1702,12 +1725,14 @@
deps = {}
deps_os = {}
hooks = []
+ hooks_os = {}
pre_deps_hooks = []
unpinned_deps = {}
for solution in client.dependencies:
_FlattenSolution(
- solution, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps)
+ solution, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps)
if options.require_pinned_revisions and unpinned_deps:
sys.stderr.write('The following dependencies are not pinned:\n')
@@ -1722,6 +1747,7 @@
_DepsOsToLines(deps_os) +
_HooksToLines('hooks', hooks) +
_HooksToLines('pre_deps_hooks', pre_deps_hooks) +
+ _HooksOsToLines(hooks_os) +
[''] # Ensure newline at end of file.
)
@@ -1735,7 +1761,7 @@
def _FlattenSolution(
- solution, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps):
+ solution, deps, deps_os, hooks, hooks_os, pre_deps_hooks, unpinned_deps):
"""Visits a solution in order to flatten it (see CMDflatten).
Arguments:
@@ -1747,6 +1773,8 @@
deps_os (dict of os name -> dep name -> Dependency): same as above,
for OS-specific deps
hooks (list of (Dependency, hook)): will be filled with flattened hooks
+ hooks_os (dict of os name -> list of (Dependency, hook)): same as above,
+ for OS-specific hooks
pre_deps_hooks (list of (Dependency, hook)): will be filled with flattened
pre_deps_hooks
unpinned_deps (dict of name -> Dependency): will be filled with unpinned
@@ -1754,11 +1782,14 @@
"""
logging.debug('_FlattenSolution(%r)', solution)
- _FlattenDep(solution, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps)
- _FlattenRecurse(solution, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps)
+ _FlattenDep(solution, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps)
+ _FlattenRecurse(solution, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps)
-def _FlattenDep(dep, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps):
+def _FlattenDep(dep, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps):
"""Visits a dependency in order to flatten it (see CMDflatten).
Arguments:
@@ -1768,6 +1799,7 @@
deps (dict): will be filled with flattened deps
deps_os (dict): will be filled with flattened deps_os
hooks (list): will be filled with flattened hooks
+ hooks_os (dict): will be filled with flattened hooks_os
pre_deps_hooks (list): will be filled with flattened pre_deps_hooks
unpinned_deps (dict): will be filled with unpinned deps
"""
@@ -1782,15 +1814,19 @@
deps_by_name = dict((d.name, d) for d in dep.dependencies)
for recurse_dep_name in (dep.recursedeps or []):
_FlattenRecurse(
- deps_by_name[recurse_dep_name], deps, deps_os, hooks, pre_deps_hooks,
- unpinned_deps)
+ deps_by_name[recurse_dep_name], deps, deps_os, hooks, hooks_os,
+ pre_deps_hooks, unpinned_deps)
# TODO(phajdan.jr): also handle hooks_os.
- hooks.extend([(dep, hook) for hook in dep.deps_hooks])
+ hooks.extend([(dep, hook) for hook in dep.orig_deps_hooks])
pre_deps_hooks.extend([(dep, hook) for hook in dep.pre_deps_hooks])
+ for hook_os, os_hooks in dep.os_deps_hooks.iteritems():
+ hooks_os.setdefault(hook_os, []).extend([(dep, hook) for hook in os_hooks])
-def _FlattenRecurse(dep, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps):
+
+def _FlattenRecurse(dep, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps):
"""Helper for flatten that recurses into |dep|'s dependencies.
Arguments:
@@ -1800,14 +1836,15 @@
deps (dict): will be filled with flattened deps
deps_os (dict): will be filled with flattened deps_os
hooks (list): will be filled with flattened hooks
+ hooks_os (dict): will be filled with flattened hooks_os
pre_deps_hooks (list): will be filled with flattened pre_deps_hooks
unpinned_deps (dict): will be filled with unpinned deps
"""
logging.debug('_FlattenRecurse(%r)', dep)
- # TODO(phajdan.jr): also handle deps_os.
for sub_dep in dep.orig_dependencies:
- _FlattenDep(sub_dep, deps, deps_os, hooks, pre_deps_hooks, unpinned_deps)
+ _FlattenDep(sub_dep, deps, deps_os, hooks, hooks_os, pre_deps_hooks,
+ unpinned_deps)
def _AddDep(dep, deps, unpinned_deps):
@@ -1903,6 +1940,32 @@
return s
+def _HooksOsToLines(hooks_os):
+ """Converts |hooks| list to list of lines for output."""
+ s = ['hooks_os = {']
+ for hook_os, os_hooks in hooks_os.iteritems():
+ s.append(' "%s": {' % hook_os)
+ for dep, hook in os_hooks:
+ s.extend([
+ ' # %s' % dep.hierarchy(include_url=False),
+ ' {',
+ ])
+ if hook.name is not None:
+ s.append(' "name": "%s",' % hook.name)
+ if hook.pattern is not None:
+ s.append(' "pattern": "%s",' % hook.pattern)
+ s.extend(
+ # Hooks run in the parent directory of their dep.
+ [' "cwd": "%s",' % os.path.normpath(os.path.dirname(dep.name))] +
+ [' "action": ['] +
+ [' "%s",' % arg for arg in hook.action] +
+ [' ]', ' },', '']
+ )
+ s.extend([' },', ''])
+ s.extend(['}', ''])
+ return s
+
+
def CMDgrep(parser, args):
"""Greps through git repos managed by gclient.