Merge ~cjwatson/git-build-recipe:nest-part into git-build-recipe:master

Proposed by Colin Watson
Status: Merged
Merged at revision: d3ce4262671b366b44ec1b59fbc8527378e60ade
Proposed branch: ~cjwatson/git-build-recipe:nest-part
Merge into: git-build-recipe:master
Diff against target: 183 lines (+36/-23)
3 files modified
debian/changelog (+6/-0)
gitbuildrecipe/recipe.py (+19/-5)
gitbuildrecipe/tests/test_recipe.py (+11/-18)
Reviewer Review Type Date Requested Status
Launchpad code reviewers Pending
Review via email: mp+283756@code.launchpad.net

Commit message

Implement nest-part (LP: #1537579).

Description of the change

Implement nest-part (LP: #1537579). Not too difficult once I finally figured out the right sequence of filter-branch and subtree operations needed.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 0c8e1bd..8a94f44 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
1git-build-recipe (0.3) UNRELEASED; urgency=medium
2
3 * Implement nest-part (LP: #1537579).
4
5 -- Colin Watson <cjwatson@ubuntu.com> Mon, 25 Jan 2016 02:51:00 +0000
6
1git-build-recipe (0.2.1) trusty; urgency=medium7git-build-recipe (0.2.1) trusty; urgency=medium
28
3 * Configure "lp:" as shorthand for "https://git.launchpad.net/".9 * Configure "lp:" as shorthand for "https://git.launchpad.net/".
diff --git a/gitbuildrecipe/recipe.py b/gitbuildrecipe/recipe.py
index 1d0faa3..a961997 100644
--- a/gitbuildrecipe/recipe.py
+++ b/gitbuildrecipe/recipe.py
@@ -385,14 +385,28 @@ def nest_part_branch(child_branch, target_path, subpath, target_subdir=None):
385 target_subdir = os.path.basename(subpath)385 target_subdir = os.path.basename(subpath)
386 # XXX should handle updating as well386 # XXX should handle updating as well
387 assert not os.path.exists(target_subdir)387 assert not os.path.exists(target_subdir)
388 target_subdir_parent = os.path.dirname(target_subdir)
389 if target_subdir_parent:
390 target_subdir_parent_path = os.path.join(
391 target_path, target_subdir_parent)
392 if not os.path.exists(target_subdir_parent_path):
393 os.makedirs(target_subdir_parent_path)
388 child_branch.path = target_path394 child_branch.path = target_path
389 ensure_remote(child_branch)395 ensure_remote(child_branch)
390 child_branch.resolve_commit()396 child_branch.resolve_commit()
391 subtree_commit = child_branch.git_output(397 child_branch.git_call(
392 "subtree", "split", "-P", subpath, child_branch.commit)398 "branch", "-q", "-f", "tmp-gbr-nest-part", child_branch.commit)
393 child_branch.path = os.path.join(target_path, target_subdir)399 if subpath != ".":
394 git_clone(".", child_branch.path)400 child_branch.git_call(
395 child_branch.git_call("checkout", subtree_commit)401 "filter-branch", "-f", "--original", "refs/git-build-recipe",
402 "--subdirectory-filter", subpath, "tmp-gbr-nest-part")
403 for original in child_branch.git_output(
404 "for-each-ref", "--format=%(refname)",
405 "refs/git-build-recipe").splitlines():
406 child_branch.git_call("update-ref", "-d", original)
407 child_branch.git_output(
408 "subtree", "add", "-q", "-P", target_subdir, "tmp-gbr-nest-part")
409 child_branch.git_call("branch", "-q", "-D", "tmp-gbr-nest-part")
396410
397411
398def _build_inner_tree(base_branch, target_path):412def _build_inner_tree(base_branch, target_path):
diff --git a/gitbuildrecipe/tests/test_recipe.py b/gitbuildrecipe/tests/test_recipe.py
index 298eea7..337b741 100644
--- a/gitbuildrecipe/tests/test_recipe.py
+++ b/gitbuildrecipe/tests/test_recipe.py
@@ -14,10 +14,10 @@
1414
15import os15import os
16import shutil16import shutil
17import unittest
1817
19from testtools.matchers import (18from testtools.matchers import (
20 FileContains,19 FileContains,
20 Not,
21 PathExists,21 PathExists,
22 )22 )
2323
@@ -287,7 +287,6 @@ class RecipeParserTests(GitTestCase):
287 self.assertEqual(None, location)287 self.assertEqual(None, location)
288 self.check_recipe_branch(child_branch, "bar", "http://bar.org")288 self.check_recipe_branch(child_branch, "bar", "http://bar.org")
289289
290 @unittest.skip("nest_part broken")
291 def test_builds_recipe_with_nest_part(self):290 def test_builds_recipe_with_nest_part(self):
292 base_branch = self.get_recipe(self.basic_header_and_branch291 base_branch = self.get_recipe(self.basic_header_and_branch
293 + "nest-part bar http://bar.org some/path")292 + "nest-part bar http://bar.org some/path")
@@ -300,7 +299,6 @@ class RecipeParserTests(GitTestCase):
300 self.assertEqual("some/path", instruction.subpath)299 self.assertEqual("some/path", instruction.subpath)
301 self.assertEqual(None, instruction.target_subdir)300 self.assertEqual(None, instruction.target_subdir)
302301
303 @unittest.skip("nest_part broken")
304 def test_builds_recipe_with_nest_part_subdir(self):302 def test_builds_recipe_with_nest_part_subdir(self):
305 base_branch = self.get_recipe(self.basic_header_and_branch303 base_branch = self.get_recipe(self.basic_header_and_branch
306 + "nest-part bar http://bar.org some/path target-subdir")304 + "nest-part bar http://bar.org some/path target-subdir")
@@ -313,7 +311,6 @@ class RecipeParserTests(GitTestCase):
313 self.assertEqual("some/path", instruction.subpath)311 self.assertEqual("some/path", instruction.subpath)
314 self.assertEqual("target-subdir", instruction.target_subdir)312 self.assertEqual("target-subdir", instruction.target_subdir)
315313
316 @unittest.skip("nest_part broken")
317 def test_builds_recipe_with_nest_part_subdir_and_revspec(self):314 def test_builds_recipe_with_nest_part_subdir_and_revspec(self):
318 base_branch = self.get_recipe(self.basic_header_and_branch315 base_branch = self.get_recipe(self.basic_header_and_branch
319 + "nest-part bar http://bar.org some/path target-subdir 1234")316 + "nest-part bar http://bar.org some/path target-subdir 1234")
@@ -631,7 +628,6 @@ class BuildTreeTests(GitTestCase):
631 self.assertEqual(source1_commit, base_branch.commit)628 self.assertEqual(source1_commit, base_branch.commit)
632 self.assertEqual(source2_commit, merged_branch.commit)629 self.assertEqual(source2_commit, merged_branch.commit)
633630
634 @unittest.skip("nest_part broken")
635 def test_build_tree_implicit_dir(self):631 def test_build_tree_implicit_dir(self):
636 # Branches nested into non-existent directories trigger creation of632 # Branches nested into non-existent directories trigger creation of
637 # those directories.633 # those directories.
@@ -659,7 +655,6 @@ class BuildTreeTests(GitTestCase):
659 "target/moreimplicit/another/c/yetanotherfile",655 "target/moreimplicit/another/c/yetanotherfile",
660 FileContains("rugby"))656 FileContains("rugby"))
661657
662 @unittest.skip("nest_part broken")
663 def test_build_tree_nest_part(self):658 def test_build_tree_nest_part(self):
664 """A recipe can specify a merge of just part of an unrelated tree."""659 """A recipe can specify a merge of just part of an unrelated tree."""
665 source1 = self.make_source_branch("source1")660 source1 = self.make_source_branch("source1")
@@ -667,7 +662,9 @@ class BuildTreeTests(GitTestCase):
667 source1_commit = source1.last_revision()662 source1_commit = source1.last_revision()
668 # Add 'b' to source2.663 # Add 'b' to source2.
669 source2.build_tree_contents([664 source2.build_tree_contents([
670 ("b", "new file"), ("not-b", "other file")])665 ("b/",), ("b/a", "new file"),
666 ("not-b/",), ("not-b/a", "other file"),
667 ])
671 source2.add(["b", "not-b"])668 source2.add(["b", "not-b"])
672 source2_commit = source2.commit("two")669 source2_commit = source2.commit("two")
673 base_branch = BaseRecipeBranch("source1", "1", 0.2)670 base_branch = BaseRecipeBranch("source1", "1", 0.2)
@@ -675,15 +672,13 @@ class BuildTreeTests(GitTestCase):
675 # Merge just 'b' from source2; 'a' is untouched.672 # Merge just 'b' from source2; 'a' is untouched.
676 base_branch.nest_part_branch(merged_branch, "b")673 base_branch.nest_part_branch(merged_branch, "b")
677 build_tree(base_branch, "target")674 build_tree(base_branch, "target")
678 file_id = source1.path2id("a")
679 self.assertThat(675 self.assertThat(
680 "target/a", FileContains(source1.get_file_text(file_id)))676 "target/a", FileContains(source1._git_output("show", "HEAD:a")))
681 self.assertThat("target/b", FileContains("new file"))677 self.assertThat("target/b/a", FileContains("new file"))
682 self.assertNotInWorkingTree("not-b", "target")678 self.assertThat("target/not-b", Not(PathExists()))
683 self.assertEqual(source1_commit, base_branch.commit)679 self.assertEqual(source1_commit, base_branch.commit)
684 self.assertEqual(source2_commit, merged_branch.commit)680 self.assertEqual(source2_commit, merged_branch.commit)
685681
686 @unittest.skip("nest_part broken")
687 def test_build_tree_nest_part_explicit_target(self):682 def test_build_tree_nest_part_explicit_target(self):
688 """A recipe can specify a merge of just part of an unrelated tree into683 """A recipe can specify a merge of just part of an unrelated tree into
689 a specific subdirectory of the target tree.684 a specific subdirectory of the target tree.
@@ -696,7 +691,8 @@ class BuildTreeTests(GitTestCase):
696 source1_commit = source1.last_revision()691 source1_commit = source1.last_revision()
697 # Add 'b' to source2.692 # Add 'b' to source2.
698 source2.build_tree_contents([693 source2.build_tree_contents([
699 ("b", "new file"), ("not-b", "other file")])694 ("b/",), ("b/a", "new file"),
695 ("not-b/",), ("not-b/a", "other file")])
700 source2.add(["b", "not-b"])696 source2.add(["b", "not-b"])
701 source2_commit = source2.commit("two")697 source2_commit = source2.commit("two")
702 base_branch = BaseRecipeBranch("source1", "1", 0.2)698 base_branch = BaseRecipeBranch("source1", "1", 0.2)
@@ -704,8 +700,8 @@ class BuildTreeTests(GitTestCase):
704 # Merge just 'b' from source2; 'a' is untouched.700 # Merge just 'b' from source2; 'a' is untouched.
705 base_branch.nest_part_branch(merged_branch, "b", "dir/b")701 base_branch.nest_part_branch(merged_branch, "b", "dir/b")
706 build_tree(base_branch, "target")702 build_tree(base_branch, "target")
707 self.assertThat("target/dir/b", FileContains("new file"))703 self.assertThat("target/dir/b/a", FileContains("new file"))
708 self.assertNotInWorkingTree("dir/not-b", "target")704 self.assertThat("target/dir/not-b", Not(PathExists()))
709 self.assertEqual(source1_commit, base_branch.commit)705 self.assertEqual(source1_commit, base_branch.commit)
710 self.assertEqual(source2_commit, merged_branch.commit)706 self.assertEqual(source2_commit, merged_branch.commit)
711707
@@ -1006,7 +1002,6 @@ class StringifyTests(GitTestCase):
1006 base_branch.nest_branch(".", nested_branch1)1002 base_branch.nest_branch(".", nested_branch1)
1007 self.assertRaises(InstructionParseError, str, base_branch)1003 self.assertRaises(InstructionParseError, str, base_branch)
10081004
1009 @unittest.skip("nest_part broken")
1010 def test_with_nest_part(self):1005 def test_with_nest_part(self):
1011 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1006 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1012 base_branch.commit = "base_revid"1007 base_branch.commit = "base_revid"
@@ -1019,7 +1014,6 @@ class StringifyTests(GitTestCase):
1019 "nest-part nested1 nested1_url foo bar tag:foo\n",1014 "nest-part nested1 nested1_url foo bar tag:foo\n",
1020 manifest)1015 manifest)
10211016
1022 @unittest.skip("nest_part broken")
1023 def test_with_nest_part_with_no_target_dir(self):1017 def test_with_nest_part_with_no_target_dir(self):
1024 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1018 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1025 base_branch.commit = "base_revid"1019 base_branch.commit = "base_revid"
@@ -1032,7 +1026,6 @@ class StringifyTests(GitTestCase):
1032 "nest-part nested1 nested1_url foo foo tag:foo\n",1026 "nest-part nested1 nested1_url foo foo tag:foo\n",
1033 manifest)1027 manifest)
10341028
1035 @unittest.skip("nest_part broken")
1036 def test_with_nest_part_with_no_target_dir_no_revspec(self):1029 def test_with_nest_part_with_no_target_dir_no_revspec(self):
1037 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1030 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1038 base_branch.commit = "base_revid"1031 base_branch.commit = "base_revid"

Subscribers

People subscribed via source and target branches