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

Side by Side Diff: gclient.py

Issue 13814012: Changed the behaviour of '--transitive' in gclient.py to use revision instead of timestamp for iden… (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 7 years, 8 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 | testing_support/fake_repos.py » ('j') | testing_support/fake_repos.py » ('J')
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 7
8 Files 8 Files
9 .gclient : Current client configuration, written by 'config' command. 9 .gclient : Current client configuration, written by 'config' command.
10 Format is a Python script defining 'solutions', a list whose 10 Format is a Python script defining 'solutions', a list whose
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 # A cache of the files affected by the current operation, necessary for 291 # A cache of the files affected by the current operation, necessary for
292 # hooks. 292 # hooks.
293 self._file_list = [] 293 self._file_list = []
294 # If it is not set to True, the dependency wasn't processed for its child 294 # If it is not set to True, the dependency wasn't processed for its child
295 # dependency, i.e. its DEPS wasn't read. 295 # dependency, i.e. its DEPS wasn't read.
296 self._deps_parsed = False 296 self._deps_parsed = False
297 # This dependency has been processed, i.e. checked out 297 # This dependency has been processed, i.e. checked out
298 self._processed = False 298 self._processed = False
299 # This dependency had its hook run 299 # This dependency had its hook run
300 self._hooks_ran = False 300 self._hooks_ran = False
301 # This is the scm used to checkout self.url. It may be used by dependencies
302 # to get the datetime of the revision we checked out.
303 self._used_scm = None
301 304
302 if not self.name and self.parent: 305 if not self.name and self.parent:
303 raise gclient_utils.Error('Dependency without name') 306 raise gclient_utils.Error('Dependency without name')
304 307
305 @property 308 @property
306 def requirements(self): 309 def requirements(self):
307 """Calculate the list of requirements.""" 310 """Calculate the list of requirements."""
308 requirements = set() 311 requirements = set()
309 # self.parent is implicitly a requirement. This will be recursive by 312 # self.parent is implicitly a requirement. This will be recursive by
310 # definition. 313 # definition.
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 self.add_dependencies_and_close(deps_to_add, local_scope.get('hooks', [])) 534 self.add_dependencies_and_close(deps_to_add, local_scope.get('hooks', []))
532 logging.info('ParseDepsFile(%s) done' % self.name) 535 logging.info('ParseDepsFile(%s) done' % self.name)
533 536
534 def add_dependencies_and_close(self, deps_to_add, hooks): 537 def add_dependencies_and_close(self, deps_to_add, hooks):
535 """Adds the dependencies, hooks and mark the parsing as done.""" 538 """Adds the dependencies, hooks and mark the parsing as done."""
536 for dep in deps_to_add: 539 for dep in deps_to_add:
537 if dep.verify_validity(): 540 if dep.verify_validity():
538 self.add_dependency(dep) 541 self.add_dependency(dep)
539 self._mark_as_parsed(hooks) 542 self._mark_as_parsed(hooks)
540 543
541 @staticmethod
542 def maybeGetParentRevision( 544 def maybeGetParentRevision(
543 command, options, parsed_url, parent_name, revision_overrides): 545 self, command, options, parsed_url, parent_name, revision_overrides):
544 """If we are performing an update and --transitive is set, set the 546 """Use revision/timestamp from parent if no explicit revision was specified.
545 revision to the parent's revision. If we have an explicit revision 547
546 do nothing.""" 548 If we are performing an update and --transitive is set, use
549 - the parent's revision if 'self.url' is in the same repository
550 - the parent's timestamp otherwise
551 to update 'self.url'. The used revision/timestamp will be set in
552 'options.revision'.
553 If we have an explicit revision do nothing.
554 """
547 if command == 'update' and options.transitive and not options.revision: 555 if command == 'update' and options.transitive and not options.revision:
548 _, revision = gclient_utils.SplitUrlRevision(parsed_url) 556 _, revision = gclient_utils.SplitUrlRevision(parsed_url)
549 if not revision: 557 if not revision:
550 options.revision = revision_overrides.get(parent_name) 558 options.revision = revision_overrides.get(parent_name)
551 if options.verbose and options.revision: 559 if (options.revision and
552 print("Using parent's revision date: %s" % options.revision) 560 not gclient_utils.IsDateRevision(options.revision)):
553 # If the parent has a revision override, then it must have been 561 assert self.parent and self.parent.used_scm != None
554 # converted to date format. 562 parent_revision_date = self.parent.used_scm.GetRevisionDate(
555 assert (not options.revision or 563 options.revision)
556 gclient_utils.IsDateRevision(options.revision)) 564 parent_revision = gclient_utils.MakeDateRevision(parent_revision_date)
557 565 # If this dependency is in the same repository as parent it's url will
558 @staticmethod 566 # start with a slash. If so we take the parent revision instead of
559 def maybeConvertToDateRevision( 567 # it's timestamp.
560 command, options, name, scm, revision_overrides): 568 # (The timestamps of commits in google code are broken -- which can
ricow1 2013/04/15 09:13:32 which can can -> which can
kustermann 2013/04/17 13:55:06 Done.
561 """If we are performing an update and --transitive is set, convert the 569 # can result in dependencies to be checked out at the wrong revision)
562 revision to a date-revision (if necessary). Instead of having 570 if self.url.startswith('/'):
563 -r 101 replace the revision with the time stamp of 101 (e.g. 571 if options.verbose:
564 "{2011-18-04}"). 572 print('Not updating revision override from %s to %s. Using '
565 This way dependencies are upgraded to the revision they had at the 573 'parent\'s revision %s since we are in the same repository.'
566 check-in of revision 101.""" 574 % (options.revision, parent_revision, options.revision))
567 if (command == 'update' and 575 else:
568 options.transitive and 576 if options.verbose:
569 options.revision and 577 print('Updating revision override from %s to %s.' %
570 not gclient_utils.IsDateRevision(options.revision)): 578 (options.revision, parent_revision))
571 revision_date = scm.GetRevisionDate(options.revision) 579 revision_overrides[self.name] = parent_revision
572 revision = gclient_utils.MakeDateRevision(revision_date) 580 options.revision = parent_revision
573 if options.verbose:
574 print("Updating revision override from %s to %s." %
575 (options.revision, revision))
576 revision_overrides[name] = revision
577 581
578 # Arguments number differs from overridden method 582 # Arguments number differs from overridden method
579 # pylint: disable=W0221 583 # pylint: disable=W0221
580 def run(self, revision_overrides, command, args, work_queue, options): 584 def run(self, revision_overrides, command, args, work_queue, options):
581 """Runs |command| then parse the DEPS file.""" 585 """Runs |command| then parse the DEPS file."""
582 logging.info('Dependency(%s).run()' % self.name) 586 logging.info('Dependency(%s).run()' % self.name)
583 assert self._file_list == [] 587 assert self._file_list == []
584 if not self.should_process: 588 if not self.should_process:
585 return 589 return
586 # When running runhooks, there's no need to consult the SCM. 590 # When running runhooks, there's no need to consult the SCM.
587 # All known hooks are expected to run unconditionally regardless of working 591 # All known hooks are expected to run unconditionally regardless of working
588 # copy state, so skip the SCM status check. 592 # copy state, so skip the SCM status check.
589 run_scm = command not in ('runhooks', 'recurse', None) 593 run_scm = command not in ('runhooks', 'recurse', None)
590 parsed_url = self.LateOverride(self.url) 594 parsed_url = self.LateOverride(self.url)
591 file_list = [] 595 file_list = []
592 if run_scm and parsed_url: 596 if run_scm and parsed_url:
593 if isinstance(parsed_url, self.FileImpl): 597 if isinstance(parsed_url, self.FileImpl):
594 # Special support for single-file checkout. 598 # Special support for single-file checkout.
595 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): 599 if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
596 # Sadly, pylint doesn't realize that parsed_url is of FileImpl. 600 # Sadly, pylint doesn't realize that parsed_url is of FileImpl.
597 # pylint: disable=E1103 601 # pylint: disable=E1103
598 options.revision = parsed_url.GetRevision() 602 options.revision = parsed_url.GetRevision()
599 scm = gclient_scm.SVNWrapper(parsed_url.GetPath(), 603 self._used_scm = gclient_scm.SVNWrapper(
600 self.root.root_dir, 604 parsed_url.GetPath(), self.root.root_dir, self.name)
601 self.name) 605 self._used_scm.RunCommand('updatesingle',
602 scm.RunCommand('updatesingle', options, 606 options, args + [parsed_url.GetFilename()], file_list)
603 args + [parsed_url.GetFilename()],
604 file_list)
605 else: 607 else:
606 # Create a shallow copy to mutate revision. 608 # Create a shallow copy to mutate revision.
607 options = copy.copy(options) 609 options = copy.copy(options)
608 options.revision = revision_overrides.get(self.name) 610 options.revision = revision_overrides.get(self.name)
609 self.maybeGetParentRevision( 611 self.maybeGetParentRevision(
610 command, options, parsed_url, self.parent.name, revision_overrides) 612 command, options, parsed_url, self.parent.name, revision_overrides)
611 scm = gclient_scm.CreateSCM(parsed_url, self.root.root_dir, self.name) 613 self._used_scm = gclient_scm.CreateSCM(
612 scm.RunCommand(command, options, args, file_list) 614 parsed_url, self.root.root_dir, self.name)
613 self.maybeConvertToDateRevision( 615 self._used_scm.RunCommand(command, options, args, file_list)
614 command, options, self.name, scm, revision_overrides)
615 file_list = [os.path.join(self.name, f.strip()) for f in file_list] 616 file_list = [os.path.join(self.name, f.strip()) for f in file_list]
616 617
617 # TODO(phajdan.jr): We should know exactly when the paths are absolute. 618 # TODO(phajdan.jr): We should know exactly when the paths are absolute.
618 # Convert all absolute paths to relative. 619 # Convert all absolute paths to relative.
619 for i in range(len(file_list)): 620 for i in range(len(file_list)):
620 # It depends on the command being executed (like runhooks vs sync). 621 # It depends on the command being executed (like runhooks vs sync).
621 if not os.path.isabs(file_list[i]): 622 if not os.path.isabs(file_list[i]):
622 continue 623 continue
623 prefix = os.path.commonprefix( 624 prefix = os.path.commonprefix(
624 [self.root.root_dir.lower(), file_list[i].lower()]) 625 [self.root.root_dir.lower(), file_list[i].lower()])
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 @gclient_utils.lockedmethod 822 @gclient_utils.lockedmethod
822 def hooks_ran(self): 823 def hooks_ran(self):
823 return self._hooks_ran 824 return self._hooks_ran
824 825
825 @property 826 @property
826 @gclient_utils.lockedmethod 827 @gclient_utils.lockedmethod
827 def file_list(self): 828 def file_list(self):
828 return tuple(self._file_list) 829 return tuple(self._file_list)
829 830
830 @property 831 @property
832 def used_scm(self):
833 """The scm that was used to checkout self.url. None if nothing has been
834 checked out"""
835 return self._used_scm
836
837 @property
831 def file_list_and_children(self): 838 def file_list_and_children(self):
832 result = list(self.file_list) 839 result = list(self.file_list)
833 for d in self.dependencies: 840 for d in self.dependencies:
834 result.extend(d.file_list_and_children) 841 result.extend(d.file_list_and_children)
835 return tuple(result) 842 return tuple(result)
836 843
837 def __str__(self): 844 def __str__(self):
838 out = [] 845 out = []
839 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', 846 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps',
840 'custom_vars', 'deps_hooks', 'file_list', 'should_process', 847 'custom_vars', 'deps_hooks', 'file_list', 'should_process',
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 except (gclient_utils.Error, subprocess2.CalledProcessError), e: 1782 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
1776 print >> sys.stderr, 'Error: %s' % str(e) 1783 print >> sys.stderr, 'Error: %s' % str(e)
1777 return 1 1784 return 1
1778 1785
1779 1786
1780 if '__main__' == __name__: 1787 if '__main__' == __name__:
1781 fix_encoding.fix_encoding() 1788 fix_encoding.fix_encoding()
1782 sys.exit(Main(sys.argv[1:])) 1789 sys.exit(Main(sys.argv[1:]))
1783 1790
1784 # vim: ts=2:sw=2:tw=80:et: 1791 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | testing_support/fake_repos.py » ('j') | testing_support/fake_repos.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698