gclient flatten: correctness fixes for OS-specific recursedeps
We need to pass OS info to recursively called _flatten_dep.
Regular deps entries in OS-specific DEPS file recursed into
need to be marked as OS-specific in the flattened file.
Bug: 570091
Change-Id: If3055b84143d8a52d10d8753113893b5054b4d07
Reviewed-on: https://chromium-review.googlesource.com/621046
Reviewed-by: Michael Moss <mmoss@chromium.org>
Commit-Queue: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
diff --git a/gclient.py b/gclient.py
index bc1df6e..84010b3 100755
--- a/gclient.py
+++ b/gclient.py
@@ -1794,12 +1794,29 @@
if dep.url:
self._deps[dep.name] = dep
- def _flatten_dep(self, dep):
+ def _add_os_dep(self, os_dep, dep_os):
+ """Helper to add an OS-specific dependency to flattened DEPS.
+
+ Arguments:
+ os_dep (Dependency): dependency to add
+ dep_os (str): name of the OS
+ """
+ assert (
+ os_dep.name not in self._deps_os.get(dep_os, {}) or
+ self._deps_os.get(dep_os, {}).get(os_dep.name) == os_dep), (
+ os_dep.name, self._deps_os.get(dep_os, {}).get(os_dep.name))
+ if os_dep.url:
+ self._deps_os.setdefault(dep_os, {})[os_dep.name] = os_dep
+
+ def _flatten_dep(self, dep, dep_os=None):
"""Visits a dependency in order to flatten it (see CMDflatten).
Arguments:
dep (Dependency): dependency to process
+ dep_os (str or None): name of the OS |dep| is specific to
"""
+ logging.debug('_flatten_dep(%s, %s)', dep.name, dep_os)
+
if not dep.deps_parsed:
dep.ParseDepsFile()
@@ -1811,31 +1828,42 @@
assert key not in self._vars or self._vars[key][1] == value
self._vars[key] = (dep, value)
- self._hooks.extend([(dep, hook) for hook in dep.deps_hooks])
self._pre_deps_hooks.extend([(dep, hook) for hook in dep.pre_deps_hooks])
+ if dep_os:
+ if dep.deps_hooks:
+ self._hooks_os.setdefault(dep_os, []).extend(
+ [(dep, hook) for hook in dep.deps_hooks])
+ else:
+ self._hooks.extend([(dep, hook) for hook in dep.deps_hooks])
+
for sub_dep in dep.dependencies:
- self._add_dep(sub_dep)
+ if dep_os:
+ self._add_os_dep(sub_dep, dep_os)
+ else:
+ self._add_dep(sub_dep)
for hook_os, os_hooks in dep.os_deps_hooks.iteritems():
self._hooks_os.setdefault(hook_os, []).extend(
[(dep, hook) for hook in os_hooks])
- for dep_os, os_deps in dep.os_dependencies.iteritems():
+ for sub_dep_os, os_deps in dep.os_dependencies.iteritems():
for os_dep in os_deps:
- self._deps_os.setdefault(dep_os, {})[os_dep.name] = os_dep
+ self._add_os_dep(os_dep, sub_dep_os)
- # Process recursedeps.
- deps_by_name = dict((d.name, d) for d in dep.dependencies)
- # Allow recursedeps entries that refer to deps_os entries.
- # In case there are multiple entries with the same name,
- # we have to pick something - e.g. the first one.
- for os_deps in dep.os_dependencies.itervalues():
+ # Process recursedeps. |deps_by_name| is a map where keys are dependency
+ # names, and values are maps of OS names to |Dependency| instances.
+ # |None| in place of OS name means the dependency is not OS-specific.
+ deps_by_name = dict((d.name, {None: d}) for d in dep.dependencies)
+ for sub_dep_os, os_deps in dep.os_dependencies.iteritems():
for os_dep in os_deps:
- if os_dep.name not in deps_by_name:
- deps_by_name[os_dep.name] = os_dep
+ assert sub_dep_os not in deps_by_name.get(os_dep.name, {}), (
+ os_dep.name, sub_dep_os)
+ deps_by_name.setdefault(os_dep.name, {})[sub_dep_os] = os_dep
for recurse_dep_name in (dep.recursedeps or []):
- self._flatten_dep(deps_by_name[recurse_dep_name])
+ dep_info = deps_by_name[recurse_dep_name]
+ for sub_dep_os, os_dep in dep_info.iteritems():
+ self._flatten_dep(os_dep, dep_os=(sub_dep_os or dep_os))
def CMDflatten(parser, args):