Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: gclient.py

Issue 23875029: Handle conflicting os deps better in gclient. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Changed how the helper method returns the result. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Meta checkout manager supporting both Subversion and GIT.""" 6 """Meta checkout manager supporting both Subversion and GIT."""
7 # Files 7 # Files
8 # .gclient : Current client configuration, written by 'config' command. 8 # .gclient : Current client configuration, written by 'config' command.
9 # Format is a Python script defining 'solutions', a list whose 9 # Format is a Python script defining 'solutions', a list whose
10 # entries each are maps binding the strings "name" and "url" 10 # entries each are maps binding the strings "name" and "url"
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 (self.name, url, url)) 459 (self.name, url, url))
460 return url 460 return url
461 461
462 if url is None: 462 if url is None:
463 logging.info( 463 logging.info(
464 'Dependency(%s).LateOverride(%s) -> %s' % (self.name, url, url)) 464 'Dependency(%s).LateOverride(%s) -> %s' % (self.name, url, url))
465 return url 465 return url
466 466
467 raise gclient_utils.Error('Unknown url type') 467 raise gclient_utils.Error('Unknown url type')
468 468
469 @staticmethod
470 def MergeWithOsDeps(deps, deps_os, target_os_list):
471 """Returns a new "deps" structure that is the deps sent in updated
472 with information from deps_os (the deps_os section of the DEPS
473 file) that matches the list of target os."""
474 os_overrides = {}
475 for the_target_os in target_os_list:
476 the_target_os_deps = deps_os.get(the_target_os, {})
477 for os_dep_key, os_dep_value in the_target_os_deps.iteritems():
478 overrides = os_overrides.setdefault(os_dep_key, [])
479 overrides.append((the_target_os, os_dep_value))
480
481 # If any os didn't specify a value (we have fewer value entries
482 # than in the os list), then it wants to use the default value.
483 for os_dep_key, os_dep_value in os_overrides.iteritems():
484 if len(os_dep_value) != len(target_os_list):
485 # Record the default value too so that we don't accidently
486 # set it to None or miss a conflicting DEPS.
487 if os_dep_key in deps:
488 os_dep_value.append(('default', deps[os_dep_key]))
489
490 target_os_deps = {}
491 for os_dep_key, os_dep_value in os_overrides.iteritems():
492 # os_dep_value is a list of (os, value) pairs.
493 possible_values = set(x[1] for x in os_dep_value if x[1] is not None)
494 if not possible_values:
495 target_os_deps[os_dep_key] = None
496 else:
497 if len(possible_values) > 1:
498 # It would be possible to abort here but it would be
499 # unfortunate if we end up preventing any kind of checkout.
500 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
501 os_dep_key, os_dep_value, target_os_list)
502 # Sorting to get the same result every time in case of conflicts.
503 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
504
505 new_deps = deps.copy()
506 new_deps.update(target_os_deps)
507 return new_deps
508
469 def ParseDepsFile(self): 509 def ParseDepsFile(self):
470 """Parses the DEPS file for this dependency.""" 510 """Parses the DEPS file for this dependency."""
471 assert not self.deps_parsed 511 assert not self.deps_parsed
472 assert not self.dependencies 512 assert not self.dependencies
473 # One thing is unintuitive, vars = {} must happen before Var() use. 513 # One thing is unintuitive, vars = {} must happen before Var() use.
474 local_scope = {} 514 local_scope = {}
475 var = self.VarImpl(self.custom_vars, local_scope) 515 var = self.VarImpl(self.custom_vars, local_scope)
476 global_scope = { 516 global_scope = {
477 'File': self.FileImpl, 517 'File': self.FileImpl,
478 'From': self.FromImpl, 518 'From': self.FromImpl,
(...skipping 16 matching lines...) Expand all
495 deps = local_scope.get('deps', {}) 535 deps = local_scope.get('deps', {})
496 if 'recursion' in local_scope: 536 if 'recursion' in local_scope:
497 self.recursion_override = local_scope.get('recursion') 537 self.recursion_override = local_scope.get('recursion')
498 logging.warning( 538 logging.warning(
499 'Setting %s recursion to %d.', self.name, self.recursion_limit) 539 'Setting %s recursion to %d.', self.name, self.recursion_limit)
500 # If present, save 'target_os' in the local_target_os property. 540 # If present, save 'target_os' in the local_target_os property.
501 if 'target_os' in local_scope: 541 if 'target_os' in local_scope:
502 self.local_target_os = local_scope['target_os'] 542 self.local_target_os = local_scope['target_os']
503 # load os specific dependencies if defined. these dependencies may 543 # load os specific dependencies if defined. these dependencies may
504 # override or extend the values defined by the 'deps' member. 544 # override or extend the values defined by the 'deps' member.
505 target_os_deps = {} 545 target_os_list = self.target_os
506 if 'deps_os' in local_scope: 546 if 'deps_os' in local_scope and target_os_list:
507 for deps_os_key in self.target_os: 547 deps = self.MergeWithOsDeps(deps, local_scope['deps_os'], target_os_list)
508 os_deps = local_scope['deps_os'].get(deps_os_key, {})
509 if len(self.target_os) > 1:
510 # Ignore any conflict when including deps for more than one
511 # platform, so we collect the broadest set of dependencies
512 # available. We may end up with the wrong revision of something for
513 # our platform, but this is the best we can do.
514 target_os_deps.update(
515 [x for x in os_deps.items() if not x[0] in target_os_deps])
516 else:
517 target_os_deps.update(os_deps)
518
519 # deps_os overrides paths from deps
520 deps.update(target_os_deps)
521 548
522 # If a line is in custom_deps, but not in the solution, we want to append 549 # If a line is in custom_deps, but not in the solution, we want to append
523 # this line to the solution. 550 # this line to the solution.
524 for d in self.custom_deps: 551 for d in self.custom_deps:
525 if d not in deps: 552 if d not in deps:
526 deps[d] = self.custom_deps[d] 553 deps[d] = self.custom_deps[d]
527 554
528 # If use_relative_paths is set in the DEPS file, regenerate 555 # If use_relative_paths is set in the DEPS file, regenerate
529 # the dictionary using paths relative to the directory containing 556 # the dictionary using paths relative to the directory containing
530 # the DEPS file. 557 # the DEPS file.
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 raise 1916 raise
1890 except (gclient_utils.Error, subprocess2.CalledProcessError), e: 1917 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
1891 print >> sys.stderr, 'Error: %s' % str(e) 1918 print >> sys.stderr, 'Error: %s' % str(e)
1892 return 1 1919 return 1
1893 1920
1894 1921
1895 if '__main__' == __name__: 1922 if '__main__' == __name__:
1896 sys.exit(Main(sys.argv[1:])) 1923 sys.exit(Main(sys.argv[1:]))
1897 1924
1898 # vim: ts=2:sw=2:tw=80:et: 1925 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698