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

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') | 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 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 """Uses revision/timestamp of 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
554 # converted to date format. 562 # If this dependency is in the same repository as parent it's url will
555 assert (not options.revision or 563 # start with a slash. If so we take the parent revision instead of
556 gclient_utils.IsDateRevision(options.revision)) 564 # it's timestamp.
557 565 # (The timestamps of commits in google code are broken -- which can
558 @staticmethod 566 # result in dependencies to be checked out at the wrong revision)
559 def maybeConvertToDateRevision( 567 if self.url.startswith('/'):
560 command, options, name, scm, revision_overrides): 568 if options.verbose:
561 """If we are performing an update and --transitive is set, convert the 569 print('Using parent\'s revision %s since we are in the same '
562 revision to a date-revision (if necessary). Instead of having 570 'repository.' % options.revision)
563 -r 101 replace the revision with the time stamp of 101 (e.g. 571 else:
564 "{2011-18-04}"). 572 parent_revision_date = self.parent.used_scm.GetRevisionDate(
565 This way dependencies are upgraded to the revision they had at the 573 options.revision)
566 check-in of revision 101.""" 574 options.revision = gclient_utils.MakeDateRevision(
567 if (command == 'update' and 575 parent_revision_date)
568 options.transitive and 576 if options.verbose:
569 options.revision and 577 print('Using parent\'s revision date %s since we are in a '
570 not gclient_utils.IsDateRevision(options.revision)): 578 'different repository.' % options.revision)
571 revision_date = scm.GetRevisionDate(options.revision) 579 revision_overrides[self.name] = options.revision
572 revision = gclient_utils.MakeDateRevision(revision_date)
573 if options.verbose:
574 print("Updating revision override from %s to %s." %
575 (options.revision, revision))
576 revision_overrides[name] = revision
577 580
578 # Arguments number differs from overridden method 581 # Arguments number differs from overridden method
579 # pylint: disable=W0221 582 # pylint: disable=W0221
580 def run(self, revision_overrides, command, args, work_queue, options): 583 def run(self, revision_overrides, command, args, work_queue, options):
581 """Runs |command| then parse the DEPS file.""" 584 """Runs |command| then parse the DEPS file."""
582 logging.info('Dependency(%s).run()' % self.name) 585 logging.info('Dependency(%s).run()' % self.name)
583 assert self._file_list == [] 586 assert self._file_list == []
584 if not self.should_process: 587 if not self.should_process:
585 return 588 return
586 # When running runhooks, there's no need to consult the SCM. 589 # When running runhooks, there's no need to consult the SCM.
587 # All known hooks are expected to run unconditionally regardless of working 590 # All known hooks are expected to run unconditionally regardless of working
588 # copy state, so skip the SCM status check. 591 # copy state, so skip the SCM status check.
589 run_scm = command not in ('runhooks', 'recurse', None) 592 run_scm = command not in ('runhooks', 'recurse', None)
590 parsed_url = self.LateOverride(self.url) 593 parsed_url = self.LateOverride(self.url)
591 file_list = [] 594 file_list = []
592 if run_scm and parsed_url: 595 if run_scm and parsed_url:
593 if isinstance(parsed_url, self.FileImpl): 596 if isinstance(parsed_url, self.FileImpl):
594 # Special support for single-file checkout. 597 # Special support for single-file checkout.
595 if not command in (None, 'cleanup', 'diff', 'pack', 'status'): 598 if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
596 # Sadly, pylint doesn't realize that parsed_url is of FileImpl. 599 # Sadly, pylint doesn't realize that parsed_url is of FileImpl.
597 # pylint: disable=E1103 600 # pylint: disable=E1103
598 options.revision = parsed_url.GetRevision() 601 options.revision = parsed_url.GetRevision()
599 scm = gclient_scm.SVNWrapper(parsed_url.GetPath(), 602 self._used_scm = gclient_scm.SVNWrapper(
600 self.root.root_dir, 603 parsed_url.GetPath(), self.root.root_dir, self.name)
601 self.name) 604 self._used_scm.RunCommand('updatesingle',
602 scm.RunCommand('updatesingle', options, 605 options, args + [parsed_url.GetFilename()], file_list)
603 args + [parsed_url.GetFilename()],
604 file_list)
605 else: 606 else:
606 # Create a shallow copy to mutate revision. 607 # Create a shallow copy to mutate revision.
607 options = copy.copy(options) 608 options = copy.copy(options)
608 options.revision = revision_overrides.get(self.name) 609 options.revision = revision_overrides.get(self.name)
609 self.maybeGetParentRevision( 610 self.maybeGetParentRevision(
610 command, options, parsed_url, self.parent.name, revision_overrides) 611 command, options, parsed_url, self.parent.name, revision_overrides)
611 scm = gclient_scm.CreateSCM(parsed_url, self.root.root_dir, self.name) 612 self._used_scm = gclient_scm.CreateSCM(
612 scm.RunCommand(command, options, args, file_list) 613 parsed_url, self.root.root_dir, self.name)
613 self.maybeConvertToDateRevision( 614 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] 615 file_list = [os.path.join(self.name, f.strip()) for f in file_list]
616 616
617 # TODO(phajdan.jr): We should know exactly when the paths are absolute. 617 # TODO(phajdan.jr): We should know exactly when the paths are absolute.
618 # Convert all absolute paths to relative. 618 # Convert all absolute paths to relative.
619 for i in range(len(file_list)): 619 for i in range(len(file_list)):
620 # It depends on the command being executed (like runhooks vs sync). 620 # It depends on the command being executed (like runhooks vs sync).
621 if not os.path.isabs(file_list[i]): 621 if not os.path.isabs(file_list[i]):
622 continue 622 continue
623 prefix = os.path.commonprefix( 623 prefix = os.path.commonprefix(
624 [self.root.root_dir.lower(), file_list[i].lower()]) 624 [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 821 @gclient_utils.lockedmethod
822 def hooks_ran(self): 822 def hooks_ran(self):
823 return self._hooks_ran 823 return self._hooks_ran
824 824
825 @property 825 @property
826 @gclient_utils.lockedmethod 826 @gclient_utils.lockedmethod
827 def file_list(self): 827 def file_list(self):
828 return tuple(self._file_list) 828 return tuple(self._file_list)
829 829
830 @property 830 @property
831 def used_scm(self):
832 """SCMWrapper instance for this dependency or None if not processed yet."""
833 return self._used_scm
834
835 @property
831 def file_list_and_children(self): 836 def file_list_and_children(self):
832 result = list(self.file_list) 837 result = list(self.file_list)
833 for d in self.dependencies: 838 for d in self.dependencies:
834 result.extend(d.file_list_and_children) 839 result.extend(d.file_list_and_children)
835 return tuple(result) 840 return tuple(result)
836 841
837 def __str__(self): 842 def __str__(self):
838 out = [] 843 out = []
839 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', 844 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps',
840 'custom_vars', 'deps_hooks', 'file_list', 'should_process', 845 '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: 1780 except (gclient_utils.Error, subprocess2.CalledProcessError), e:
1776 print >> sys.stderr, 'Error: %s' % str(e) 1781 print >> sys.stderr, 'Error: %s' % str(e)
1777 return 1 1782 return 1
1778 1783
1779 1784
1780 if '__main__' == __name__: 1785 if '__main__' == __name__:
1781 fix_encoding.fix_encoding() 1786 fix_encoding.fix_encoding()
1782 sys.exit(Main(sys.argv[1:])) 1787 sys.exit(Main(sys.argv[1:]))
1783 1788
1784 # vim: ts=2:sw=2:tw=80:et: 1789 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « no previous file | testing_support/fake_repos.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698