Merge lp:~lifeless/bzr-builddeb/trunk into lp:bzr-builddeb

Proposed by Robert Collins
Status: Merged
Merged at revision: 463
Proposed branch: lp:~lifeless/bzr-builddeb/trunk
Merge into: lp:bzr-builddeb
Diff against target: 268 lines (+183/-27)
4 files modified
bzrtools_import.py (+32/-21)
debian/changelog (+7/-0)
dh_make.py (+10/-1)
tests/blackbox/test_merge_upstream.py (+134/-5)
To merge this branch: bzr merge lp:~lifeless/bzr-builddeb/trunk
Reviewer Review Type Date Requested Status
Bzr-builddeb-hackers Pending
Review via email: mp+29167@code.launchpad.net

Commit message

Candidate (missing tests) fix for bug lp:588060.

Description of the change

This fixes the unversioned executability issue for me, but I haven't
written a unit test yet. Merging this as-is may be a step forward, though
a test is obviously preferrable, I'm not sure when I'll have tuits to get
around to that.

To post a comment you must log in.
lp:~lifeless/bzr-builddeb/trunk updated
463. By Robert Collins

Happy path tests R us. bzrtools_import file id resolution fix tested.

Revision history for this message
Robert Collins (lifeless) wrote :

This now has a happy path test. \o/

Revision history for this message
James Westby (james-w) wrote :

Merged with a tweak to the tests to use a lower level API for setup.

Thanks,

James

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrtools_import.py'
2--- bzrtools_import.py 2010-05-28 00:36:04 +0000
3+++ bzrtools_import.py 2010-07-06 05:35:40 +0000
4@@ -197,12 +197,20 @@
5 import_archive(tree, dir_file, file_ids_from=file_ids_from)
6
7 def import_archive(tree, archive_file, file_ids_from=None):
8+ if file_ids_from is None:
9+ file_ids_from = []
10+ for other_tree in file_ids_from:
11+ other_tree.lock_read()
12+ try:
13+ return _import_archive(tree, archive_file, file_ids_from)
14+ finally:
15+ for other_tree in file_ids_from:
16+ other_tree.unlock()
17+
18+
19+def _import_archive(tree, archive_file, file_ids_from):
20 prefix = common_directory(names_of_files(archive_file))
21 tt = TreeTransform(tree)
22-
23- if file_ids_from is None:
24- file_ids_from = []
25-
26 removed = set()
27 for path, entry in tree.inventory.iter_entries():
28 if entry.parent_id is None:
29@@ -231,6 +239,26 @@
30 add_implied_parents(implied_parents, relative_path)
31 trans_id = tt.trans_id_tree_path(relative_path)
32 added.add(relative_path.rstrip('/'))
33+ # To handle renames, we need to not use the preserved file id, rather
34+ # we need to lookup the file id in a from_tree, if there is one. If
35+ # there isn't, we should use the one in the current tree, and failing
36+ # that we will allocate one. In this importer we want the file_ids_from
37+ # tree to authoritative about id2path, which is why we consult it
38+ # first.
39+ existing_file_id = tt.tree_file_id(trans_id)
40+ for other_tree in file_ids_from:
41+ found_file_id = other_tree.path2id(relative_path)
42+ if found_file_id:
43+ if found_file_id != existing_file_id:
44+ # Found a specific file id in one of the source trees
45+ tt.version_file(found_file_id, trans_id)
46+ break
47+ if not found_file_id and not existing_file_id:
48+ # No file_id in any of the source trees and no file id in the base
49+ # tree.
50+ name = basename(member.name.rstrip('/'))
51+ file_id = generate_ids.gen_file_id(name)
52+ tt.version_file(file_id, trans_id)
53 path = tree.abspath(relative_path)
54 if member.name in seen:
55 if tt.final_kind(trans_id) == 'file':
56@@ -248,23 +276,6 @@
57 tt.create_symlink(member.linkname, trans_id)
58 else:
59 raise UnknownType(relative_path)
60- if tt.tree_file_id(trans_id) is None:
61- found = False
62- for other_tree in file_ids_from:
63- other_tree.lock_read()
64- try:
65- if other_tree.has_filename(relative_path):
66- file_id = other_tree.path2id(relative_path)
67- if file_id is not None:
68- tt.version_file(file_id, trans_id)
69- found = True
70- break
71- finally:
72- other_tree.unlock()
73- if not found:
74- name = basename(member.name.rstrip('/'))
75- file_id = generate_ids.gen_file_id(name)
76- tt.version_file(file_id, trans_id)
77
78 for relative_path in implied_parents.difference(added):
79 if relative_path == "":
80
81=== modified file 'debian/changelog'
82--- debian/changelog 2010-05-31 17:33:49 +0000
83+++ debian/changelog 2010-07-06 05:35:40 +0000
84@@ -1,3 +1,10 @@
85+bzr-builddeb (2.5lifeless1) UNRELEASED; urgency=low
86+
87+ * (No tests yet) treat the upstream branch as authoritative for file ids -
88+ causes renamed to be honoured. (LP: #588060)
89+
90+ -- Robert Collins <robertc@robertcollins.net> Sun, 04 Jul 2010 20:29:17 +1000
91+
92 bzr-builddeb (2.5) UNRELEASED; urgency=low
93
94 [ Colin Watson ]
95
96=== modified file 'dh_make.py'
97--- dh_make.py 2010-05-05 07:20:17 +0000
98+++ dh_make.py 2010-07-06 05:35:40 +0000
99@@ -108,8 +108,17 @@
100 tree.add("debian/source/format")
101 command = ["dh_make", "--addmissing", "--packagename",
102 "%s_%s" % (package_name, version)]
103+ if getattr(sys.stdin, 'fileno', None) is None:
104+ # running in a test or something
105+ stdin = subprocess.PIPE
106+ input = "s\n\n"
107+ else:
108+ stdin = sys.stdin
109+ input = None
110 proc = subprocess.Popen(command, cwd=tree.basedir,
111- preexec_fn=util.subprocess_setup, stdin=sys.stdin)
112+ preexec_fn=util.subprocess_setup, stdin=stdin)
113+ if input:
114+ proc.stdin.write(input)
115 retcode = proc.wait()
116 if retcode != 0:
117 raise bzr_errors.BzrCommandError("dh_make failed.")
118
119=== modified file 'tests/blackbox/test_merge_upstream.py'
120--- tests/blackbox/test_merge_upstream.py 2008-03-05 17:00:51 +0000
121+++ tests/blackbox/test_merge_upstream.py 2010-07-06 05:35:40 +0000
122@@ -18,12 +18,141 @@
123 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
124 #
125
126-from bzrlib.plugins.builddeb.tests import BuilddebTestCase
127+import os.path
128+
129+import bzrlib.export
130+
131+from bzrlib.plugins.builddeb.tests import (
132+ BuilddebTestCase,
133+ SourcePackageBuilder,
134+ )
135+
136+
137+class Fixture(object):
138+ """A test fixture."""
139+
140+ def __init__(self):
141+ pass
142+
143+ def setUp(self, test_case):
144+ test_case.addCleanup(self.tearDown)
145+
146+ def tearDown(self):
147+ pass
148+
149+
150+class Upstream(Fixture):
151+ """An upstream.
152+
153+ :ivar tree: The tree of the upstream.
154+ """
155+
156+ def setUp(self, test_case):
157+ Fixture.setUp(self, test_case)
158+ treename = test_case.getUniqueString()
159+ tree = test_case.make_branch_and_tree(treename)
160+ filename = test_case.getUniqueString()
161+ test_case.build_tree(["%s/%s" % (treename, filename)])
162+ tree.add([filename])
163+ tree.commit(test_case.getUniqueString())
164+ self.tree = tree
165+
166+
167+class ExportedTarball(Fixture):
168+ """An exported tarball 'release'."""
169+
170+ def __init__(self, upstream, version):
171+ self.upstream = upstream
172+ self.version = version
173+
174+ def setUp(self, test_case):
175+ filename = "project-%s.tar.gz" % self.version
176+ tree = self.upstream.tree.branch.repository.revision_tree(
177+ self.upstream.tree.branch.last_revision())
178+ bzrlib.export.export(tree, filename)
179+ self.tarball = filename
180+
181+
182+class DHMadePackage(Fixture):
183+ """A package made via dh-make."""
184+
185+ def __init__(self, tar, upstream):
186+ self.tar = tar
187+ self.upstream = upstream
188+
189+ def setUp(self, test_case):
190+ branchpath = test_case.getUniqueString()
191+ tree = self.upstream.tree.bzrdir.sprout(branchpath).open_workingtree()
192+ # UGH: spews, because the subprocess output isn't captured. Be nicer to
193+ # use closer to the metal functions here, but I'm overwhelmed by the
194+ # API today, and there is a grue.
195+ test_case.run_bzr(['dh-make', 'package', str(self.tar.version),
196+ os.path.abspath(self.tar.tarball)], working_dir=branchpath)
197+ tree.smart_add([tree.basedir])
198+ tree.commit('debianised.') # Honestly.
199+ self.tree = tree
200+
201+
202+class FileMovedReplacedUpstream(Fixture):
203+ """An upstream that has been changed by moving and replacing a file."""
204+
205+ def __init__(self, upstream):
206+ self.upstream = upstream
207+
208+ def setUp(self, test_case):
209+ branchpath = test_case.getUniqueString()
210+ tree = self.upstream.tree.bzrdir.sprout(branchpath).open_workingtree()
211+ self.tree = tree
212+ tree.lock_write()
213+ try:
214+ newpath = test_case.getUniqueString()
215+ for child in tree.inventory.root.children.values():
216+ if child.kind == 'file':
217+ oldpath = child.name
218+ tree.rename_one(oldpath, newpath)
219+ test_case.build_tree(["%s/%s" % (os.path.basename(tree.basedir),
220+ oldpath)])
221+ tree.add([oldpath])
222+ tree.commit('yo, renaming and replacing')
223+ finally:
224+ tree.unlock()
225+
226
227
228 class TestMergeUpstream(BuilddebTestCase):
229
230- def test_merge_upstream_available(self):
231- self.run_bzr('merge-upstream --help')
232-
233-# vim: ts=2 sts=2 sw=2
234+ def test_merge_upstream_available(self):
235+ self.run_bzr('merge-upstream --help')
236+
237+ def make_upstream(self):
238+ result = Upstream()
239+ result.setUp(self)
240+ return result
241+
242+ def release_upstream(self, upstream):
243+ tar = ExportedTarball(upstream, version=self.getUniqueInteger())
244+ tar.setUp(self)
245+ return tar
246+
247+ def import_upstream(self, tar, upstream):
248+ packaging = DHMadePackage(tar, upstream)
249+ packaging.setUp(self)
250+ return packaging
251+
252+ def file_moved_replaced_upstream(self, upstream):
253+ result = FileMovedReplacedUpstream(upstream)
254+ result.setUp(self)
255+ return result
256+
257+ def test_smoke_renamed_file(self):
258+ # When a file is renamed by upstream, it should still import ok.
259+ upstream = self.make_upstream()
260+ rel1 = self.release_upstream(upstream)
261+ package = self.import_upstream(rel1, upstream)
262+ changed_upstream = self.file_moved_replaced_upstream(upstream)
263+ rel2 = self.release_upstream(changed_upstream)
264+ self.run_bzr(['merge-upstream', '--version', str(rel2.version),
265+ os.path.abspath(rel2.tarball), changed_upstream.tree.basedir],
266+ working_dir=package.tree.basedir)
267+
268+# vim: ts=4 sts=4 sw=4

Subscribers

People subscribed via source and target branches