From be71c2f80fa115e8256211fd0e3116d93cfae93e Mon Sep 17 00:00:00 2001 From: Fredrik de Groot Date: Wed, 31 May 2023 16:56:34 +0200 Subject: manifest: enable remove-project using path A something.xml that gets included by two different files, that both remove and add same shared project to two different locations, would not work prior to this change. Reason is that remove killed all name keys, even though reuse of same repo in different locations is allowed. Solve by adding optional attrib path to and tweak remove-project. Behaves as before without path, and deletes more selectively when remove path is supplied. As secondary feature, a project can now also be removed by only using path, assuming a matching project name can be found. Change-Id: I502d9f949f5d858ddc1503846b170473f76dc8e2 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/375694 Tested-by: Fredrik de Groot Reviewed-by: Mike Frysinger --- manifest_xml.py | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'manifest_xml.py') diff --git a/manifest_xml.py b/manifest_xml.py index 555bf736..73be1b6e 100644 --- a/manifest_xml.py +++ b/manifest_xml.py @@ -1535,22 +1535,45 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md self._contactinfo = ContactInfo(bugurl) if node.nodeName == "remove-project": - name = self._reqatt(node, "name") + name = node.getAttribute("name") + path = node.getAttribute("path") - if name in self._projects: - for p in self._projects[name]: - del self._paths[p.relpath] - del self._projects[name] - - # If the manifest removes the hooks project, treat it as if - # it deleted - # the repo-hooks element too. - if repo_hooks_project == name: - repo_hooks_project = None - elif not XmlBool(node, "optional", False): + # Name or path needed. + if not name and not path: + raise ManifestParseError( + "remove-project must have name and/or path" + ) + + removed_project = "" + + # Find and remove projects based on name and/or path. + for projname, projects in list(self._projects.items()): + for p in projects: + if name == projname and not path: + del self._paths[p.relpath] + if not removed_project: + del self._projects[name] + removed_project = name + elif path == p.relpath and ( + name == projname or not name + ): + self._projects[projname].remove(p) + del self._paths[p.relpath] + removed_project = p.name + + # If the manifest removes the hooks project, treat it as if + # it deleted the repo-hooks element too. + if ( + removed_project + and removed_project not in self._projects + and repo_hooks_project == removed_project + ): + repo_hooks_project = None + + if not removed_project and not XmlBool(node, "optional", False): raise ManifestParseError( "remove-project element specifies non-existent " - "project: %s" % name + "project: %s" % node.toxml() ) # Store repo hooks project information. -- cgit v1.2.3-54-g00ecf