summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/manifest-format.md21
-rw-r--r--manifest_xml.py14
-rw-r--r--tests/test_manifest_xml.py78
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
429Zero or more annotation elements may be specified as children of a 431Zero or more annotation elements may be specified as children of a
430project or remote element. Each element describes a name-value pair. 432project element, an extend-project element, or a remote element. Each
431For projects, this name-value pair will be exported into each project's 433element describes a name-value pair. For projects, this name-value pair
432environment during a 'forall' command, prefixed with `REPO__`. In addition, 434will be exported into each project's environment during a 'forall'
433there is an optional attribute "keep" which accepts the case insensitive values 435command, prefixed with `REPO__`. In addition, there is an optional
434"true" (default) or "false". This attribute determines whether or not the 436attribute "keep" which accepts the case insensitive values "true"
437(default) or "false". This attribute determines whether or not the
435annotation will be kept when exported with the manifest subcommand. 438annotation will be kept when exported with the manifest subcommand.
436 439
437### Element copyfile 440### Element copyfile
438 441
439Zero or more copyfile elements may be specified as children of a 442Zero or more copyfile elements may be specified as children of a
440project element. Each element describes a src-dest pair of files; 443project element, or an extend-project element. Each element describes a
441the "src" file will be copied to the "dest" place during `repo sync` 444src-dest pair of files; the "src" file will be copied to the "dest"
442command. 445place 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.
445Copying from paths outside of the project or to paths outside of the repo 448Copying 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
1218class NormalizeUrlTests(ManifestParseTestCase): 1296class NormalizeUrlTests(ManifestParseTestCase):
1219 """Tests for normalize_url() in manifest_xml.py""" 1297 """Tests for normalize_url() in manifest_xml.py"""