Index: gclient.py |
diff --git a/gclient.py b/gclient.py |
index c3e295c42e1dca0fff893a61352cfa7deee4fe36..d1b5a8733859fb76b7cc28e825b941f19ad8ab01 100755 |
--- a/gclient.py |
+++ b/gclient.py |
@@ -466,6 +466,46 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
raise gclient_utils.Error('Unknown url type') |
+ @staticmethod |
+ def MergeWithOsDeps(deps, deps_os, target_os_list): |
+ """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 accidently |
+ # 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: |
+ # It would be possible to abort here but it would be |
+ # unfortunate if we end up preventing any kind of checkout. |
+ logging.error('Conflicting dependencies for %s: %s. (target_os=%s)', |
Ami GONE FROM CHROMIUM
2013/12/16 22:33:47
It's interesting that this is logged even when the
M-A Ruel
2013/12/16 23:20:53
ok so the best would likely be to log only if:
if
Isaac (away)
2013/12/16 23:49:04
possible_values is already a set... I'm not sure w
|
+ 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] |
Isaac (away)
2013/12/16 23:26:50
Also, this sorted call should be sorting by target
|
+ |
+ new_deps = deps.copy() |
+ new_deps.update(target_os_deps) |
+ return new_deps |
+ |
def ParseDepsFile(self): |
"""Parses the DEPS file for this dependency.""" |
assert not self.deps_parsed |
@@ -502,22 +542,9 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): |
self.local_target_os = local_scope['target_os'] |
# load os specific dependencies if defined. these dependencies may |
# override or extend the values defined by the 'deps' member. |
- target_os_deps = {} |
- if 'deps_os' in local_scope: |
- for deps_os_key in self.target_os: |
- os_deps = local_scope['deps_os'].get(deps_os_key, {}) |
- if len(self.target_os) > 1: |
- # Ignore any conflict when including deps for more than one |
- # platform, so we collect the broadest set of dependencies |
- # available. We may end up with the wrong revision of something for |
- # our platform, but this is the best we can do. |
- target_os_deps.update( |
- [x for x in os_deps.items() if not x[0] in target_os_deps]) |
- else: |
- target_os_deps.update(os_deps) |
- |
- # deps_os overrides paths from deps |
- deps.update(target_os_deps) |
+ target_os_list = self.target_os |
+ if 'deps_os' in local_scope and target_os_list: |
+ deps = self.MergeWithOsDeps(deps, local_scope['deps_os'], target_os_list) |
# If a line is in custom_deps, but not in the solution, we want to append |
# this line to the solution. |