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

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.
M-A Ruel 2013/04/16 20:28:04 Uses
kustermann 2013/04/17 13:55:06 Done.
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
561 """If we are performing an update and --transitive is set, convert the 569 # 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('/'):
M-A Ruel 2013/04/16 20:28:04 Why not do this check because evaluating parent_re
kustermann 2013/04/17 13:55:06 Both branches used parent_revision. I changed it s
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"""
M-A Ruel 2013/04/16 20:28:04 """SCMWrapper instance for this dependency or None
kustermann 2013/04/17 13:55:06 Done.
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