summaryrefslogtreecommitdiffstats
path: root/manifest_xml.py
diff options
context:
space:
mode:
Diffstat (limited to 'manifest_xml.py')
-rw-r--r--manifest_xml.py129
1 files changed, 103 insertions, 26 deletions
diff --git a/manifest_xml.py b/manifest_xml.py
index 122393cf..36f8ef87 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -40,6 +40,7 @@ class _Default(object):
40 remote = None 40 remote = None
41 sync_j = 1 41 sync_j = 1
42 sync_c = False 42 sync_c = False
43 sync_s = False
43 44
44class _XmlRemote(object): 45class _XmlRemote(object):
45 def __init__(self, 46 def __init__(self,
@@ -178,6 +179,9 @@ class XmlManifest(object):
178 if d.sync_c: 179 if d.sync_c:
179 have_default = True 180 have_default = True
180 e.setAttribute('sync-c', 'true') 181 e.setAttribute('sync-c', 'true')
182 if d.sync_s:
183 have_default = True
184 e.setAttribute('sync-s', 'true')
181 if have_default: 185 if have_default:
182 root.appendChild(e) 186 root.appendChild(e)
183 root.appendChild(doc.createTextNode('')) 187 root.appendChild(doc.createTextNode(''))
@@ -188,20 +192,25 @@ class XmlManifest(object):
188 root.appendChild(e) 192 root.appendChild(e)
189 root.appendChild(doc.createTextNode('')) 193 root.appendChild(doc.createTextNode(''))
190 194
191 sort_projects = list(self.projects.keys()) 195 def output_projects(parent, parent_node, projects):
192 sort_projects.sort() 196 for p in projects:
193 197 output_project(parent, parent_node, self.projects[p])
194 for p in sort_projects:
195 p = self.projects[p]
196 198
199 def output_project(parent, parent_node, p):
197 if not p.MatchesGroups(groups): 200 if not p.MatchesGroups(groups):
198 continue 201 return
202
203 name = p.name
204 relpath = p.relpath
205 if parent:
206 name = self._UnjoinName(parent.name, name)
207 relpath = self._UnjoinRelpath(parent.relpath, relpath)
199 208
200 e = doc.createElement('project') 209 e = doc.createElement('project')
201 root.appendChild(e) 210 parent_node.appendChild(e)
202 e.setAttribute('name', p.name) 211 e.setAttribute('name', name)
203 if p.relpath != p.name: 212 if relpath != name:
204 e.setAttribute('path', p.relpath) 213 e.setAttribute('path', relpath)
205 if not d.remote or p.remote.name != d.remote.name: 214 if not d.remote or p.remote.name != d.remote.name:
206 e.setAttribute('remote', p.remote.name) 215 e.setAttribute('remote', p.remote.name)
207 if peg_rev: 216 if peg_rev:
@@ -239,6 +248,19 @@ class XmlManifest(object):
239 if p.sync_c: 248 if p.sync_c:
240 e.setAttribute('sync-c', 'true') 249 e.setAttribute('sync-c', 'true')
241 250
251 if p.sync_s:
252 e.setAttribute('sync-s', 'true')
253
254 if p.subprojects:
255 sort_projects = [subp.name for subp in p.subprojects]
256 sort_projects.sort()
257 output_projects(p, e, sort_projects)
258
259 sort_projects = [key for key in self.projects.keys()
260 if not self.projects[key].parent]
261 sort_projects.sort()
262 output_projects(None, root, sort_projects)
263
242 if self._repo_hooks_project: 264 if self._repo_hooks_project:
243 root.appendChild(doc.createTextNode('')) 265 root.appendChild(doc.createTextNode(''))
244 e = doc.createElement('repo-hooks') 266 e = doc.createElement('repo-hooks')
@@ -409,14 +431,19 @@ class XmlManifest(object):
409 (self.manifestFile)) 431 (self.manifestFile))
410 self._manifest_server = url 432 self._manifest_server = url
411 433
434 def recursively_add_projects(project):
435 if self._projects.get(project.name):
436 raise ManifestParseError(
437 'duplicate project %s in %s' %
438 (project.name, self.manifestFile))
439 self._projects[project.name] = project
440 for subproject in project.subprojects:
441 recursively_add_projects(subproject)
442
412 for node in itertools.chain(*node_list): 443 for node in itertools.chain(*node_list):
413 if node.nodeName == 'project': 444 if node.nodeName == 'project':
414 project = self._ParseProject(node) 445 project = self._ParseProject(node)
415 if self._projects.get(project.name): 446 recursively_add_projects(project)
416 raise ManifestParseError(
417 'duplicate project %s in %s' %
418 (project.name, self.manifestFile))
419 self._projects[project.name] = project
420 if node.nodeName == 'repo-hooks': 447 if node.nodeName == 'repo-hooks':
421 # Get the name of the project and the (space-separated) list of enabled. 448 # Get the name of the project and the (space-separated) list of enabled.
422 repo_hooks_project = self._reqatt(node, 'in-project') 449 repo_hooks_project = self._reqatt(node, 'in-project')
@@ -524,6 +551,12 @@ class XmlManifest(object):
524 d.sync_c = False 551 d.sync_c = False
525 else: 552 else:
526 d.sync_c = sync_c.lower() in ("yes", "true", "1") 553 d.sync_c = sync_c.lower() in ("yes", "true", "1")
554
555 sync_s = node.getAttribute('sync-s')
556 if not sync_s:
557 d.sync_s = False
558 else:
559 d.sync_s = sync_s.lower() in ("yes", "true", "1")
527 return d 560 return d
528 561
529 def _ParseNotice(self, node): 562 def _ParseNotice(self, node):
@@ -565,11 +598,19 @@ class XmlManifest(object):
565 598
566 return '\n'.join(cleanLines) 599 return '\n'.join(cleanLines)
567 600
568 def _ParseProject(self, node): 601 def _JoinName(self, parent_name, name):
602 return os.path.join(parent_name, name)
603
604 def _UnjoinName(self, parent_name, name):
605 return os.path.relpath(name, parent_name)
606
607 def _ParseProject(self, node, parent = None):
569 """ 608 """
570 reads a <project> element from the manifest file 609 reads a <project> element from the manifest file
571 """ 610 """
572 name = self._reqatt(node, 'name') 611 name = self._reqatt(node, 'name')
612 if parent:
613 name = self._JoinName(parent.name, name)
573 614
574 remote = self._get_remote(node) 615 remote = self._get_remote(node)
575 if remote is None: 616 if remote is None:
@@ -607,6 +648,12 @@ class XmlManifest(object):
607 else: 648 else:
608 sync_c = sync_c.lower() in ("yes", "true", "1") 649 sync_c = sync_c.lower() in ("yes", "true", "1")
609 650
651 sync_s = node.getAttribute('sync-s')
652 if not sync_s:
653 sync_s = self._default.sync_s
654 else:
655 sync_s = sync_s.lower() in ("yes", "true", "1")
656
610 upstream = node.getAttribute('upstream') 657 upstream = node.getAttribute('upstream')
611 658
612 groups = '' 659 groups = ''
@@ -614,37 +661,67 @@ class XmlManifest(object):
614 groups = node.getAttribute('groups') 661 groups = node.getAttribute('groups')
615 groups = [x for x in re.split(r'[,\s]+', groups) if x] 662 groups = [x for x in re.split(r'[,\s]+', groups) if x]
616 663
617 default_groups = ['all', 'name:%s' % name, 'path:%s' % path] 664 if parent is None:
618 groups.extend(set(default_groups).difference(groups)) 665 relpath, worktree, gitdir = self.GetProjectPaths(name, path)
619
620 if self.IsMirror:
621 worktree = None
622 gitdir = os.path.join(self.topdir, '%s.git' % name)
623 else: 666 else:
624 worktree = os.path.join(self.topdir, path).replace('\\', '/') 667 relpath, worktree, gitdir = self.GetSubprojectPaths(parent, path)
625 gitdir = os.path.join(self.repodir, 'projects/%s.git' % path) 668
669 default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath]
670 groups.extend(set(default_groups).difference(groups))
626 671
627 project = Project(manifest = self, 672 project = Project(manifest = self,
628 name = name, 673 name = name,
629 remote = remote.ToRemoteSpec(name), 674 remote = remote.ToRemoteSpec(name),
630 gitdir = gitdir, 675 gitdir = gitdir,
631 worktree = worktree, 676 worktree = worktree,
632 relpath = path, 677 relpath = relpath,
633 revisionExpr = revisionExpr, 678 revisionExpr = revisionExpr,
634 revisionId = None, 679 revisionId = None,
635 rebase = rebase, 680 rebase = rebase,
636 groups = groups, 681 groups = groups,
637 sync_c = sync_c, 682 sync_c = sync_c,
638 upstream = upstream) 683 sync_s = sync_s,
684 upstream = upstream,
685 parent = parent)
639 686
640 for n in node.childNodes: 687 for n in node.childNodes:
641 if n.nodeName == 'copyfile': 688 if n.nodeName == 'copyfile':
642 self._ParseCopyFile(project, n) 689 self._ParseCopyFile(project, n)
643 if n.nodeName == 'annotation': 690 if n.nodeName == 'annotation':
644 self._ParseAnnotation(project, n) 691 self._ParseAnnotation(project, n)
692 if n.nodeName == 'project':
693 project.subprojects.append(self._ParseProject(n, parent = project))
645 694
646 return project 695 return project
647 696
697 def GetProjectPaths(self, name, path):
698 relpath = path
699 if self.IsMirror:
700 worktree = None
701 gitdir = os.path.join(self.topdir, '%s.git' % name)
702 else:
703 worktree = os.path.join(self.topdir, path).replace('\\', '/')
704 gitdir = os.path.join(self.repodir, 'projects', '%s.git' % path)
705 return relpath, worktree, gitdir
706
707 def GetSubprojectName(self, parent, submodule_path):
708 return os.path.join(parent.name, submodule_path)
709
710 def _JoinRelpath(self, parent_relpath, relpath):
711 return os.path.join(parent_relpath, relpath)
712
713 def _UnjoinRelpath(self, parent_relpath, relpath):
714 return os.path.relpath(relpath, parent_relpath)
715
716 def GetSubprojectPaths(self, parent, path):
717 relpath = self._JoinRelpath(parent.relpath, path)
718 gitdir = os.path.join(parent.gitdir, 'subprojects', '%s.git' % path)
719 if self.IsMirror:
720 worktree = None
721 else:
722 worktree = os.path.join(parent.worktree, path).replace('\\', '/')
723 return relpath, worktree, gitdir
724
648 def _ParseCopyFile(self, project, node): 725 def _ParseCopyFile(self, project, node):
649 src = self._reqatt(node, 'src') 726 src = self._reqatt(node, 'src')
650 dest = self._reqatt(node, 'dest') 727 dest = self._reqatt(node, 'dest')