Merge lp:~jelmer/bzr-builddeb/quilt into lp:bzr-builddeb

Proposed by Jelmer Vernooij
Status: Merged
Merged at revision: 680
Proposed branch: lp:~jelmer/bzr-builddeb/quilt
Merge into: lp:bzr-builddeb
Diff against target: 305 lines (+265/-0)
4 files modified
merge_quilt.py (+24/-0)
quilt.py (+151/-0)
tests/__init__.py (+3/-0)
tests/test_quilt.py (+87/-0)
To merge this branch: bzr merge lp:~jelmer/bzr-builddeb/quilt
Reviewer Review Type Date Requested Status
James Westby Approve
Review via email: mp+87284@code.launchpad.net

Description of the change

Add utility methods for using quilt.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

87 + :param quilt: Whether to be quiet (quilt stderr not to terminal)

muscle memory I think :-)

I think there's no tests for tree_unapply_patches?

However, it looks good to me.

Thanks,

James

review: Approve
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

> I think there's no tests for tree_unapply_patches?
I've added two while landing this.

Thanks, as always, for the quick reviews!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'merge_quilt.py'
2--- merge_quilt.py 2011-12-20 14:44:17 +0000
3+++ merge_quilt.py 2012-01-02 19:24:23 +0000
4@@ -21,3 +21,27 @@
5 """Quilt patch handling."""
6
7 from __future__ import absolute_import
8+import tempfile
9+
10+from bzrlib import trace
11+from bzrlib.plugins.builddeb.quilt import quilt_pop_all
12+
13+
14+def tree_unapply_patches(orig_tree):
15+ """Return a tree with patches unapplied.
16+
17+ :param tree: Tree from which to unapply quilt patches
18+ :return: Tuple with tree and temp path.
19+ The tree is a tree with unapplied patches; either a checkout of
20+ tree or tree itself if there were no patches
21+ """
22+ series_file_id = orig_tree.path2id("debian/patches/series")
23+ if series_file_id is None:
24+ # No quilt patches
25+ return orig_tree, None
26+
27+ target_dir = tempfile.mkdtemp()
28+ tree = orig_tree.branch.create_checkout(target_dir, lightweight=True)
29+ trace.warning("Applying quilt patches for %r in %s", orig_tree, target_dir)
30+ quilt_pop_all(working_dir=tree.basedir)
31+ return tree, target_dir
32
33=== added file 'quilt.py'
34--- quilt.py 1970-01-01 00:00:00 +0000
35+++ quilt.py 2012-01-02 19:24:23 +0000
36@@ -0,0 +1,151 @@
37+# quilt.py -- Quilt patch handling
38+# Copyright (C) 2011 Canonical Ltd.
39+#
40+# This file is part of bzr-builddeb.
41+#
42+# bzr-builddeb is free software; you can redistribute it and/or modify
43+# it under the terms of the GNU General Public License as published by
44+# the Free Software Foundation; either version 2 of the License, or
45+# (at your option) any later version.
46+#
47+# bzr-builddeb is distributed in the hope that it will be useful,
48+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+# GNU General Public License for more details.
51+#
52+# You should have received a copy of the GNU General Public License
53+# along with bzr-builddeb; if not, write to the Free Software
54+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
55+#
56+
57+"""Quilt patch handling."""
58+
59+from __future__ import absolute_import
60+
61+import errno
62+import os
63+import signal
64+import subprocess
65+from bzrlib import (
66+ errors,
67+ trace,
68+ )
69+
70+
71+class QuiltError(errors.BzrError):
72+
73+ _fmt = "An error (%(retcode)d) occurred running quilt: %(msg)s"
74+
75+ def __init__(self, retcode, msg):
76+ self.retcode = retcode
77+ self.msg = msg
78+
79+
80+def run_quilt(args, working_dir, series_file=None, patches_dir=None, quiet=None):
81+ """Run quilt.
82+
83+ :param args: Arguments to quilt
84+ :param working_dir: Working dir
85+ :param series_file: Optional path to the series file
86+ :param patches_dir: Optional path to the patches
87+ :param quilt: Whether to be quiet (quilt stderr not to terminal)
88+ :raise QuiltError: When running quilt fails
89+ """
90+ def subprocess_setup():
91+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
92+ env = {}
93+ if patches_dir is not None:
94+ env["QUILT_PATCHES"] = patches_dir
95+ else:
96+ env["QUILT_PATCHES"] = os.path.join(working_dir, "debian", "patches")
97+ if series_file is not None:
98+ env["QUILT_SERIES"] = series_file
99+ else:
100+ env["QUILT_SERIES"] = os.path.join(env["QUILT_PATCHES"], "series")
101+ # Hide output if -q is in use.
102+ if quiet is None:
103+ quiet = trace.is_quiet()
104+ if quiet:
105+ stderr = subprocess.STDOUT
106+ else:
107+ stderr = subprocess.PIPE
108+ command = ["quilt"] + args
109+ trace.mutter("running: %r", command)
110+ if not os.path.isdir(working_dir):
111+ raise AssertionError("%s is not a valid directory" % working_dir)
112+ try:
113+ proc = subprocess.Popen(command, cwd=working_dir, env=env,
114+ stdin=subprocess.PIPE, preexec_fn=subprocess_setup,
115+ stdout=subprocess.PIPE, stderr=stderr)
116+ except OSError, e:
117+ if e.errno != errno.ENOENT:
118+ raise
119+ raise errors.BzrError("quilt is not installed, please install it")
120+ output = proc.communicate()
121+ if proc.returncode not in (0, 2):
122+ raise QuiltError(proc.returncode, output[1])
123+ if output[0] is None:
124+ return ""
125+ return output[0]
126+
127+
128+def quilt_pop_all(working_dir, patches_dir=None, series_file=None, quiet=None):
129+ """Pop all patches.
130+
131+ :param working_dir: Directory to work in
132+ :param patches_dir: Optional patches directory
133+ :param series_file: Optional series file
134+ """
135+ return run_quilt(["pop", "-a", "-v"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file, quiet=quiet)
136+
137+
138+def quilt_push_all(working_dir, patches_dir=None, series_file=None, quiet=None):
139+ """Push all patches.
140+
141+ :param working_dir: Directory to work in
142+ :param patches_dir: Optional patches directory
143+ :param series_file: Optional series file
144+ """
145+ return run_quilt(["push", "-a", "-v"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file, quiet=quiet)
146+
147+
148+def quilt_applied(working_dir, patches_dir=None, series_file=None):
149+ """Find the list of applied quilt patches.
150+
151+ :param working_dir: Directory to work in
152+ :param patches_dir: Optional patches directory
153+ :param series_file: Optional series file
154+ """
155+ try:
156+ return run_quilt(["applied"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file).splitlines()
157+ except QuiltError, e:
158+ if e.retcode == 1:
159+ return []
160+ raise
161+
162+
163+def quilt_unapplied(working_dir, patches_dir=None, series_file=None):
164+ """Find the list of unapplied quilt patches.
165+
166+ :param working_dir: Directory to work in
167+ :param patches_dir: Optional patches directory
168+ :param series_file: Optional series file
169+ """
170+ try:
171+ return run_quilt(["unapplied"], working_dir=working_dir,
172+ patches_dir=patches_dir, series_file=series_file).splitlines()
173+ except QuiltError, e:
174+ if e.retcode == 1:
175+ return []
176+ raise
177+
178+
179+def quilt_series(working_dir, patches_dir=None, series_file=None):
180+ """Find the list of patches.
181+
182+ :param working_dir: Directory to work in
183+ :param patches_dir: Optional patches directory
184+ :param series_file: Optional series file
185+ """
186+ return run_quilt(["series"], working_dir=working_dir, patches_dir=patches_dir, series_file=series_file).splitlines()
187+
188
189=== modified file 'tests/__init__.py'
190--- tests/__init__.py 2011-12-20 14:44:17 +0000
191+++ tests/__init__.py 2012-01-02 19:24:23 +0000
192@@ -37,11 +37,13 @@
193 from bzrlib.tests import TestUtil, multiply_tests
194 try:
195 from bzrlib.tests.features import (
196+ ExecutableFeature,
197 ModuleAvailableFeature,
198 UnicodeFilenameFeature,
199 )
200 except ImportError: # bzr < 2.5
201 from bzrlib.tests import (
202+ ExecutableFeature,
203 ModuleAvailableFeature,
204 UnicodeFilenameFeature,
205 )
206@@ -135,6 +137,7 @@
207 'test_merge_package',
208 'test_merge_quilt',
209 'test_merge_upstream',
210+ 'test_quilt',
211 'test_repack_tarball_extra',
212 'test_revspec',
213 'test_source_distiller',
214
215=== added file 'tests/test_quilt.py'
216--- tests/test_quilt.py 1970-01-01 00:00:00 +0000
217+++ tests/test_quilt.py 2012-01-02 19:24:23 +0000
218@@ -0,0 +1,87 @@
219+# Copyright (C) 2011 Canonical Ltd
220+#
221+# This file is part of bzr-builddeb.
222+#
223+# bzr-builddeb is free software; you can redistribute it and/or modify
224+# it under the terms of the GNU General Public License as published by
225+# the Free Software Foundation; either version 2 of the License, or
226+# (at your option) any later version.
227+#
228+# bzr-builddeb is distributed in the hope that it will be useful,
229+# but WITHOUT ANY WARRANTY; without even the implied warranty of
230+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
231+# GNU General Public License for more details.
232+#
233+# You should have received a copy of the GNU General Public License
234+# along with bzr-builddeb; if not, write to the Free Software
235+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
236+#
237+
238+"""Tests for the quilt code."""
239+
240+import os
241+
242+from bzrlib.plugins.builddeb.tests import ExecutableFeature
243+from bzrlib.plugins.builddeb.quilt import (
244+ quilt_pop_all,
245+ quilt_applied,
246+ quilt_unapplied,
247+ quilt_push_all,
248+ quilt_series,
249+ )
250+
251+from bzrlib.tests import TestCaseWithTransport
252+
253+quilt_feature = ExecutableFeature('quilt')
254+
255+TRIVIAL_PATCH = """--- /dev/null 2012-01-02 01:09:10.986490031 +0100
256++++ a 2012-01-02 20:03:59.710666215 +0100
257+@@ -0,0 +1 @@
258++a
259+"""
260+
261+class QuiltTests(TestCaseWithTransport):
262+
263+ _test_needs_features = [quilt_feature]
264+
265+ def make_empty_quilt_dir(self, path):
266+ source = self.make_branch_and_tree(path)
267+ self.build_tree([os.path.join(path, n) for n in ['debian/',
268+ 'debian/patches/']])
269+ self.build_tree_contents([
270+ (os.path.join(path, "debian/patches/series"), "\n")])
271+ source.add(["debian", "debian/patches", "debian/patches/series"])
272+ return source
273+
274+ def test_series_all_empty(self):
275+ self.make_empty_quilt_dir("source")
276+ self.assertEquals([], quilt_series("source"))
277+
278+ def test_series_all(self):
279+ self.make_empty_quilt_dir("source")
280+ self.build_tree_contents([
281+ ("source/debian/patches/series", "patch1.diff\n"),
282+ ("source/debian/patches/patch1.diff", TRIVIAL_PATCH)])
283+ self.assertEquals(["patch1.diff"], quilt_series("source"))
284+
285+ def test_push_all_empty(self):
286+ self.make_empty_quilt_dir("source")
287+ quilt_push_all("source", quiet=True)
288+
289+ def test_poph_all_empty(self):
290+ self.make_empty_quilt_dir("source")
291+ quilt_pop_all("source", quiet=True)
292+
293+ def test_applied_empty(self):
294+ self.make_empty_quilt_dir("source")
295+ self.build_tree_contents([
296+ ("source/debian/patches/series", "patch1.diff\n"),
297+ ("source/debian/patches/patch1.diff", "foob ar")])
298+ self.assertEquals([], quilt_applied("source"))
299+
300+ def test_unapplied(self):
301+ self.make_empty_quilt_dir("source")
302+ self.build_tree_contents([
303+ ("source/debian/patches/series", "patch1.diff\n"),
304+ ("source/debian/patches/patch1.diff", "foob ar")])
305+ self.assertEquals(["patch1.diff"], quilt_unapplied("source"))

Subscribers

People subscribed via source and target branches