1
# Copyright (C) 2011 Canonical Ltd
3
# This file is part of bzr-builddeb.
5
# bzr-builddeb is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# bzr-builddeb is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with bzr-builddeb; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
"""Tests for the merge_quilt code."""
22
from __future__ import absolute_import
32
from .....bedding import ensure_config_dir_exists
33
from .....merge import Merger
34
from .....mutabletree import MutableTree
38
start_commit_check_quilt,
39
post_build_tree_quilt,
40
post_merge_quilt_cleanup,
42
from ..quilt import QuiltPatches
43
from ..merge import tree_unapply_patches
45
from .test_wrapper import quilt_feature
47
from .....tests import (
48
TestCaseWithTransport,
52
TRIVIAL_PATCH = """--- /dev/null 2012-01-02 01:09:10.986490031 +0100
53
+++ base/a 2012-01-02 20:03:59.710666215 +0100
59
def quilt_push_all(tree):
60
QuiltPatches(tree, 'debian/patches').push_all()
63
class TestTreeUnapplyPatches(TestCaseWithTransport):
65
_test_needs_features = [quilt_feature]
67
def test_no_patches(self):
68
tree = self.make_branch_and_tree('.')
69
new_tree, target_dir = tree_unapply_patches(tree)
70
self.assertIs(tree, new_tree)
71
self.assertIs(None, target_dir)
73
def test_unapply(self):
74
orig_tree = self.make_branch_and_tree('source')
75
self.build_tree(["source/debian/", "source/debian/patches/"])
76
self.build_tree_contents([
77
("source/debian/patches/series", "patch1.diff\n"),
78
("source/debian/patches/patch1.diff", TRIVIAL_PATCH)])
79
quilt_push_all(orig_tree)
80
orig_tree.smart_add([orig_tree.basedir])
81
tree, target_dir = tree_unapply_patches(orig_tree)
82
self.addCleanup(shutil.rmtree, target_dir)
83
self.assertPathExists("source/a")
84
self.assertNotEqual(tree.basedir, orig_tree.basedir)
85
self.assertPathDoesNotExist(tree.abspath("a"))
86
self.assertPathExists(tree.abspath("debian/patches/series"))
88
def test_unapply_nothing_applied(self):
89
orig_tree = self.make_branch_and_tree('source')
90
self.build_tree(["source/debian/", "source/debian/patches/"])
91
self.build_tree_contents([
92
("source/debian/patches/series", "patch1.diff\n"),
93
("source/debian/patches/patch1.diff", TRIVIAL_PATCH)])
94
orig_tree.smart_add([orig_tree.basedir])
95
tree, target_dir = tree_unapply_patches(orig_tree)
96
self.assertIs(tree, orig_tree)
97
self.assertIs(None, target_dir)
100
class TestMergeHook(TestCaseWithTransport):
102
_test_needs_features = [quilt_feature]
104
def enable_hooks(self):
105
Merger.hooks.install_named_hook(
106
'pre_merge', pre_merge_quilt,
107
'Debian quilt patch (un)applying and ancestry fixing')
108
Merger.hooks.install_named_hook(
109
'post_merge', post_merge_quilt_cleanup,
110
'Cleaning up quilt temporary directories')
111
MutableTree.hooks.install_named_hook(
112
"post_build_tree", post_build_tree_quilt,
113
"Apply quilt trees.")
115
def test_diverged_patches(self):
118
tree_a = self.make_branch_and_tree('a')
120
['a/debian/', 'a/debian/patches/', 'a/debian/source/', 'a/.pc/'])
121
self.build_tree_contents([
122
('a/.pc/.quilt_patches', 'debian/patches'),
123
('a/.pc/.version', '2'),
124
('a/debian/source/format', '3.0 (quilt)'),
125
('a/debian/patches/series', 'patch1\n'),
126
('a/debian/patches/patch1', TRIVIAL_PATCH)])
127
tree_a.smart_add([tree_a.basedir])
128
tree_a.commit('initial')
130
tree_b = tree_a.controldir.sprout('b').open_workingtree()
131
self.build_tree_contents([
132
('a/debian/patches/patch1',
133
"\n".join(TRIVIAL_PATCH.splitlines()[:-1] + ["+d\n"]))])
134
quilt_push_all(tree_a)
135
tree_a.smart_add([tree_a.basedir])
136
tree_a.commit('apply patches')
137
self.build_tree_contents([
138
('b/debian/patches/patch1',
139
"\n".join(TRIVIAL_PATCH.splitlines()[:-1] + ["+c\n"]))])
140
quilt_push_all(tree_b)
141
tree_b.commit('apply patches')
142
conflicts = tree_a.merge_from_branch(tree_b.branch)
143
self.assertFileEqual("""\
144
--- /dev/null\t2012-01-02 01:09:10.986490031 +0100
145
+++ base/a\t2012-01-02 20:03:59.710666215 +0100
152
""", "a/debian/patches/patch1")
153
# "a" should be unapplied again
154
self.assertPathDoesNotExist("a/a")
155
self.assertEquals(1, conflicts)
157
def test_auto_apply_patches_after_checkout(self):
160
tree_a = self.make_branch_and_tree('a')
162
self.build_tree(['a/debian/', 'a/debian/patches/'])
163
self.build_tree_contents([
164
('a/debian/patches/series', 'patch1\n'),
165
('a/debian/patches/patch1', TRIVIAL_PATCH)])
166
tree_a.smart_add([tree_a.basedir])
167
tree_a.commit('initial')
169
ensure_config_dir_exists()
170
config.GlobalStack().set('quilt.tree_policy', 'applied')
172
tree_a.branch.create_checkout("b")
173
self.assertFileEqual("a\n", "b/a")
175
def test_auto_apply_patches_after_update_format_1(self):
178
tree_a = self.make_branch_and_tree('a')
179
tree_b = tree_a.branch.create_checkout("b")
181
self.build_tree(['a/debian/', 'a/debian/patches/', 'a/.pc/'])
182
self.build_tree_contents([
183
('a/.pc/.quilt_patches', 'debian/patches'),
184
('a/.pc/.version', '2'),
185
('a/debian/patches/series', 'patch1\n'),
186
('a/debian/patches/patch1', TRIVIAL_PATCH)])
187
tree_a.smart_add([tree_a.basedir])
188
tree_a.commit('initial')
190
self.build_tree(["b/.bzr-builddeb/", "b/debian/", "b/debian/source/"])
191
tree_b.get_config_stack().set('quilt.tree_policy', 'applied')
192
self.build_tree_contents([
193
("b/debian/source/format", "1.0")])
196
self.assertFileEqual("a\n", "b/a")
198
def test_auto_apply_patches_after_update(self):
201
tree_a = self.make_branch_and_tree('a')
202
tree_b = tree_a.branch.create_checkout("b")
204
self.build_tree(['a/debian/', 'a/debian/patches/', 'a/debian/source/', 'a/.pc/'])
205
self.build_tree_contents([
206
('a/.pc/.quilt_patches', 'debian/patches'),
207
('a/.pc/.version', '2'),
208
('a/debian/source/format', '3.0 (quilt)'),
209
('a/debian/patches/series', 'patch1\n'),
210
('a/debian/patches/patch1', TRIVIAL_PATCH)])
211
tree_a.smart_add([tree_a.basedir])
212
tree_a.commit('initial')
214
self.build_tree(["b/.bzr-builddeb/", "b/debian/", "b/debian/source/"])
215
tree_b.get_config_stack().set('quilt.tree_policy', 'applied')
216
self.build_tree_contents([
217
('b/debian/source/format', '3.0 (quilt)'),
221
self.assertFileEqual("a\n", "b/a")
223
def test_auto_unapply_patches_after_update(self):
226
tree_a = self.make_branch_and_tree('a')
227
tree_b = tree_a.branch.create_checkout("b")
229
self.build_tree(['a/debian/', 'a/debian/patches/', 'a/debian/source/', 'a/.pc/'])
230
self.build_tree_contents([
231
('a/.pc/.quilt_patches', 'debian/patches'),
232
('a/.pc/.version', '2'),
233
('a/debian/source/format', '3.0 (quilt)'),
234
('a/debian/patches/series', 'patch1\n'),
235
('a/debian/patches/patch1', TRIVIAL_PATCH)])
236
tree_a.smart_add([tree_a.basedir])
237
tree_a.commit('initial')
239
self.build_tree(["b/.bzr-builddeb/"])
240
tree_b.get_config_stack().set('quilt.tree_policy', 'unapplied')
243
self.assertPathDoesNotExist("b/a")
245
def test_disabled_hook(self):
248
tree_a = self.make_branch_and_tree('a')
249
tree_a.get_config_stack().set('quilt.smart_merge', False)
250
self.build_tree(['a/debian/', 'a/debian/patches/', 'a/.pc/'])
251
self.build_tree_contents([
252
('a/.pc/.quilt_patches', 'debian/patches'),
253
('a/.pc/.version', '2'),
254
('a/debian/patches/series', 'patch1\n'),
255
('a/debian/patches/patch1', TRIVIAL_PATCH),
257
tree_a.smart_add([tree_a.basedir])
258
tree_a.commit('initial')
260
tree_b = tree_a.controldir.sprout('b').open_workingtree()
261
self.build_tree_contents([
262
('a/debian/patches/patch1',
263
"\n".join(TRIVIAL_PATCH.splitlines()[:-1] + ["+d\n"]))])
264
quilt_push_all(tree_a)
265
tree_a.smart_add([tree_a.basedir])
266
tree_a.commit('apply patches')
267
self.assertFileEqual("d\n", "a/a")
268
self.build_tree_contents([
269
('b/debian/patches/patch1',
270
"\n".join(TRIVIAL_PATCH.splitlines()[:-1] + ["+c\n"]))])
271
quilt_push_all(tree_b)
272
tree_b.commit('apply patches')
273
self.assertFileEqual("c\n", "b/a")
274
conflicts = tree_a.merge_from_branch(tree_b.branch)
275
self.assertFileEqual("""\
276
--- /dev/null\t2012-01-02 01:09:10.986490031 +0100
277
+++ base/a\t2012-01-02 20:03:59.710666215 +0100
284
""", "a/debian/patches/patch1")
285
self.assertFileEqual("""\
292
self.assertEquals(2, conflicts)
296
class StartCommitMergeHookTests(TestCaseWithTransport):
298
def enable_hooks(self):
299
MutableTree.hooks.install_named_hook(
300
'start_commit', start_commit_check_quilt,
301
'Check for (un)applied quilt patches')
303
def test_applied(self):
305
tree = self.make_branch_and_tree('source')
306
tree.get_config_stack().set('quilt.commit_policy', 'applied')
307
self.build_tree(['source/debian/', 'source/debian/patches/',
308
'source/debian/source/'])
309
self.build_tree_contents([
310
('source/debian/source/format', '3.0 (quilt)'),
311
('source/debian/patches/series', 'patch1\n'),
312
('source/debian/patches/patch1', TRIVIAL_PATCH)])
313
self.assertPathDoesNotExist("source/.pc/applied-patches")
314
self.assertPathDoesNotExist("source/a")
315
tree.smart_add([tree.basedir])
317
self.assertPathExists("source/.pc/applied-patches")
318
self.assertPathExists("source/a")
320
def test_unapplied(self):
322
tree = self.make_branch_and_tree('source')
323
tree.get_config_stack().set('quilt.commit_policy', 'unapplied')
325
['source/debian/', 'source/debian/patches/',
326
'source/debian/source/'])
327
self.build_tree_contents([
328
('source/debian/patches/series', 'patch1\n'),
329
('source/debian/patches/patch1', TRIVIAL_PATCH),
330
('source/debian/source/format', '3.0 (quilt)')])
332
self.assertPathExists("source/.pc/applied-patches")
333
self.assertPathExists("source/a")
334
tree.smart_add([tree.basedir])
336
self.assertPathDoesNotExist("source/.pc/applied-patches")
337
self.assertPathDoesNotExist("source/a")
339
def test_warning(self):
345
warnings.append(args[0] % args[1:])
347
warnings.append(args[0])
348
_warning = trace.warning
349
trace.warning = warning
350
self.addCleanup(setattr, trace, "warning", _warning)
351
tree = self.make_branch_and_tree('source')
352
self.build_tree(['source/debian/', 'source/debian/patches/',
353
'source/debian/source/'])
354
self.build_tree_contents([
355
('source/debian/patches/series', 'patch1\n'),
356
('source/debian/patches/patch1', TRIVIAL_PATCH)])
358
tree.smart_add([tree.basedir])
359
tree.commit("initial")
360
self.assertEquals([], warnings)
361
self.assertPathExists("source/.pc/applied-patches")
362
self.assertPathExists("source/a")
363
self.build_tree_contents([
364
('source/debian/source/format', '3.0 (quilt)'),
365
('source/debian/patches/series', 'patch1\npatch2\n'),
366
('source/debian/patches/patch2',
367
"""--- /dev/null 2012-01-02 01:09:10.986490031 +0100
368
+++ base/b 2012-01-02 20:03:59.710666215 +0100
372
tree.smart_add([tree.basedir])
375
['Committing with 1 patches applied and 1 patches unapplied.'],
377
self.assertPathExists("source/.pc/applied-patches")
378
self.assertPathExists("source/a")
379
self.assertPathDoesNotExist("source/b")