Merge ~cjwatson/launchpad-buildd:brz-builder into launchpad-buildd:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 89ee2a61cbbafaf791d809238674523028add63b
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad-buildd:brz-builder
Merge into: launchpad-buildd:master
Diff against target: 164 lines (+101/-0)
3 files modified
bin/buildrecipe (+17/-0)
debian/changelog (+2/-0)
lpbuildd/tests/test_buildrecipe.py (+82/-0)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+412287@code.launchpad.net

Commit message

Use brz-build-daily-recipe if it exists

Description of the change

In order to fully support focal, we need to use `brz` rather than `bzr` to support Python 3. Fortunately, `bzr-builder` was already ported upstream as `brz-builder`, so make use of it if it exists.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

As I lack a bit about background on buildd, I compared the new with the existing similar test and the changes look good.

I have not run the tests yet, as I need to setup the environment before.

review: Approve
Revision history for this message
Colin Watson (cjwatson) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/bin/buildrecipe b/bin/buildrecipe
2index b447f01..4d04c4f 100755
3--- a/bin/buildrecipe
4+++ b/bin/buildrecipe
5@@ -84,6 +84,21 @@ class RecipeBuilder:
6 """
7 return self.chroot(['apt-get', 'install', '-y', 'lsb-release'])
8
9+ # XXX cjwatson 2021-11-23: Use shutil.which instead once we can assume
10+ # Python >= 3.3.
11+ def _is_command_on_path(self, command):
12+ """Is 'command' on the executable search path?"""
13+ if "PATH" not in os.environ:
14+ return False
15+ path = os.environ["PATH"]
16+ for element in path.split(os.pathsep):
17+ if not element:
18+ continue
19+ filename = os.path.join(element, command)
20+ if os.path.isfile(filename) and os.access(filename, os.X_OK):
21+ return True
22+ return False
23+
24 def buildTree(self):
25 """Build the recipe into a source tree.
26
27@@ -127,6 +142,8 @@ class RecipeBuilder:
28 }
29 if self.git:
30 cmd = ['git-build-recipe']
31+ elif self._is_command_on_path('brz-build-daily-recipe'):
32+ cmd = ['brz-build-daily-recipe']
33 else:
34 cmd = ['bzr', '-Derror', 'dailydeb']
35 cmd.extend([
36diff --git a/debian/changelog b/debian/changelog
37index 28df0fc..2eb11a0 100644
38--- a/debian/changelog
39+++ b/debian/changelog
40@@ -1,6 +1,8 @@
41 launchpad-buildd (205) UNRELEASED; urgency=medium
42
43 * Ignore NotAutomatic flag for -proposed and -backports (LP: #1016776).
44+ * Use brz-build-daily-recipe rather than "bzr -Derror dailydeb" if the
45+ former exists (see LP #1943292).
46
47 -- Colin Watson <cjwatson@ubuntu.com> Mon, 29 Nov 2021 16:20:37 +0000
48
49diff --git a/lpbuildd/tests/test_buildrecipe.py b/lpbuildd/tests/test_buildrecipe.py
50index a4da180..2faa985 100644
51--- a/lpbuildd/tests/test_buildrecipe.py
52+++ b/lpbuildd/tests/test_buildrecipe.py
53@@ -16,8 +16,10 @@ import tempfile
54 from textwrap import dedent
55
56 from fixtures import (
57+ EnvironmentVariable,
58 MockPatch,
59 MockPatchObject,
60+ TempDir,
61 )
62 import six
63 from systemfixtures import FakeProcesses
64@@ -86,6 +88,30 @@ class TestRecipeBuilder(TestCase):
65 self.resetEnvironment()
66 super(TestRecipeBuilder, self).tearDown()
67
68+ def test_is_command_on_path_missing_environment(self):
69+ self.useFixture(EnvironmentVariable("PATH"))
70+ self.assertFalse(self.builder._is_command_on_path("ls"))
71+
72+ def test_is_command_on_path_present_executable(self):
73+ temp_dir = self.useFixture(TempDir()).path
74+ bin_dir = os.path.join(temp_dir, "bin")
75+ os.mkdir(bin_dir)
76+ program = os.path.join(bin_dir, "program")
77+ with open(program, "w"):
78+ pass
79+ os.chmod(program, 0o755)
80+ self.useFixture(EnvironmentVariable("PATH", bin_dir))
81+ self.assertTrue(self.builder._is_command_on_path("program"))
82+
83+ def test_is_command_on_path_present_not_executable(self):
84+ temp_dir = self.useFixture(TempDir()).path
85+ bin_dir = os.path.join(temp_dir, "bin")
86+ os.mkdir(bin_dir)
87+ with open(os.path.join(bin_dir, "program"), "w"):
88+ pass
89+ self.useFixture(EnvironmentVariable("PATH", bin_dir))
90+ self.assertFalse(self.builder._is_command_on_path("program"))
91+
92 def test_buildTree_git(self):
93 def fake_git(args):
94 if args["args"][1] == "--version":
95@@ -139,6 +165,60 @@ class TestRecipeBuilder(TestCase):
96 """) % repr(expected_recipe_command),
97 mock_stdout.getvalue())
98
99+ def test_buildTree_brz(self):
100+ def fake_bzr(args):
101+ if args["args"][1] == "version":
102+ print("brz version x.y.z")
103+ return {}
104+ elif args["args"][1] == "plugins":
105+ print("brz-plugin x.y.z")
106+ return {}
107+ else:
108+ return {"returncode": 1}
109+
110+ def fake_brz_build_daily_recipe(args):
111+ print("dummy recipe build")
112+ os.makedirs(os.path.join(self.builder.tree_path, "foo"))
113+ return {}
114+
115+ processes_fixture = self.useFixture(FakeProcesses())
116+ processes_fixture.add(
117+ lambda _: {"stdout": io.StringIO(u"5.10\n")}, name="sudo")
118+ processes_fixture.add(fake_bzr, name="bzr")
119+ processes_fixture.add(
120+ fake_brz_build_daily_recipe, name="brz-build-daily-recipe")
121+ with open(os.path.join(self.builder.work_dir, "recipe"), "w") as f:
122+ f.write("dummy recipe contents\n")
123+ mock_stdout = six.StringIO()
124+ self.useFixture(MockPatch("sys.stdout", mock_stdout))
125+ self.useFixture(MockPatchObject(
126+ self.builder, "_is_command_on_path",
127+ side_effect=lambda command: command == "brz-build-daily-recipe"))
128+ self.assertEqual(0, self.builder.buildTree())
129+ self.assertEqual(
130+ os.path.join(self.builder.work_dir_relative, "tree", "foo"),
131+ self.builder.source_dir_relative)
132+ expected_recipe_command = [
133+ "brz-build-daily-recipe", "--safe", "--no-build",
134+ "--manifest", os.path.join(self.builder.tree_path, "manifest"),
135+ "--distribution", "grumpy", "--allow-fallback-to-native",
136+ "--append-version", u"~ubuntu5.10.1",
137+ os.path.join(self.builder.work_dir, "recipe"),
138+ self.builder.tree_path,
139+ ]
140+ self.assertEqual(
141+ dedent("""\
142+ Bazaar versions:
143+ brz version x.y.z
144+ brz-plugin x.y.z
145+ Building recipe:
146+ dummy recipe contents
147+
148+ RUN %s
149+ dummy recipe build
150+ """) % repr(expected_recipe_command),
151+ mock_stdout.getvalue())
152+
153 def test_buildTree_bzr(self):
154 def fake_bzr(args):
155 if args["args"][1] == "version":
156@@ -162,6 +242,8 @@ class TestRecipeBuilder(TestCase):
157 f.write("dummy recipe contents\n")
158 mock_stdout = six.StringIO()
159 self.useFixture(MockPatch("sys.stdout", mock_stdout))
160+ self.useFixture(MockPatchObject(
161+ self.builder, "_is_command_on_path", return_value=False))
162 self.assertEqual(0, self.builder.buildTree())
163 self.assertEqual(
164 os.path.join(self.builder.work_dir_relative, "tree", "foo"),

Subscribers

People subscribed via source and target branches