gclient: include deps_os entries in dependencies
Keep deps_os entries in dependencies, just with should_process set to False
for entries not applicable to target OS list.
This way gclient flatten has proper access to dependencies e.g. to evaluate
recursedeps referring to deps_os entries other than active OS.
Allow but ignore deps_os overriding a value with None, since that does not
fit the new model. There's no correctness harm in not checking out a repo.
Allow "overrides" setting given dependency to the same value. This seems
fairly common, especially for mac/ios and unix/android, even in chromium/src.
Bug: 570091
Change-Id: I2037a1ecc5fd2da6b5f73061548b81fc79ba2e72
Reviewed-on: https://chromium-review.googlesource.com/541280
Reviewed-by: Dirk Pranke <dpranke@chromium.org>
Commit-Queue: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
diff --git a/gclient.py b/gclient.py
index f78b62a..a1aef8c 100755
--- a/gclient.py
+++ b/gclient.py
@@ -543,43 +543,30 @@
"""Returns a new "deps" structure that is the deps sent in updated
with information from deps_os (the deps_os section of the DEPS
file) that matches the list of target os."""
- os_overrides = {}
- for the_target_os in target_os_list:
- the_target_os_deps = deps_os.get(the_target_os, {})
- for os_dep_key, os_dep_value in the_target_os_deps.iteritems():
- overrides = os_overrides.setdefault(os_dep_key, [])
- overrides.append((the_target_os, os_dep_value))
-
- # If any os didn't specify a value (we have fewer value entries
- # than in the os list), then it wants to use the default value.
- for os_dep_key, os_dep_value in os_overrides.iteritems():
- if len(os_dep_value) != len(target_os_list):
- # Record the default value too so that we don't accidentally
- # set it to None or miss a conflicting DEPS.
- if os_dep_key in deps:
- os_dep_value.append(('default', deps[os_dep_key]))
-
- target_os_deps = {}
- for os_dep_key, os_dep_value in os_overrides.iteritems():
- # os_dep_value is a list of (os, value) pairs.
- possible_values = set(x[1] for x in os_dep_value if x[1] is not None)
- if not possible_values:
- target_os_deps[os_dep_key] = None
- else:
- if len(possible_values) > 1:
- raise gclient_utils.Error(
- 'Conflicting dependencies for %s: %s. (target_os=%s)' % (
- os_dep_key, os_dep_value, target_os_list))
- # Sorting to get the same result every time in case of conflicts.
- target_os_deps[os_dep_key] = sorted(possible_values)[0]
-
new_deps = deps.copy()
- for key, value in target_os_deps.iteritems():
- if key in new_deps:
- raise gclient_utils.Error(
- ('Value from deps_os (%r: %r) conflicts with existing deps '
- 'entry (%r).') % (key, value, new_deps[key]))
- new_deps[key] = value
+ for dep_os, os_deps in deps_os.iteritems():
+ for key, value in os_deps.iteritems():
+ if value is None:
+ # Make this condition very visible, so it's not a silent failure.
+ # It's unclear how to support None override in deps_os.
+ logging.error('Ignoring %r:%r in %r deps_os', key, value, dep_os)
+ continue
+ if isinstance(value, basestring):
+ value = {'url': value}
+ if key in new_deps and new_deps[key] != value:
+ if isinstance(new_deps[key], basestring):
+ existing_url = new_deps[key]
+ else:
+ assert isinstance(new_deps[key],
+ collections.Mapping), (key, new_deps[key])
+ existing_url = new_deps[key]['url']
+ if value['url'] != existing_url:
+ raise gclient_utils.Error(
+ ('Value from deps_os (%r; %r: %r) conflicts with existing deps '
+ 'entry (%r).') % (dep_os, key, value, new_deps[key]))
+ assert isinstance(value, collections.Mapping), (key, value)
+ new_deps[key] = value
+ new_deps[key]['should_process'] = dep_os in target_os_list
return new_deps
def _postprocess_deps(self, deps, rel_prefix):
@@ -625,6 +612,9 @@
# This should be guaranteed by schema checking in gclient_eval.
assert isinstance(dep_value, collections.Mapping)
url = dep_value['url']
+ # Take into account should_process metadata set by MergeWithOsDeps.
+ should_process = (should_process and
+ dep_value.get('should_process', True))
condition = dep_value.get('condition')
if condition:
# TODO(phajdan.jr): should we also take custom vars into account?