diff options
Diffstat (limited to 'manifest_xml.py')
-rw-r--r-- | manifest_xml.py | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/manifest_xml.py b/manifest_xml.py index 50417c60..cc441dc8 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
@@ -18,7 +18,15 @@ import itertools | |||
18 | import os | 18 | import os |
19 | import re | 19 | import re |
20 | import sys | 20 | import sys |
21 | import urlparse | 21 | try: |
22 | # For python3 | ||
23 | import urllib.parse | ||
24 | except ImportError: | ||
25 | # For python2 | ||
26 | import imp | ||
27 | import urlparse | ||
28 | urllib = imp.new_module('urllib') | ||
29 | urllib.parse = urlparse | ||
22 | import xml.dom.minidom | 30 | import xml.dom.minidom |
23 | 31 | ||
24 | from git_config import GitConfig | 32 | from git_config import GitConfig |
@@ -30,8 +38,8 @@ MANIFEST_FILE_NAME = 'manifest.xml' | |||
30 | LOCAL_MANIFEST_NAME = 'local_manifest.xml' | 38 | LOCAL_MANIFEST_NAME = 'local_manifest.xml' |
31 | LOCAL_MANIFESTS_DIR_NAME = 'local_manifests' | 39 | LOCAL_MANIFESTS_DIR_NAME = 'local_manifests' |
32 | 40 | ||
33 | urlparse.uses_relative.extend(['ssh', 'git']) | 41 | urllib.parse.uses_relative.extend(['ssh', 'git']) |
34 | urlparse.uses_netloc.extend(['ssh', 'git']) | 42 | urllib.parse.uses_netloc.extend(['ssh', 'git']) |
35 | 43 | ||
36 | class _Default(object): | 44 | class _Default(object): |
37 | """Project defaults within the manifest.""" | 45 | """Project defaults within the manifest.""" |
@@ -73,7 +81,7 @@ class _XmlRemote(object): | |||
73 | # ie, if manifestUrl is of the form <hostname:port> | 81 | # ie, if manifestUrl is of the form <hostname:port> |
74 | if manifestUrl.find(':') != manifestUrl.find('/') - 1: | 82 | if manifestUrl.find(':') != manifestUrl.find('/') - 1: |
75 | manifestUrl = 'gopher://' + manifestUrl | 83 | manifestUrl = 'gopher://' + manifestUrl |
76 | url = urlparse.urljoin(manifestUrl, url) | 84 | url = urllib.parse.urljoin(manifestUrl, url) |
77 | url = re.sub(r'^gopher://', '', url) | 85 | url = re.sub(r'^gopher://', '', url) |
78 | if p: | 86 | if p: |
79 | url = 'persistent-' + url | 87 | url = 'persistent-' + url |
@@ -82,8 +90,6 @@ class _XmlRemote(object): | |||
82 | def ToRemoteSpec(self, projectName): | 90 | def ToRemoteSpec(self, projectName): |
83 | url = self.resolvedFetchUrl.rstrip('/') + '/' + projectName | 91 | url = self.resolvedFetchUrl.rstrip('/') + '/' + projectName |
84 | remoteName = self.name | 92 | remoteName = self.name |
85 | if self.remoteAlias: | ||
86 | remoteName = self.remoteAlias | ||
87 | return RemoteSpec(remoteName, url, self.reviewUrl) | 93 | return RemoteSpec(remoteName, url, self.reviewUrl) |
88 | 94 | ||
89 | class XmlManifest(object): | 95 | class XmlManifest(object): |
@@ -164,10 +170,8 @@ class XmlManifest(object): | |||
164 | notice_element.appendChild(doc.createTextNode(indented_notice)) | 170 | notice_element.appendChild(doc.createTextNode(indented_notice)) |
165 | 171 | ||
166 | d = self.default | 172 | d = self.default |
167 | sort_remotes = list(self.remotes.keys()) | ||
168 | sort_remotes.sort() | ||
169 | 173 | ||
170 | for r in sort_remotes: | 174 | for r in sorted(self.remotes): |
171 | self._RemoteToXml(self.remotes[r], doc, root) | 175 | self._RemoteToXml(self.remotes[r], doc, root) |
172 | if self.remotes: | 176 | if self.remotes: |
173 | root.appendChild(doc.createTextNode('')) | 177 | root.appendChild(doc.createTextNode('')) |
@@ -259,12 +263,11 @@ class XmlManifest(object): | |||
259 | e.setAttribute('sync-s', 'true') | 263 | e.setAttribute('sync-s', 'true') |
260 | 264 | ||
261 | if p.subprojects: | 265 | if p.subprojects: |
262 | sort_projects = [subp.name for subp in p.subprojects] | 266 | sort_projects = list(sorted([subp.name for subp in p.subprojects])) |
263 | sort_projects.sort() | ||
264 | output_projects(p, e, sort_projects) | 267 | output_projects(p, e, sort_projects) |
265 | 268 | ||
266 | sort_projects = [key for key in self.projects.keys() | 269 | sort_projects = list(sorted([key for key, value in self.projects.items() |
267 | if not self.projects[key].parent] | 270 | if not value.parent])) |
268 | sort_projects.sort() | 271 | sort_projects.sort() |
269 | output_projects(None, root, sort_projects) | 272 | output_projects(None, root, sort_projects) |
270 | 273 | ||
@@ -388,9 +391,8 @@ class XmlManifest(object): | |||
388 | name = self._reqatt(node, 'name') | 391 | name = self._reqatt(node, 'name') |
389 | fp = os.path.join(include_root, name) | 392 | fp = os.path.join(include_root, name) |
390 | if not os.path.isfile(fp): | 393 | if not os.path.isfile(fp): |
391 | raise ManifestParseError, \ | 394 | raise ManifestParseError("include %s doesn't exist or isn't a file" |
392 | "include %s doesn't exist or isn't a file" % \ | 395 | % (name,)) |
393 | (name,) | ||
394 | try: | 396 | try: |
395 | nodes.extend(self._ParseManifestXml(fp, include_root)) | 397 | nodes.extend(self._ParseManifestXml(fp, include_root)) |
396 | # should isolate this to the exact exception, but that's | 398 | # should isolate this to the exact exception, but that's |
@@ -496,7 +498,7 @@ class XmlManifest(object): | |||
496 | name = None | 498 | name = None |
497 | m_url = m.GetRemote(m.remote.name).url | 499 | m_url = m.GetRemote(m.remote.name).url |
498 | if m_url.endswith('/.git'): | 500 | if m_url.endswith('/.git'): |
499 | raise ManifestParseError, 'refusing to mirror %s' % m_url | 501 | raise ManifestParseError('refusing to mirror %s' % m_url) |
500 | 502 | ||
501 | if self._default and self._default.remote: | 503 | if self._default and self._default.remote: |
502 | url = self._default.remote.resolvedFetchUrl | 504 | url = self._default.remote.resolvedFetchUrl |
@@ -590,7 +592,7 @@ class XmlManifest(object): | |||
590 | 592 | ||
591 | # Figure out minimum indentation, skipping the first line (the same line | 593 | # Figure out minimum indentation, skipping the first line (the same line |
592 | # as the <notice> tag)... | 594 | # as the <notice> tag)... |
593 | minIndent = sys.maxint | 595 | minIndent = sys.maxsize |
594 | lines = notice.splitlines() | 596 | lines = notice.splitlines() |
595 | for line in lines[1:]: | 597 | for line in lines[1:]: |
596 | lstrippedLine = line.lstrip() | 598 | lstrippedLine = line.lstrip() |
@@ -629,25 +631,22 @@ class XmlManifest(object): | |||
629 | if remote is None: | 631 | if remote is None: |
630 | remote = self._default.remote | 632 | remote = self._default.remote |
631 | if remote is None: | 633 | if remote is None: |
632 | raise ManifestParseError, \ | 634 | raise ManifestParseError("no remote for project %s within %s" % |
633 | "no remote for project %s within %s" % \ | 635 | (name, self.manifestFile)) |
634 | (name, self.manifestFile) | ||
635 | 636 | ||
636 | revisionExpr = node.getAttribute('revision') | 637 | revisionExpr = node.getAttribute('revision') |
637 | if not revisionExpr: | 638 | if not revisionExpr: |
638 | revisionExpr = self._default.revisionExpr | 639 | revisionExpr = self._default.revisionExpr |
639 | if not revisionExpr: | 640 | if not revisionExpr: |
640 | raise ManifestParseError, \ | 641 | raise ManifestParseError("no revision for project %s within %s" % |
641 | "no revision for project %s within %s" % \ | 642 | (name, self.manifestFile)) |
642 | (name, self.manifestFile) | ||
643 | 643 | ||
644 | path = node.getAttribute('path') | 644 | path = node.getAttribute('path') |
645 | if not path: | 645 | if not path: |
646 | path = name | 646 | path = name |
647 | if path.startswith('/'): | 647 | if path.startswith('/'): |
648 | raise ManifestParseError, \ | 648 | raise ManifestParseError("project %s path cannot be absolute in %s" % |
649 | "project %s path cannot be absolute in %s" % \ | 649 | (name, self.manifestFile)) |
650 | (name, self.manifestFile) | ||
651 | 650 | ||
652 | rebase = node.getAttribute('rebase') | 651 | rebase = node.getAttribute('rebase') |
653 | if not rebase: | 652 | if not rebase: |
@@ -667,6 +666,16 @@ class XmlManifest(object): | |||
667 | else: | 666 | else: |
668 | sync_s = sync_s.lower() in ("yes", "true", "1") | 667 | sync_s = sync_s.lower() in ("yes", "true", "1") |
669 | 668 | ||
669 | clone_depth = node.getAttribute('clone-depth') | ||
670 | if clone_depth: | ||
671 | try: | ||
672 | clone_depth = int(clone_depth) | ||
673 | if clone_depth <= 0: | ||
674 | raise ValueError() | ||
675 | except ValueError: | ||
676 | raise ManifestParseError('invalid clone-depth %s in %s' % | ||
677 | (clone_depth, self.manifestFile)) | ||
678 | |||
670 | upstream = node.getAttribute('upstream') | 679 | upstream = node.getAttribute('upstream') |
671 | 680 | ||
672 | groups = '' | 681 | groups = '' |
@@ -682,6 +691,10 @@ class XmlManifest(object): | |||
682 | default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath] | 691 | default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath] |
683 | groups.extend(set(default_groups).difference(groups)) | 692 | groups.extend(set(default_groups).difference(groups)) |
684 | 693 | ||
694 | if self.IsMirror and node.hasAttribute('force-path'): | ||
695 | if node.getAttribute('force-path').lower() in ("yes", "true", "1"): | ||
696 | gitdir = os.path.join(self.topdir, '%s.git' % path) | ||
697 | |||
685 | project = Project(manifest = self, | 698 | project = Project(manifest = self, |
686 | name = name, | 699 | name = name, |
687 | remote = remote.ToRemoteSpec(name), | 700 | remote = remote.ToRemoteSpec(name), |
@@ -694,6 +707,7 @@ class XmlManifest(object): | |||
694 | groups = groups, | 707 | groups = groups, |
695 | sync_c = sync_c, | 708 | sync_c = sync_c, |
696 | sync_s = sync_s, | 709 | sync_s = sync_s, |
710 | clone_depth = clone_depth, | ||
697 | upstream = upstream, | 711 | upstream = upstream, |
698 | parent = parent) | 712 | parent = parent) |
699 | 713 | ||
@@ -751,7 +765,8 @@ class XmlManifest(object): | |||
751 | except ManifestParseError: | 765 | except ManifestParseError: |
752 | keep = "true" | 766 | keep = "true" |
753 | if keep != "true" and keep != "false": | 767 | if keep != "true" and keep != "false": |
754 | raise ManifestParseError, "optional \"keep\" attribute must be \"true\" or \"false\"" | 768 | raise ManifestParseError('optional "keep" attribute must be ' |
769 | '"true" or "false"') | ||
755 | project.AddAnnotation(name, value, keep) | 770 | project.AddAnnotation(name, value, keep) |
756 | 771 | ||
757 | def _get_remote(self, node): | 772 | def _get_remote(self, node): |
@@ -761,9 +776,8 @@ class XmlManifest(object): | |||
761 | 776 | ||
762 | v = self._remotes.get(name) | 777 | v = self._remotes.get(name) |
763 | if not v: | 778 | if not v: |
764 | raise ManifestParseError, \ | 779 | raise ManifestParseError("remote %s not defined in %s" % |
765 | "remote %s not defined in %s" % \ | 780 | (name, self.manifestFile)) |
766 | (name, self.manifestFile) | ||
767 | return v | 781 | return v |
768 | 782 | ||
769 | def _reqatt(self, node, attname): | 783 | def _reqatt(self, node, attname): |
@@ -772,7 +786,6 @@ class XmlManifest(object): | |||
772 | """ | 786 | """ |
773 | v = node.getAttribute(attname) | 787 | v = node.getAttribute(attname) |
774 | if not v: | 788 | if not v: |
775 | raise ManifestParseError, \ | 789 | raise ManifestParseError("no %s in <%s> within %s" % |
776 | "no %s in <%s> within %s" % \ | 790 | (attname, node.nodeName, self.manifestFile)) |
777 | (attname, node.nodeName, self.manifestFile) | ||
778 | return v | 791 | return v |