summaryrefslogtreecommitdiffstats
path: root/manifest_xml.py
diff options
context:
space:
mode:
Diffstat (limited to 'manifest_xml.py')
-rw-r--r--manifest_xml.py81
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
18import os 18import os
19import re 19import re
20import sys 20import sys
21import urlparse 21try:
22 # For python3
23 import urllib.parse
24except ImportError:
25 # For python2
26 import imp
27 import urlparse
28 urllib = imp.new_module('urllib')
29 urllib.parse = urlparse
22import xml.dom.minidom 30import xml.dom.minidom
23 31
24from git_config import GitConfig 32from git_config import GitConfig
@@ -30,8 +38,8 @@ MANIFEST_FILE_NAME = 'manifest.xml'
30LOCAL_MANIFEST_NAME = 'local_manifest.xml' 38LOCAL_MANIFEST_NAME = 'local_manifest.xml'
31LOCAL_MANIFESTS_DIR_NAME = 'local_manifests' 39LOCAL_MANIFESTS_DIR_NAME = 'local_manifests'
32 40
33urlparse.uses_relative.extend(['ssh', 'git']) 41urllib.parse.uses_relative.extend(['ssh', 'git'])
34urlparse.uses_netloc.extend(['ssh', 'git']) 42urllib.parse.uses_netloc.extend(['ssh', 'git'])
35 43
36class _Default(object): 44class _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
89class XmlManifest(object): 95class 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