diff options
| author | Peter Kjellerstedt <pkj@axis.com> | 2025-10-16 20:29:28 +0200 |
|---|---|---|
| committer | Gavin Mak <gavinmak@google.com> | 2025-10-27 11:38:07 -0700 |
| commit | 4ab2284a945d82b017c6646fca57c5973ffdabaf (patch) | |
| tree | b70f27fe505573b038c62c7eb98ef4a695b9e30b | |
| parent | 1afe96a7e997ce7748f066b206a85ac648f7a87c (diff) | |
| download | git-repo-4ab2284a945d82b017c6646fca57c5973ffdabaf.tar.gz | |
manifest: Make extend-project support copyfile, linkfile and annotationmain
This allows an existing project to be extended by these elements.
Change-Id: I6826e518f39ca86485301491639101943b7e2ae0
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/519781
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
| -rw-r--r-- | docs/manifest-format.md | 21 | ||||
| -rw-r--r-- | manifest_xml.py | 14 | ||||
| -rw-r--r-- | tests/test_manifest_xml.py | 78 |
3 files changed, 101 insertions, 12 deletions
diff --git a/docs/manifest-format.md b/docs/manifest-format.md index 71fa04c5..06d370a3 100644 --- a/docs/manifest-format.md +++ b/docs/manifest-format.md | |||
| @@ -98,7 +98,9 @@ following DTD: | |||
| 98 | <!ATTLIST linkfile src CDATA #REQUIRED> | 98 | <!ATTLIST linkfile src CDATA #REQUIRED> |
| 99 | <!ATTLIST linkfile dest CDATA #REQUIRED> | 99 | <!ATTLIST linkfile dest CDATA #REQUIRED> |
| 100 | 100 | ||
| 101 | <!ELEMENT extend-project EMPTY> | 101 | <!ELEMENT extend-project (annotation*, |
| 102 | copyfile*, | ||
| 103 | linkfile*)> | ||
| 102 | <!ATTLIST extend-project name CDATA #REQUIRED> | 104 | <!ATTLIST extend-project name CDATA #REQUIRED> |
| 103 | <!ATTLIST extend-project path CDATA #IMPLIED> | 105 | <!ATTLIST extend-project path CDATA #IMPLIED> |
| 104 | <!ATTLIST extend-project dest-path CDATA #IMPLIED> | 106 | <!ATTLIST extend-project dest-path CDATA #IMPLIED> |
| @@ -427,19 +429,20 @@ Same syntax as the corresponding element of `project`. | |||
| 427 | ### Element annotation | 429 | ### Element annotation |
| 428 | 430 | ||
| 429 | Zero or more annotation elements may be specified as children of a | 431 | Zero or more annotation elements may be specified as children of a |
| 430 | project or remote element. Each element describes a name-value pair. | 432 | project element, an extend-project element, or a remote element. Each |
| 431 | For projects, this name-value pair will be exported into each project's | 433 | element describes a name-value pair. For projects, this name-value pair |
| 432 | environment during a 'forall' command, prefixed with `REPO__`. In addition, | 434 | will be exported into each project's environment during a 'forall' |
| 433 | there is an optional attribute "keep" which accepts the case insensitive values | 435 | command, prefixed with `REPO__`. In addition, there is an optional |
| 434 | "true" (default) or "false". This attribute determines whether or not the | 436 | attribute "keep" which accepts the case insensitive values "true" |
| 437 | (default) or "false". This attribute determines whether or not the | ||
| 435 | annotation will be kept when exported with the manifest subcommand. | 438 | annotation will be kept when exported with the manifest subcommand. |
| 436 | 439 | ||
| 437 | ### Element copyfile | 440 | ### Element copyfile |
| 438 | 441 | ||
| 439 | Zero or more copyfile elements may be specified as children of a | 442 | Zero or more copyfile elements may be specified as children of a |
| 440 | project element. Each element describes a src-dest pair of files; | 443 | project element, or an extend-project element. Each element describes a |
| 441 | the "src" file will be copied to the "dest" place during `repo sync` | 444 | src-dest pair of files; the "src" file will be copied to the "dest" |
| 442 | command. | 445 | place during `repo sync` command. |
| 443 | 446 | ||
| 444 | "src" is project relative, "dest" is relative to the top of the tree. | 447 | "src" is project relative, "dest" is relative to the top of the tree. |
| 445 | Copying from paths outside of the project or to paths outside of the repo | 448 | Copying from paths outside of the project or to paths outside of the repo |
diff --git a/manifest_xml.py b/manifest_xml.py index 30c5b590..5e0b53b9 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
| @@ -1509,6 +1509,14 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
| 1509 | p.UpdatePaths(relpath, worktree, gitdir, objdir) | 1509 | p.UpdatePaths(relpath, worktree, gitdir, objdir) |
| 1510 | self._paths[p.relpath] = p | 1510 | self._paths[p.relpath] = p |
| 1511 | 1511 | ||
| 1512 | for n in node.childNodes: | ||
| 1513 | if n.nodeName == "copyfile": | ||
| 1514 | self._ParseCopyFile(p, n) | ||
| 1515 | elif n.nodeName == "linkfile": | ||
| 1516 | self._ParseLinkFile(p, n) | ||
| 1517 | elif n.nodeName == "annotation": | ||
| 1518 | self._ParseAnnotation(p, n) | ||
| 1519 | |||
| 1512 | if node.nodeName == "repo-hooks": | 1520 | if node.nodeName == "repo-hooks": |
| 1513 | # Only one project can be the hooks project | 1521 | # Only one project can be the hooks project |
| 1514 | if repo_hooks_project is not None: | 1522 | if repo_hooks_project is not None: |
| @@ -1963,11 +1971,11 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
| 1963 | for n in node.childNodes: | 1971 | for n in node.childNodes: |
| 1964 | if n.nodeName == "copyfile": | 1972 | if n.nodeName == "copyfile": |
| 1965 | self._ParseCopyFile(project, n) | 1973 | self._ParseCopyFile(project, n) |
| 1966 | if n.nodeName == "linkfile": | 1974 | elif n.nodeName == "linkfile": |
| 1967 | self._ParseLinkFile(project, n) | 1975 | self._ParseLinkFile(project, n) |
| 1968 | if n.nodeName == "annotation": | 1976 | elif n.nodeName == "annotation": |
| 1969 | self._ParseAnnotation(project, n) | 1977 | self._ParseAnnotation(project, n) |
| 1970 | if n.nodeName == "project": | 1978 | elif n.nodeName == "project": |
| 1971 | project.subprojects.append( | 1979 | project.subprojects.append( |
| 1972 | self._ParseProject(n, parent=project) | 1980 | self._ParseProject(n, parent=project) |
| 1973 | ) | 1981 | ) |
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py index ebc0ce58..07939e16 100644 --- a/tests/test_manifest_xml.py +++ b/tests/test_manifest_xml.py | |||
| @@ -1214,6 +1214,84 @@ class ExtendProjectElementTests(ManifestParseTestCase): | |||
| 1214 | self.assertEqual(len(manifest.projects), 1) | 1214 | self.assertEqual(len(manifest.projects), 1) |
| 1215 | self.assertEqual(manifest.projects[0].upstream, "bar") | 1215 | self.assertEqual(manifest.projects[0].upstream, "bar") |
| 1216 | 1216 | ||
| 1217 | def test_extend_project_copyfiles(self): | ||
| 1218 | manifest = self.getXmlManifest( | ||
| 1219 | """ | ||
| 1220 | <manifest> | ||
| 1221 | <remote name="default-remote" fetch="http://localhost" /> | ||
| 1222 | <default remote="default-remote" revision="refs/heads/main" /> | ||
| 1223 | <project name="myproject" /> | ||
| 1224 | <extend-project name="myproject"> | ||
| 1225 | <copyfile src="foo" dest="bar" /> | ||
| 1226 | </extend-project> | ||
| 1227 | </manifest> | ||
| 1228 | """ | ||
| 1229 | ) | ||
| 1230 | self.assertEqual(manifest.projects[0].copyfiles[0].src, "foo") | ||
| 1231 | self.assertEqual(manifest.projects[0].copyfiles[0].dest, "bar") | ||
| 1232 | self.assertEqual( | ||
| 1233 | sort_attributes(manifest.ToXml().toxml()), | ||
| 1234 | '<?xml version="1.0" ?><manifest>' | ||
| 1235 | '<remote fetch="http://localhost" name="default-remote"/>' | ||
| 1236 | '<default remote="default-remote" revision="refs/heads/main"/>' | ||
| 1237 | '<project name="myproject">' | ||
| 1238 | '<copyfile dest="bar" src="foo"/>' | ||
| 1239 | "</project>" | ||
| 1240 | "</manifest>", | ||
| 1241 | ) | ||
| 1242 | |||
| 1243 | def test_extend_project_linkfiles(self): | ||
| 1244 | manifest = self.getXmlManifest( | ||
| 1245 | """ | ||
| 1246 | <manifest> | ||
| 1247 | <remote name="default-remote" fetch="http://localhost" /> | ||
| 1248 | <default remote="default-remote" revision="refs/heads/main" /> | ||
| 1249 | <project name="myproject" /> | ||
| 1250 | <extend-project name="myproject"> | ||
| 1251 | <linkfile src="foo" dest="bar" /> | ||
| 1252 | </extend-project> | ||
| 1253 | </manifest> | ||
| 1254 | """ | ||
| 1255 | ) | ||
| 1256 | self.assertEqual(manifest.projects[0].linkfiles[0].src, "foo") | ||
| 1257 | self.assertEqual(manifest.projects[0].linkfiles[0].dest, "bar") | ||
| 1258 | self.assertEqual( | ||
| 1259 | sort_attributes(manifest.ToXml().toxml()), | ||
| 1260 | '<?xml version="1.0" ?><manifest>' | ||
| 1261 | '<remote fetch="http://localhost" name="default-remote"/>' | ||
| 1262 | '<default remote="default-remote" revision="refs/heads/main"/>' | ||
| 1263 | '<project name="myproject">' | ||
| 1264 | '<linkfile dest="bar" src="foo"/>' | ||
| 1265 | "</project>" | ||
| 1266 | "</manifest>", | ||
| 1267 | ) | ||
| 1268 | |||
| 1269 | def test_extend_project_annotations(self): | ||
| 1270 | manifest = self.getXmlManifest( | ||
| 1271 | """ | ||
| 1272 | <manifest> | ||
| 1273 | <remote name="default-remote" fetch="http://localhost" /> | ||
| 1274 | <default remote="default-remote" revision="refs/heads/main" /> | ||
| 1275 | <project name="myproject" /> | ||
| 1276 | <extend-project name="myproject"> | ||
| 1277 | <annotation name="foo" value="bar" /> | ||
| 1278 | </extend-project> | ||
| 1279 | </manifest> | ||
| 1280 | """ | ||
| 1281 | ) | ||
| 1282 | self.assertEqual(manifest.projects[0].annotations[0].name, "foo") | ||
| 1283 | self.assertEqual(manifest.projects[0].annotations[0].value, "bar") | ||
| 1284 | self.assertEqual( | ||
| 1285 | sort_attributes(manifest.ToXml().toxml()), | ||
| 1286 | '<?xml version="1.0" ?><manifest>' | ||
| 1287 | '<remote fetch="http://localhost" name="default-remote"/>' | ||
| 1288 | '<default remote="default-remote" revision="refs/heads/main"/>' | ||
| 1289 | '<project name="myproject">' | ||
| 1290 | '<annotation name="foo" value="bar"/>' | ||
| 1291 | "</project>" | ||
| 1292 | "</manifest>", | ||
| 1293 | ) | ||
| 1294 | |||
| 1217 | 1295 | ||
| 1218 | class NormalizeUrlTests(ManifestParseTestCase): | 1296 | class NormalizeUrlTests(ManifestParseTestCase): |
| 1219 | """Tests for normalize_url() in manifest_xml.py""" | 1297 | """Tests for normalize_url() in manifest_xml.py""" |
