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

Side by Side Diff: gclient.py

Issue 2304002: Add workaround to ignore the first solution specified with --revision solution@rev (Closed)
Patch Set: . Created 10 years, 7 months 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/fake_repos.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/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 """A wrapper script to manage a set of client modules in different SCM. 6 """A wrapper script to manage a set of client modules in different SCM.
7 7
8 This script is intended to be used to help basic management of client 8 This script is intended to be used to help basic management of client
9 program sources residing in one or more Subversion modules and Git 9 program sources residing in one or more Subversion modules and Git
10 repositories, along with other modules it depends on, also in Subversion or Git, 10 repositories, along with other modules it depends on, also in Subversion or Git,
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 return 496 return
497 497
498 # Run hooks on the basis of whether the files from the gclient operation 498 # Run hooks on the basis of whether the files from the gclient operation
499 # match each hook's pattern. 499 # match each hook's pattern.
500 for hook_dict in hooks: 500 for hook_dict in hooks:
501 pattern = re.compile(hook_dict['pattern']) 501 pattern = re.compile(hook_dict['pattern'])
502 matching_file_list = [f for f in file_list if pattern.search(f)] 502 matching_file_list = [f for f in file_list if pattern.search(f)]
503 if matching_file_list: 503 if matching_file_list:
504 self._RunHookAction(hook_dict, matching_file_list) 504 self._RunHookAction(hook_dict, matching_file_list)
505 505
506 def _EnforceRevisions(self, solutions):
507 """Checks for revision overrides."""
508 revision_overrides = {}
509 solutions = [s['name'] for s in solutions]
510 if self._options.revisions:
511 revision = self._options.revisions[0]
512 # Ignore solution@
513 rev = revision
514 if '@' in revision:
515 rev = revision.split('@', 1)[1]
516 revision_overrides[solutions[0]] = rev
517
518 if len(self._options.revisions) > 1:
519 # Enforce solution@rev format for following params.
520 for revision in self._options.revisions[1:]:
521 if not '@' in revision:
522 raise gclient_utils.Error(
523 'Specify the full dependency when specifying a revision number '
524 'for non-primary solution.')
525 sol, rev = revision.split("@", 1)
526 # Disallow conflicting revs
527 if revision_overrides.get(sol, rev) != rev:
528 raise gclient_utils.Error(
529 'Conflicting revision numbers specified for %s: %s and %s.' %
530 (sol, revision_overrides[sol], rev))
531 if not sol in solutions:
532 raise gclient_utils.Error('%s is not a valid solution.' % sol)
533 revision_overrides[sol] = rev
534 return revision_overrides
535
506 def RunOnDeps(self, command, args): 536 def RunOnDeps(self, command, args):
507 """Runs a command on each dependency in a client and its dependencies. 537 """Runs a command on each dependency in a client and its dependencies.
508 538
509 The module's dependencies are specified in its top-level DEPS files. 539 The module's dependencies are specified in its top-level DEPS files.
510 540
511 Args: 541 Args:
512 command: The command to use (e.g., 'status' or 'diff') 542 command: The command to use (e.g., 'status' or 'diff')
513 args: list of str - extra arguments to add to the command line. 543 args: list of str - extra arguments to add to the command line.
514 544
515 Raises: 545 Raises:
516 Error: If the client has conflicting entries. 546 Error: If the client has conflicting entries.
517 """ 547 """
518 if not command in self.supported_commands: 548 if not command in self.supported_commands:
519 raise gclient_utils.Error("'%s' is an unsupported command" % command) 549 raise gclient_utils.Error("'%s' is an unsupported command" % command)
520 550
521 # Check for revision overrides.
522 revision_overrides = {}
523 for revision in self._options.revisions:
524 if revision.find("@") == -1:
525 raise gclient_utils.Error(
526 "Specify the full dependency when specifying a revision number.")
527 revision_elem = revision.split("@")
528 # Disallow conflicting revs
529 if revision_overrides.has_key(revision_elem[0]) and \
530 revision_overrides[revision_elem[0]] != revision_elem[1]:
531 raise gclient_utils.Error(
532 "Conflicting revision numbers specified.")
533 revision_overrides[revision_elem[0]] = revision_elem[1]
534
535 solutions = self.GetVar("solutions") 551 solutions = self.GetVar("solutions")
536 if not solutions: 552 if not solutions:
537 raise gclient_utils.Error("No solution specified") 553 raise gclient_utils.Error("No solution specified")
554 revision_overrides = self._EnforceRevisions(solutions)
538 555
539 # When running runhooks --force, there's no need to consult the SCM. 556 # When running runhooks --force, there's no need to consult the SCM.
540 # All known hooks are expected to run unconditionally regardless of working 557 # All known hooks are expected to run unconditionally regardless of working
541 # copy state, so skip the SCM status check. 558 # copy state, so skip the SCM status check.
542 run_scm = not (command == 'runhooks' and self._options.force) 559 run_scm = not (command == 'runhooks' and self._options.force)
543 560
544 entries = {} 561 entries = {}
545 entries_deps_content = {} 562 entries_deps_content = {}
546 file_list = [] 563 file_list = []
547 # Run on the base solutions first. 564 # Run on the base solutions first.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 print("\n________ deleting \'%s\' " + 689 print("\n________ deleting \'%s\' " +
673 "in \'%s\'") % (entry_fixed, self._root_dir) 690 "in \'%s\'") % (entry_fixed, self._root_dir)
674 gclient_utils.RemoveDirectory(e_dir) 691 gclient_utils.RemoveDirectory(e_dir)
675 # record the current list of entries for next time 692 # record the current list of entries for next time
676 self._SaveEntries(entries) 693 self._SaveEntries(entries)
677 694
678 def PrintRevInfo(self): 695 def PrintRevInfo(self):
679 """Output revision info mapping for the client and its dependencies. 696 """Output revision info mapping for the client and its dependencies.
680 697
681 This allows the capture of an overall "revision" for the source tree that 698 This allows the capture of an overall "revision" for the source tree that
682 can be used to reproduce the same tree in the future. The actual output 699 can be used to reproduce the same tree in the future. It is only useful for
683 contains enough information (source paths, svn server urls and revisions) 700 "unpinned dependencies", i.e. DEPS/deps references without a svn revision
684 that it can be used either to generate external svn/git commands (without 701 number or a git hash. A git branch name isn't "pinned" since the actual
685 gclient) or as input to gclient's --rev option (with some massaging of 702 commit can change.
686 the data).
687
688 Since we care about the revision of the current source tree, for git
689 repositories this command uses the revision of the HEAD. For subversion we
690 use BASE.
691 703
692 The --snapshot option allows creating a .gclient file to reproduce the tree. 704 The --snapshot option allows creating a .gclient file to reproduce the tree.
693
694 Raises:
695 Error: If the client has conflicting entries.
696 """ 705 """
697 # Check for revision overrides.
698 revision_overrides = {}
699 for revision in self._options.revisions:
700 if revision.find("@") < 0:
701 raise gclient_utils.Error(
702 "Specify the full dependency when specifying a revision number.")
703 revision_elem = revision.split("@")
704 # Disallow conflicting revs
705 if revision_overrides.has_key(revision_elem[0]) and \
706 revision_overrides[revision_elem[0]] != revision_elem[1]:
707 raise gclient_utils.Error(
708 "Conflicting revision numbers specified.")
709 revision_overrides[revision_elem[0]] = revision_elem[1]
710
711 solutions = self.GetVar("solutions") 706 solutions = self.GetVar("solutions")
712 if not solutions: 707 if not solutions:
713 raise gclient_utils.Error("No solution specified") 708 raise gclient_utils.Error("No solution specified")
714 709
715 # Inner helper to generate base url and rev tuple 710 # Inner helper to generate base url and rev tuple
716 def GetURLAndRev(name, original_url): 711 def GetURLAndRev(name, original_url):
717 url, _ = gclient_utils.SplitUrlRevision(original_url) 712 url, _ = gclient_utils.SplitUrlRevision(original_url)
718 scm = gclient_scm.CreateSCM(original_url, self._root_dir, name) 713 scm = gclient_scm.CreateSCM(original_url, self._root_dir, name)
719 return (url, scm.revinfo(self._options, [], None)) 714 return (url, scm.revinfo(self._options, [], None))
720 715
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 update src directory to r31000 921 update src directory to r31000
927 """) 922 """)
928 def CMDsync(parser, args): 923 def CMDsync(parser, args):
929 """Checkout/update all modules.""" 924 """Checkout/update all modules."""
930 parser.add_option("--force", action="store_true", 925 parser.add_option("--force", action="store_true",
931 help="force update even for unchanged modules") 926 help="force update even for unchanged modules")
932 parser.add_option("--nohooks", action="store_true", 927 parser.add_option("--nohooks", action="store_true",
933 help="don't run hooks after the update is complete") 928 help="don't run hooks after the update is complete")
934 parser.add_option("-r", "--revision", action="append", 929 parser.add_option("-r", "--revision", action="append",
935 dest="revisions", metavar="REV", default=[], 930 dest="revisions", metavar="REV", default=[],
936 help="update given solution to specified revision, " 931 help="Enforces revision/hash for the primary solution. "
937 "can be used multiple times for each solution, " 932 "To modify a secondary solution, use it at least once "
938 "e.g. -r src@123, -r internal@32") 933 "for the primary solution and then use the format "
934 "solution@rev/hash, e.g. -r src@123")
939 parser.add_option("--head", action="store_true", 935 parser.add_option("--head", action="store_true",
940 help="skips any safesync_urls specified in " 936 help="skips any safesync_urls specified in "
941 "configured solutions and sync to head instead") 937 "configured solutions and sync to head instead")
942 parser.add_option("--delete_unversioned_trees", action="store_true", 938 parser.add_option("--delete_unversioned_trees", action="store_true",
943 help="delete any unexpected unversioned trees " 939 help="delete any unexpected unversioned trees "
944 "that are in the checkout") 940 "that are in the checkout")
945 parser.add_option("--reset", action="store_true", 941 parser.add_option("--reset", action="store_true",
946 help="resets any local changes before updating (git only)") 942 help="resets any local changes before updating (git only)")
947 parser.add_option("--deps", dest="deps_os", metavar="OS_LIST", 943 parser.add_option("--deps", dest="deps_os", metavar="OS_LIST",
948 help="sync deps for the specified (comma-separated) " 944 help="sync deps for the specified (comma-separated) "
949 "platform(s); 'all' will sync all platforms") 945 "platform(s); 'all' will sync all platforms")
950 parser.add_option("--manually_grab_svn_rev", action="store_true", 946 parser.add_option("--manually_grab_svn_rev", action="store_true",
951 help="Skip svn up whenever possible by requesting " 947 help="Skip svn up whenever possible by requesting "
952 "actual HEAD revision from the repository") 948 "actual HEAD revision from the repository")
953 (options, args) = parser.parse_args(args) 949 (options, args) = parser.parse_args(args)
954 client = GClient.LoadCurrentConfig(options) 950 client = GClient.LoadCurrentConfig(options)
955 951
956 if not client: 952 if not client:
957 raise gclient_utils.Error("client not configured; see 'gclient config'") 953 raise gclient_utils.Error("client not configured; see 'gclient config'")
958 954
959 if not options.head: 955 if not options.head:
960 solutions = client.GetVar('solutions') 956 solutions = client.GetVar('solutions')
961 if solutions: 957 if solutions:
958 first = True
962 for s in solutions: 959 for s in solutions:
963 if s.get('safesync_url', ''): 960 if s.get('safesync_url', None):
964 # rip through revisions and make sure we're not over-riding 961 # rip through revisions and make sure we're not over-riding
965 # something that was explicitly passed 962 # something that was explicitly passed
966 has_key = False 963 has_key = False
964 r_first = True
967 for r in options.revisions: 965 for r in options.revisions:
968 if r.split('@')[0] == s['name']: 966 if (first and r_first) or r.split('@', 1)[0] == s['name']:
969 has_key = True 967 has_key = True
970 break 968 break
969 r_first = False
971 970
972 if not has_key: 971 if not has_key:
973 handle = urllib.urlopen(s['safesync_url']) 972 handle = urllib.urlopen(s['safesync_url'])
974 rev = handle.read().strip() 973 rev = handle.read().strip()
975 handle.close() 974 handle.close()
976 if len(rev): 975 if len(rev):
977 options.revisions.append(s['name']+'@'+rev) 976 options.revisions.append(s['name']+'@'+rev)
977 first = False
978 978
979 if options.verbose: 979 if options.verbose:
980 # Print out the .gclient file. This is longer than if we just printed the 980 # Print out the .gclient file. This is longer than if we just printed the
981 # client dict, but more legible, and it might contain helpful comments. 981 # client dict, but more legible, and it might contain helpful comments.
982 print(client.ConfigContent()) 982 print(client.ConfigContent())
983 return client.RunOnDeps('update', args) 983 return client.RunOnDeps('update', args)
984 984
985 985
986 def CMDupdate(parser, args): 986 def CMDupdate(parser, args):
987 """Alias for the sync command. Deprecated.""" 987 """Alias for the sync command. Deprecated."""
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 1116
1117 1117
1118 if "__main__" == __name__: 1118 if "__main__" == __name__:
1119 try: 1119 try:
1120 sys.exit(Main(sys.argv[1:])) 1120 sys.exit(Main(sys.argv[1:]))
1121 except gclient_utils.Error, e: 1121 except gclient_utils.Error, e:
1122 print >> sys.stderr, "Error: %s" % str(e) 1122 print >> sys.stderr, "Error: %s" % str(e)
1123 sys.exit(1) 1123 sys.exit(1)
1124 1124
1125 # vim: ts=2:sw=2:tw=80:et: 1125 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | tests/fake_repos.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698