OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright 2008 Google Inc. All Rights Reserved. | 3 # Copyright 2008 Google Inc. All Rights Reserved. |
4 # | 4 # |
5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
8 # | 8 # |
9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
10 # | 10 # |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 'checkout': update_pattern, | 550 'checkout': update_pattern, |
551 'status': status_pattern, | 551 'status': status_pattern, |
552 'update': update_pattern, | 552 'update': update_pattern, |
553 }[args[0]] | 553 }[args[0]] |
554 | 554 |
555 SubprocessCallAndCapture(command, in_directory, options.stdout, | 555 SubprocessCallAndCapture(command, in_directory, options.stdout, |
556 pattern=pattern, capture_list=file_list) | 556 pattern=pattern, capture_list=file_list) |
557 | 557 |
558 | 558 |
559 def CaptureSVNInfo(options, relpath, in_directory): | 559 def CaptureSVNInfo(options, relpath, in_directory): |
560 """Runs 'svn info' on an existing path. | 560 """Returns a dictionary from the svn info output for the given file. |
561 | 561 |
562 Args: | 562 Args: |
563 relpath: The directory where the working copy resides relative to | 563 relpath: The directory where the working copy resides relative to |
564 the directory given by in_directory. | 564 the directory given by in_directory. |
565 in_directory: The directory where svn is to be run. | 565 in_directory: The directory where svn is to be run. |
566 | |
567 Returns: | |
568 An object with fields corresponding to the output of 'svn info' | |
569 """ | 566 """ |
570 dom = ParseXML(CaptureSVN(options, ["info", "--xml", relpath], in_directory)) | 567 dom = ParseXML(CaptureSVN(options, ["info", "--xml", relpath], in_directory)) |
571 result = PrintableObject() | 568 result = {} |
572 if dom: | 569 if dom: |
| 570 def C(item, f): |
| 571 if item is not None: return f(item) |
573 # /info/entry/ | 572 # /info/entry/ |
574 # url | 573 # url |
575 # reposityory/(root|uuid) | 574 # reposityory/(root|uuid) |
576 # wc-info/(schedule|depth) | 575 # wc-info/(schedule|depth) |
577 # commit/(author|date) | 576 # commit/(author|date) |
578 # str() the results because they may be returned as Unicode, which | 577 # str() the results because they may be returned as Unicode, which |
579 # interferes with the higher layers matching up things in the deps | 578 # interferes with the higher layers matching up things in the deps |
580 # dictionary. | 579 # dictionary. |
581 result = PrintableObject() | 580 # TODO(maruel): Fix at higher level instead (!) |
582 result.root = str(GetNamedNodeText(dom, 'root')) | 581 result['Repository Root'] = C(GetNamedNodeText(dom, 'root'), str) |
583 result.url = str(GetNamedNodeText(dom, 'url')) | 582 result['URL'] = C(GetNamedNodeText(dom, 'url'), str) |
584 result.uuid = str(GetNamedNodeText(dom, 'uuid')) | 583 result['UUID'] = C(GetNamedNodeText(dom, 'uuid'), str) |
585 result.revision = int(GetNodeNamedAttributeText(dom, 'entry', 'revision')) | 584 result['Revision'] = C(GetNodeNamedAttributeText(dom, 'entry', 'revision'), |
| 585 int) |
| 586 result['Node Kind'] = C(GetNodeNamedAttributeText(dom, 'entry', 'kind'), |
| 587 str) |
| 588 result['Schedule'] = C(GetNamedNodeText(dom, 'schedule'), str) |
| 589 result['Path'] = C(GetNodeNamedAttributeText(dom, 'entry', 'path'), str) |
| 590 result['Copied From URL'] = C(GetNamedNodeText(dom, 'copy-from-url'), str) |
| 591 result['Copied From Rev'] = C(GetNamedNodeText(dom, 'copy-from-rev'), str) |
586 return result | 592 return result |
587 | 593 |
588 | 594 |
589 def CaptureSVNHeadRevision(options, url): | 595 def CaptureSVNHeadRevision(options, url): |
590 """Get the head revision of a SVN repository. | 596 """Get the head revision of a SVN repository. |
591 | 597 |
592 Returns: | 598 Returns: |
593 Int head revision | 599 Int head revision |
594 """ | 600 """ |
595 info = CaptureSVN(options, ["info", "--xml", url], os.getcwd()) | 601 info = CaptureSVN(options, ["info", "--xml", url], os.getcwd()) |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 return | 780 return |
775 | 781 |
776 # Get the existing scm url and the revision number of the current checkout. | 782 # Get the existing scm url and the revision number of the current checkout. |
777 from_info = CaptureSVNInfo(options, | 783 from_info = CaptureSVNInfo(options, |
778 os.path.join(self._root_dir, self.relpath, '.'), | 784 os.path.join(self._root_dir, self.relpath, '.'), |
779 '.') | 785 '.') |
780 | 786 |
781 if options.manually_grab_svn_rev: | 787 if options.manually_grab_svn_rev: |
782 # Retrieve the current HEAD version because svn is slow at null updates. | 788 # Retrieve the current HEAD version because svn is slow at null updates. |
783 if not revision: | 789 if not revision: |
784 from_info_live = CaptureSVNInfo(options, from_info.url, '.') | 790 from_info_live = CaptureSVNInfo(options, from_info['URL'], '.') |
785 revision = int(from_info_live.revision) | 791 revision = int(from_info_live['Revision']) |
786 rev_str = ' at %d' % revision | 792 rev_str = ' at %d' % revision |
787 | 793 |
788 if from_info.url != components[0]: | 794 if from_info['URL'] != components[0]: |
789 to_info = CaptureSVNInfo(options, url, '.') | 795 to_info = CaptureSVNInfo(options, url, '.') |
790 if from_info.root != to_info.root: | 796 if from_info['Repository Root'] != to_info['Repository Root']: |
791 # We have different roots, so check if we can switch --relocate. | 797 # We have different roots, so check if we can switch --relocate. |
792 # Subversion only permits this if the repository UUIDs match. | 798 # Subversion only permits this if the repository UUIDs match. |
793 if from_info.uuid != to_info.uuid: | 799 if from_info['UUID'] != to_info['UUID']: |
794 raise Error("Can't switch the checkout to %s; UUID don't match" % url) | 800 raise Error("Can't switch the checkout to %s; UUID don't match. That " |
| 801 "simply means in theory, gclient should verify you don't " |
| 802 "have a local change, remove the old checkout and do a " |
| 803 "fresh new checkout of the new repo. Contributions are " |
| 804 "welcome." % url) |
795 | 805 |
796 # Perform the switch --relocate, then rewrite the from_url | 806 # Perform the switch --relocate, then rewrite the from_url |
797 # to reflect where we "are now." (This is the same way that | 807 # to reflect where we "are now." (This is the same way that |
798 # Subversion itself handles the metadata when switch --relocate | 808 # Subversion itself handles the metadata when switch --relocate |
799 # is used.) This makes the checks below for whether we | 809 # is used.) This makes the checks below for whether we |
800 # can update to a revision or have to switch to a different | 810 # can update to a revision or have to switch to a different |
801 # branch work as expected. | 811 # branch work as expected. |
802 # TODO(maruel): TEST ME ! | 812 # TODO(maruel): TEST ME ! |
803 command = ["switch", "--relocate", from_info.root, to_info.root, | 813 command = ["switch", "--relocate", |
| 814 from_info['Repository Root'], |
| 815 to_info['Repository Root'], |
804 self.relpath] | 816 self.relpath] |
805 RunSVN(options, command, self._root_dir) | 817 RunSVN(options, command, self._root_dir) |
806 from_info.url = from_info.url.replace(from_info.root, to_info.root) | 818 from_info['URL'] = from_info['URL'].replace( |
| 819 from_info['Repository Root'], |
| 820 to_info['Repository Root']) |
807 | 821 |
808 # If the provided url has a revision number that matches the revision | 822 # If the provided url has a revision number that matches the revision |
809 # number of the existing directory, then we don't need to bother updating. | 823 # number of the existing directory, then we don't need to bother updating. |
810 if not options.force and from_info.revision == revision: | 824 if not options.force and from_info['Revision'] == revision: |
811 if options.verbose or not forced_revision: | 825 if options.verbose or not forced_revision: |
812 print >>options.stdout, ("\n_____ %s%s" % ( | 826 print >>options.stdout, ("\n_____ %s%s" % ( |
813 self.relpath, rev_str)) | 827 self.relpath, rev_str)) |
814 return | 828 return |
815 | 829 |
816 command = ["update", os.path.join(self._root_dir, self.relpath)] | 830 command = ["update", os.path.join(self._root_dir, self.relpath)] |
817 if revision: | 831 if revision: |
818 command.extend(['--revision', str(revision)]) | 832 command.extend(['--revision', str(revision)]) |
819 RunSVNAndGetFileList(options, command, self._root_dir, file_list) | 833 RunSVNAndGetFileList(options, command, self._root_dir, file_list) |
820 | 834 |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 | 1716 |
1703 if "__main__" == __name__: | 1717 if "__main__" == __name__: |
1704 try: | 1718 try: |
1705 result = Main(sys.argv) | 1719 result = Main(sys.argv) |
1706 except Error, e: | 1720 except Error, e: |
1707 print "Error: %s" % str(e) | 1721 print "Error: %s" % str(e) |
1708 result = 1 | 1722 result = 1 |
1709 sys.exit(result) | 1723 sys.exit(result) |
1710 | 1724 |
1711 # vim: ts=2:sw=2:tw=80:et: | 1725 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |