Merge lp:~jelmer/bzr-builddeb/multiple-upstream-tarballs into lp:bzr-builddeb

Proposed by Jelmer Vernooij
Status: Superseded
Proposed branch: lp:~jelmer/bzr-builddeb/multiple-upstream-tarballs
Merge into: lp:bzr-builddeb
Diff against target: 1272 lines (+339/-191)
11 files modified
cmds.py (+29/-25)
debian/changelog (+3/-1)
dh_make.py (+2/-2)
import_dsc.py (+79/-45)
merge_package.py (+9/-4)
tests/blackbox/test_merge_upstream.py (+1/-1)
tests/test_import_dsc.py (+47/-38)
tests/test_upstream.py (+51/-11)
upstream/__init__.py (+16/-13)
upstream/branch.py (+13/-3)
upstream/pristinetar.py (+89/-48)
To merge this branch: bzr merge lp:~jelmer/bzr-builddeb/multiple-upstream-tarballs
Reviewer Review Type Date Requested Status
Bzr-builddeb-hackers Pending
Review via email: mp+77075@code.launchpad.net

This proposal has been superseded by a proposal from 2011-10-03.

Description of the change

Importing and building of packages with multiple upstream tarballs now works.

There are still two caveats:

 * when exporting the base component before generating a pristine tar delta, we don't exclude non-base components. This probably causes the pristine tar delta to be bigger than it needs to be
 * Needs more tests

To post a comment you must log in.
625. By Jelmer Vernooij

merge lp:bzr-builddeb.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmds.py'
2--- cmds.py 2011-09-09 13:20:42 +0000
3+++ cmds.py 2011-09-27 00:50:26 +0000
4@@ -556,7 +556,7 @@
5 'entry yourself, review the merge, and then commit.')
6
7 def _do_merge(self, tree, tarball_filenames, package, version,
8- current_version, upstream_branch, upstream_revision, merge_type,
9+ current_version, upstream_branch, upstream_revisions, merge_type,
10 force):
11 db = DistributionBranch(tree.branch, tree.branch, tree=tree)
12 dbs = DistributionBranchSet()
13@@ -565,7 +565,7 @@
14 in tarball_filenames]
15 conflicts = db.merge_upstream(tarballs, package, version,
16 current_version, upstream_branch=upstream_branch,
17- upstream_revision=upstream_revision,
18+ upstream_revisions=upstream_revisions,
19 merge_type=merge_type, force=force)
20 return conflicts
21
22@@ -712,15 +712,15 @@
23 raise BzrCommandError("merge-upstream takes only a "
24 "single --revision")
25 upstream_revspec = revision[0]
26- upstream_revision = upstream_revspec.as_revision_id(
27- upstream_branch)
28+ upstream_revisions = { None: upstream_revspec.as_revision_id(
29+ upstream_branch) }
30 else:
31- upstream_revision = None
32+ upstream_revisions = None
33
34- if version is None and upstream_revision is not None:
35+ if version is None and upstream_revisions is not None:
36 # Look up the version from the upstream revision
37 version = upstream_branch_source.get_version(package,
38- current_version, upstream_revision)
39+ current_version, upstream_revisions)
40 elif version is None and primary_upstream_source is not None:
41 version = primary_upstream_source.get_latest_version(
42 package, current_version)
43@@ -735,9 +735,9 @@
44 assert isinstance(version, str)
45 note("Using version string %s." % (version))
46 # Look up the revision id from the version string
47- if upstream_revision is None and upstream_branch_source is not None:
48+ if upstream_revisions is None and upstream_branch_source is not None:
49 try:
50- upstream_revision = upstream_branch_source.version_as_revision(
51+ upstream_revisions = upstream_branch_source.version_as_revisions(
52 package, version)
53 except PackageVersionNotPresent:
54 raise BzrCommandError(
55@@ -748,15 +748,15 @@
56 if need_upstream_tarball:
57 target_dir = tempfile.mkdtemp() # FIXME: Cleanup?
58 locations = primary_upstream_source.fetch_tarballs(
59- package, version, target_dir)
60+ package, version, target_dir, components=[None])
61 source_format = get_source_format(tree)
62 v3 = (source_format in [
63 FORMAT_3_0_QUILT, FORMAT_3_0_NATIVE])
64 tarball_filenames = self._get_tarballs(config, tree, package,
65- version, upstream_branch, upstream_revision, v3,
66+ version, upstream_branch, upstream_revisions, v3,
67 locations)
68 conflicts = self._do_merge(tree, tarball_filenames, package,
69- version, current_version, upstream_branch, upstream_revision,
70+ version, current_version, upstream_branch, upstream_revisions,
71 merge_type, force)
72 if (current_version is not None and
73 Version(current_version) >= Version(version)):
74@@ -886,9 +886,9 @@
75 "sure it is tagged as %r." % (last_version,
76 db.pristine_upstream_source.tag_name(
77 last_version.upstream_version)))
78- upstream_tip = db.pristine_upstream_source.version_as_revision(
79+ upstream_tips = db.pristine_upstream_source.version_as_revisions(
80 changelog.package, last_version.upstream_version)
81- db.extract_upstream_tree(upstream_tip, tempdir)
82+ db.extract_upstream_tree(upstream_tips, tempdir)
83 else:
84 db._create_empty_upstream_tree(tempdir)
85 self.import_many(db, files_list, orig_target)
86@@ -955,19 +955,24 @@
87 if db.pristine_upstream_source.has_version(None, version):
88 raise BzrCommandError("Version %s is already present." % version)
89 tagged_versions = {}
90- for tag, tag_version, revid in db.pristine_upstream_source.iter_versions():
91- tagged_versions[Version(tag_version)] = revid
92+ for tversion, tcomponents in db.pristine_upstream_source.iter_versions():
93+ tagged_versions[Version(version)] = tcomponents
94 tag_order = sorted(tagged_versions.keys())
95 if tag_order:
96- parents = [tagged_versions[tag_order[-1]]]
97+ base_revisions = tagged_versions[tag_order[-1]]
98 else:
99- parents = []
100- if parents:
101+ base_revisions = {}
102+ if base_revisions:
103 if upstream is not None:
104 # See bug lp:309682
105- upstream.repository.fetch(branch.repository, parents[0])
106- db.extract_upstream_tree(parents[0], tempdir)
107+ for parent in base_revisions.values():
108+ upstream.repository.fetch(branch.repository, parent)
109+ db.extract_upstream_tree(base_revisions, tempdir)
110+ parents = {}
111+ for name, base_revid in base_revisions.iteritems():
112+ parents[name] = [base_revid]
113 else:
114+ parents = {}
115 db._create_empty_upstream_tree(tempdir)
116 tree = db.branch.basis_tree()
117 tree.lock_read()
118@@ -983,7 +988,7 @@
119 tarballs = [(location, None, md5sum_filename(location))]
120 for (component, tag_name, revid) in db.import_upstream_tarballs(
121 tarballs, None, version, parents, upstream_branch=upstream,
122- upstream_revision=upstream_revid):
123+ upstream_revisions={ None: upstream_revid }):
124 if component is None:
125 self.outf.write('Imported %s as tag:%s.\n' % (
126 location, tag_name))
127@@ -1224,9 +1229,8 @@
128 dh_make.run_dh_make(tree, package_name, version, use_v3=v3)
129 finally:
130 tree.unlock()
131- note('Package prepared in %s'
132- % urlutils.unescape_for_display(tree.basedir,
133- self.outf.encoding))
134+ note('Package prepared in %s',
135+ urlutils.unescape_for_display(tree.basedir, self.outf.encoding))
136
137
138 class cmd_dep3_patch(Command):
139
140=== modified file 'debian/changelog'
141--- debian/changelog 2011-09-09 13:21:35 +0000
142+++ debian/changelog 2011-09-27 00:50:26 +0000
143@@ -1,8 +1,10 @@
144 bzr-builddeb (2.7.9) UNRELEASED; urgency=low
145
146 * Support .tar.xz Debian files rather than .tar.lzma.
147+ * Support importing and building packages with multiple upstream
148+ tarballs. LP: #653757, LP: #664834
149
150- -- Jelmer Vernooij <jelmer@debian.org> Fri, 09 Sep 2011 15:21:22 +0200
151+ -- Jelmer Vernooij <jelmer@debian.org> Tue, 27 Sep 2011 02:40:03 +0200
152
153 bzr-builddeb (2.7.8) unstable; urgency=low
154
155
156=== modified file 'dh_make.py'
157--- dh_make.py 2011-09-09 13:20:42 +0000
158+++ dh_make.py 2011-09-27 00:50:26 +0000
159@@ -79,9 +79,9 @@
160 def import_upstream(tarball, package_name, version, use_v3=False):
161 tree = _get_tree(package_name)
162 if tree.branch.last_revision() != mod_revision.NULL_REVISION:
163- parents = [tree.branch.last_revision()]
164+ parents = { None: [tree.branch.last_revision()] }
165 else:
166- parents = []
167+ parents = {}
168 tarball_filenames = _get_tarballs(tree, tarball,
169 package_name, version, use_v3=use_v3)
170 db = import_dsc.DistributionBranch(tree.branch, tree.branch, tree=tree,
171
172=== modified file 'import_dsc.py'
173--- import_dsc.py 2011-09-09 13:20:42 +0000
174+++ import_dsc.py 2011-09-27 00:50:26 +0000
175@@ -60,6 +60,7 @@
176
177 from bzrlib.plugins.builddeb.bzrtools_import import import_dir
178 from bzrlib.plugins.builddeb.errors import (
179+ MultipleUpstreamTarballsNotSupported,
180 PackageVersionNotPresent,
181 UpstreamAlreadyImported,
182 UpstreamBranchAlreadyMerged,
183@@ -556,6 +557,7 @@
184 tarballs=upstream_tarballs):
185 return False
186
187+
188 up_branch = self.pristine_upstream_branch
189 up_branch.lock_read()
190 try:
191@@ -563,10 +565,14 @@
192 other_up_branch = branch.pristine_upstream_branch
193 other_up_branch.lock_read()
194 try:
195+ pristine_upstream_revids = branch.pristine_upstream_source.version_as_revisions(package, version)
196+ if pristine_upstream_revids.keys() != [None]:
197+ raise MultipleUpstreamTarballsNotSupported()
198+ pristine_upstream_revid = pristine_upstream_revids[None]
199 graph = other_up_branch.repository.get_graph(
200 up_branch.repository)
201 return graph.is_ancestor(up_branch.last_revision(),
202- branch.pristine_upstream_source.version_as_revision(package, version))
203+ pristine_upstream_revid)
204 finally:
205 other_up_branch.unlock()
206 finally:
207@@ -680,7 +686,11 @@
208 :param version: the upstream version string
209 """
210 assert isinstance(version, str)
211- pull_revision = pull_branch.pristine_upstream_source.version_as_revision(package, version)
212+ pull_revisions = pull_branch.pristine_upstream_source.version_as_revisions(
213+ package, version)
214+ if pull_revisions.keys() != [None]:
215+ raise MultipleUpstreamTarballsNotSupported()
216+ pull_revision = pull_revisions[None]
217 mutter("Pulling upstream part of %s from revision %s" % \
218 (version, pull_revision))
219 assert self.pristine_upstream_tree is not None, \
220@@ -774,12 +784,17 @@
221 break
222 real_parents = [p[2] for p in parents]
223 if need_upstream_parent:
224- parent_revid = self.pristine_upstream_source.version_as_revision(package,
225- version.upstream_version, tarballs)
226- if len(parents) > 0:
227- real_parents.insert(1, parent_revid)
228- else:
229- real_parents = [parent_revid]
230+ upstream_revids = self.pristine_upstream_source.version_as_revisions(
231+ package, version.upstream_version, tarballs)
232+ def key(a):
233+ if a is None:
234+ return None
235+ return a
236+ for component in sorted(upstream_revids.keys(), key=key):
237+ if len(real_parents) > 0:
238+ real_parents.insert(1, upstream_revids[component])
239+ else:
240+ real_parents = [upstream_revids[component]]
241 return real_parents
242
243 def _fetch_upstream_to_branch(self, revid):
244@@ -793,7 +808,7 @@
245
246 def import_upstream(self, upstream_part, package, version, upstream_parents,
247 upstream_tarballs, upstream_branch=None,
248- upstream_revision=None, timestamp=None, author=None,
249+ upstream_revisions=None, timestamp=None, author=None,
250 file_ids_from=None):
251 """Import an upstream part on to the upstream branch.
252
253@@ -814,25 +829,31 @@
254 # TODO: this method needs a lot of work for when we will make
255 # the branches writeable by others.
256 assert isinstance(version, str)
257- mutter("Importing upstream version %s from %s with parents %s" \
258- % (version, upstream_part, str(upstream_parents)))
259+ mutter("Importing upstream version %s from %s with parents %r" \
260+ % (version, upstream_part, upstream_parents))
261 assert self.pristine_upstream_tree is not None, \
262 "Can't import upstream with no tree"
263 other_branches = self.get_other_branches()
264 ret = []
265 for (tarball, component, md5) in upstream_tarballs:
266+ parents = upstream_parents.get(component, [])
267+ if upstream_revisions is not None:
268+ revid = upstream_revisions[component]
269+ else:
270+ revid = None
271 upstream_trees = [o.pristine_upstream_branch.basis_tree()
272 for o in other_branches]
273 target_tree = None
274 if upstream_branch is not None:
275- if upstream_revision is None:
276- upstream_revision = upstream_branch.last_revision()
277+ if revid is None:
278+ # FIXME: This is wrong for component tarballs
279+ revid = upstream_branch.last_revision()
280 self.pristine_upstream_branch.fetch(upstream_branch,
281- last_revision=upstream_revision)
282+ last_revision=revid)
283 upstream_branch.tags.merge_to(self.pristine_upstream_branch.tags)
284- upstream_parents.append(upstream_revision)
285+ parents.append(revid)
286 target_tree = self.pristine_upstream_branch.repository.revision_tree(
287- upstream_revision)
288+ revid)
289 if file_ids_from is not None:
290 upstream_trees = file_ids_from + upstream_trees
291 if self.tree:
292@@ -841,8 +862,8 @@
293 else:
294 self_tree = self.branch.basis_tree()
295 self_tree.lock_read()
296- if len(upstream_parents) > 0:
297- parent_revid = upstream_parents[0]
298+ if len(parents) > 0:
299+ parent_revid = parents[0]
300 else:
301 parent_revid = NULL_REVISION
302 self.pristine_upstream_tree.pull(self.pristine_upstream_tree.branch,
303@@ -857,16 +878,22 @@
304 target_tree=target_tree)
305 finally:
306 self_tree.unlock()
307+ if component is None:
308+ exclude = [tb[1] for tb in upstream_tarballs if tb[1] is not None]
309+ else:
310+ exclude = []
311 (tag, revid) = self.pristine_upstream_source.import_component_tarball(
312- package, version, self.pristine_upstream_tree, upstream_parents, component,
313- md5, tarball, author=author, timestamp=timestamp)
314+ package, version, self.pristine_upstream_tree, parents,
315+ component, md5, tarball, author=author, timestamp=timestamp,
316+ exclude=exclude)
317+ self.pristine_upstream_branch.generate_revision_history(revid)
318 ret.append((component, tag, revid))
319 self.branch.fetch(self.pristine_upstream_branch)
320 self.branch.tags.set_tag(tag, revid)
321 return ret
322
323 def import_upstream_tarballs(self, tarballs, package, version, parents,
324- upstream_branch=None, upstream_revision=None):
325+ upstream_branch=None, upstream_revisions=None):
326 """Import an upstream part to the upstream branch.
327
328 :param tarballs: List of tarballs / components to extract
329@@ -876,7 +903,7 @@
330 parents.
331 :param upstream_branch: An upstream branch to associate with the
332 tarball.
333- :param upstream_revision: Upstream revision id
334+ :param upstream_revisions: Upstream revision ids dictionary
335 :param md5sum: hex digest of the md5sum of the tarball, if known.
336 :return: list with (component, tag, revid) tuples
337 """
338@@ -885,7 +912,7 @@
339 return self.import_upstream(tarball_dir, package, version, parents,
340 tarballs,
341 upstream_branch=upstream_branch,
342- upstream_revision=upstream_revision)
343+ upstream_revisions=upstream_revisions)
344 finally:
345 shutil.rmtree(tarball_dir)
346
347@@ -1052,8 +1079,11 @@
348 pull_branch = pull_parents[1][0]
349 pull_version = pull_parents[1][1]
350 if not pull_branch.is_version_native(pull_version):
351- pull_revid = pull_branch.pristine_upstream_source.version_as_revision(
352+ pull_revids = pull_branch.pristine_upstream_source.version_as_revisions(
353 package, pull_version.upstream_version)
354+ if pull_revids.keys() != [None]:
355+ raise MultipleUpstreamTarballsNotSupported()
356+ pull_revid = pull_revids[None]
357 mutter("Initialising upstream from %s, version %s",
358 str(pull_branch), str(pull_version))
359 parents.append(pull_revid)
360@@ -1062,7 +1092,8 @@
361 last_revision=pull_revid)
362 pull_branch.pristine_upstream_branch.tags.merge_to(
363 self.pristine_upstream_branch.tags)
364- return parents
365+ # FIXME: What about other versions ?
366+ return { None: parents }
367
368 def get_changelog_from_source(self, dir):
369 cl_filename = os.path.join(dir, "debian", "changelog")
370@@ -1245,16 +1276,16 @@
371 finally:
372 extractor.cleanup()
373
374- def extract_upstream_tree(self, upstream_tip, basedir):
375+ def extract_upstream_tree(self, upstream_tips, basedir):
376 """Extract upstream_tip to a tempdir as a working tree."""
377 # TODO: should stack rather than trying to use the repository,
378 # as that will be more efficient.
379- # TODO: remove the _extract_upstream_tree alias below.
380 to_location = os.path.join(basedir, "upstream")
381 # Use upstream_branch if it has been set, otherwise self.branch.
382 source_branch = self.pristine_upstream_branch or self.branch
383+ assert upstream_tips.keys() == [None]
384 dir_to = source_branch.bzrdir.sprout(to_location,
385- revision_id=upstream_tip,
386+ revision_id=upstream_tips[None],
387 accelerator_tree=self.tree)
388 try:
389 self.pristine_upstream_tree = dir_to.open_workingtree()
390@@ -1263,8 +1294,6 @@
391 self.pristine_upstream_tree = dir_to.create_workingtree()
392 self.pristine_upstream_branch = self.pristine_upstream_tree.branch
393
394- _extract_upstream_tree = extract_upstream_tree
395-
396 def _create_empty_upstream_tree(self, basedir):
397 to_location = os.path.join(basedir, "upstream")
398 to_transport = get_transport(to_location)
399@@ -1314,7 +1343,7 @@
400 assert isinstance(previous_version, str), \
401 "Should pass upstream version as str, not Version."
402 try:
403- upstream_tip = self.pristine_upstream_source.version_as_revision(
404+ upstream_tips = self.pristine_upstream_source.version_as_revisions(
405 package, previous_version)
406 except PackageVersionNotPresent:
407 raise BzrCommandError("Unable to find the tag for the "
408@@ -1322,10 +1351,16 @@
409 "%s" % (
410 previous_version,
411 self.pristine_upstream_source.tag_name(previous_version)))
412- self.extract_upstream_tree(upstream_tip, tempdir)
413+ self.extract_upstream_tree(upstream_tips, tempdir)
414+
415+ def has_merged_upstream_revisions(self, this_revision, upstream_repository, upstream_revisions):
416+ graph = self.branch.repository.get_graph(
417+ other_repository=upstream_repository)
418+ return all(graph.is_ancestor(upstream_revision, this_revision)
419+ for upstream_revision in upstream_revisions.values())
420
421 def merge_upstream(self, tarball_filenames, package, version, previous_version,
422- upstream_branch=None, upstream_revision=None, merge_type=None,
423+ upstream_branch=None, upstream_revisions=None, merge_type=None,
424 force=False):
425 assert isinstance(version, str), \
426 "Should pass version as str not %s" % str(type(version))
427@@ -1344,12 +1379,10 @@
428 upstream_branch.lock_read()
429 try:
430 if upstream_branch is not None:
431- if upstream_revision is None:
432- upstream_revision = upstream_branch.last_revision()
433- graph = self.branch.repository.get_graph(
434- other_repository=upstream_branch.repository)
435- if not force and graph.is_ancestor(upstream_revision,
436- self.branch.last_revision()):
437+ if upstream_revisions is None:
438+ upstream_revisions = { None: upstream_branch.last_revision() }
439+ if (not force and
440+ self.has_merged_upstream_revisions(self.branch.last_revision(), upstream_branch.repository, upstream_revisions)):
441 raise UpstreamBranchAlreadyMerged
442 upstream_tarballs = [
443 (os.path.abspath(fn), component, md5sum_filename(fn)) for
444@@ -1358,13 +1391,14 @@
445 tarball_dir = self._extract_tarballs_to_tempdir(upstream_tarballs)
446 try:
447 # FIXME: should use upstream_parents()?
448- parents = []
449+ parents = { None: [] }
450 if self.pristine_upstream_branch.last_revision() != NULL_REVISION:
451- parents = [self.pristine_upstream_branch.last_revision()]
452+ parents = { None: [self.pristine_upstream_branch.last_revision()] }
453 for (component, tag, revid) in self.import_upstream(tarball_dir,
454- package, version, parents, upstream_tarballs=upstream_tarballs,
455+ package, version, parents,
456+ upstream_tarballs=upstream_tarballs,
457 upstream_branch=upstream_branch,
458- upstream_revision=upstream_revision):
459+ upstream_revisions=upstream_revisions):
460 self._fetch_upstream_to_branch(revid)
461 finally:
462 shutil.rmtree(tarball_dir)
463@@ -1377,10 +1411,10 @@
464 # missing a proper history link and a criss-cross merge
465 # then recurses and finds no deeper ancestor.
466 # Use the previous upstream import as the from revision
467- if len(parents) == 0:
468+ if len(parents[None]) == 0:
469 from_revision = NULL_REVISION
470 else:
471- from_revision = parents[0]
472+ from_revision = parents[None][0]
473 conflicts = self.tree.merge_from_branch(
474 self.pristine_upstream_branch, merge_type=merge_type,
475 from_revision=from_revision)
476
477=== modified file 'merge_package.py'
478--- merge_package.py 2011-06-15 13:21:22 +0000
479+++ merge_package.py 2011-09-27 00:50:26 +0000
480@@ -31,7 +31,9 @@
481 from debian_bundle.changelog import Version
482
483 from bzrlib.plugins.builddeb.errors import (
484- SharedUpstreamConflictsWithTargetPackaging)
485+ MultipleUpstreamTarballsNotSupported,
486+ SharedUpstreamConflictsWithTargetPackaging,
487+ )
488 from bzrlib.plugins.builddeb.import_dsc import DistributionBranch
489 from bzrlib.plugins.builddeb.util import find_changelog
490
491@@ -59,8 +61,11 @@
492 for branch in (source, target):
493 db = DistributionBranch(branch, branch)
494 uver = _latest_version(branch).upstream_version
495- results.append((Version(uver),
496- db.pristine_upstream_source.version_as_revision(None, uver)))
497+ upstream_revids = db.pristine_upstream_source.version_as_revisions(None, uver)
498+ if upstream_revids.keys() != [None]:
499+ raise MultipleUpstreamTarballsNotSupported()
500+ upstream_revid = upstream_revids[None]
501+ results.append((Version(uver), upstream_revid))
502
503 return results
504
505@@ -136,7 +141,7 @@
506 try:
507 # Extract the merge target's upstream tree into a temporary
508 # directory.
509- db.extract_upstream_tree(ut_revid, tempdir)
510+ db.extract_upstream_tree({None: ut_revid}, tempdir)
511 tmp_target_utree = db.pristine_upstream_tree
512
513 # Merge upstream branch tips to obtain a shared upstream parent.
514
515=== modified file 'tests/blackbox/test_merge_upstream.py'
516--- tests/blackbox/test_merge_upstream.py 2011-07-20 19:14:43 +0000
517+++ tests/blackbox/test_merge_upstream.py 2011-09-27 00:50:26 +0000
518@@ -98,7 +98,7 @@
519 [(self.tar.tarball, None, md5sum_filename(self.tar.tarball))],
520 "foo",
521 str(self.tar.version),
522- [tree.branch.last_revision()])
523+ { None: [tree.branch.last_revision()]} )
524 package_builder = SourcePackageBuilder("foo",
525 str(self.tar.version)+"-1")
526 package_builder.add_default_control()
527
528=== modified file 'tests/test_import_dsc.py'
529--- tests/test_import_dsc.py 2011-09-09 13:20:42 +0000
530+++ tests/test_import_dsc.py 2011-09-27 00:50:26 +0000
531@@ -213,14 +213,15 @@
532 db.tag_version(version)
533 self.assertEqual(db.revid_of_version(version), revid)
534
535- def test_upstream_version_as_revid(self):
536+ def test_upstream_versions_as_revid(self):
537 db = self.db1
538 tree = self.up_tree1
539 version = "0.1"
540 revid = tree.commit("one")
541 db.tag_upstream_version(version)
542 self.assertEqual(
543- db.pristine_upstream_source.version_as_revision("package", version), revid)
544+ db.pristine_upstream_source.version_as_revisions("package", version),
545+ { None: revid })
546
547 def test_contained_versions(self):
548 db = self.db1
549@@ -710,8 +711,8 @@
550 self.assertEqual(self.tree2.branch.last_revision(), revid)
551 self.assertEqual(self.up_tree2.branch.last_revision(), up_revid)
552 self.assertEqual(self.db2.revid_of_version(version), revid)
553- self.assertEqual(self.db2.pristine_upstream_source.version_as_revision(
554- "package", version.upstream_version), up_revid)
555+ self.assertEqual(self.db2.pristine_upstream_source.version_as_revisions(
556+ "package", version.upstream_version), {None: up_revid})
557
558 def test_pull_from_lesser_branch_with_upstream(self):
559 version = Version("0.1-1")
560@@ -726,8 +727,8 @@
561 self.assertEqual(self.tree2.branch.last_revision(), revid)
562 self.assertEqual(self.up_tree2.branch.last_revision(), up_revid)
563 self.assertEqual(self.db2.revid_of_version(version), revid)
564- self.assertEqual(self.db2.pristine_upstream_source.version_as_revision(
565- "package", version.upstream_version), up_revid)
566+ self.assertEqual(self.db2.pristine_upstream_source.version_as_revisions(
567+ "package", version.upstream_version), {None: up_revid})
568
569 def test_pull_upstream_from_branch(self):
570 version = "0.1"
571@@ -737,8 +738,9 @@
572 self.assertNotEqual(self.up_tree2.branch.last_revision(), up_revid)
573 self.db2.pull_upstream_from_branch(self.db1, "package", version)
574 self.assertEqual(self.up_tree2.branch.last_revision(), up_revid)
575- self.assertEqual(self.db2.pristine_upstream_source.version_as_revision("package", version),
576- up_revid)
577+ self.assertEqual(
578+ self.db2.pristine_upstream_source.version_as_revisions("package", version),
579+ {None: up_revid})
580
581 def check_changes(self, changes, added=[], removed=[], modified=[],
582 renamed=[]):
583@@ -785,7 +787,7 @@
584 element in contents]
585 self.build_tree_contents(contents)
586 self.db1.import_upstream(basedir, "package", version.upstream_version,
587- [], [(None, None, None)])
588+ {}, [(None, None, None)])
589 return version
590
591 def test_import_upstream(self):
592@@ -794,8 +796,8 @@
593 branch = tree.branch
594 rh = branch.revision_history()
595 self.assertEqual(len(rh), 1)
596- self.assertEqual(self.db1.pristine_upstream_source.version_as_revision(
597- "package", version.upstream_version), rh[0])
598+ self.assertEqual(self.db1.pristine_upstream_source.version_as_revisions(
599+ "package", version.upstream_version), {None: rh[0]})
600 rev = branch.repository.get_revision(rh[0])
601 self.assertEqual(rev.message,
602 "Import upstream version %s" % str(version.upstream_version))
603@@ -819,7 +821,7 @@
604 write_to_file(os.path.join(basedir, "README"), "Hi\n")
605 write_to_file(os.path.join(basedir, "BUGS"), "")
606 write_to_file(os.path.join(basedir, "COPYING"), "")
607- self.db1.import_upstream(basedir, "package", version1.upstream_version, [],
608+ self.db1.import_upstream(basedir, "package", version1.upstream_version, {},
609 [(None, None, None)])
610 basedir = name + "-" + str(version2.upstream_version)
611 os.mkdir(basedir)
612@@ -827,13 +829,15 @@
613 write_to_file(os.path.join(basedir, "BUGS"), "")
614 write_to_file(os.path.join(basedir, "NEWS"), "")
615 self.db1.import_upstream(basedir, "package", version2.upstream_version,
616- [self.up_tree1.branch.last_revision()], [(None, None, None)])
617+ { None: [self.up_tree1.branch.last_revision()] }, [(None, None, None)])
618 tree = self.up_tree1
619 branch = tree.branch
620 rh = branch.revision_history()
621 self.assertEqual(len(rh), 2)
622 self.assertEqual(
623- self.db1.pristine_upstream_source.version_as_revision("package", version2.upstream_version), rh[1])
624+ self.db1.pristine_upstream_source.version_as_revisions(
625+ "package", version2.upstream_version),
626+ {None: rh[1]})
627 rev = branch.repository.get_revision(rh[1])
628 self.assertEqual(rev.message,
629 "Import upstream version %s" % str(version2.upstream_version))
630@@ -858,14 +862,14 @@
631 tf.add(basedir)
632 finally:
633 tf.close()
634- self.db1.import_upstream(basedir, "package", version.upstream_version, [],
635+ self.db1.import_upstream(basedir, "package", version.upstream_version, {},
636 upstream_tarballs=[(os.path.abspath(tar_path), None, self.fake_md5_1)])
637 tree = self.up_tree1
638 branch = tree.branch
639 rh = branch.revision_history()
640 self.assertEqual(len(rh), 1)
641- self.assertEqual(self.db1.pristine_upstream_source.version_as_revision(
642- "package", version.upstream_version), rh[0])
643+ self.assertEqual(self.db1.pristine_upstream_source.version_as_revisions(
644+ "package", version.upstream_version), {None: rh[0]})
645 rev = branch.repository.get_revision(rh[0])
646 self.assertEqual(rev.message,
647 "Import upstream version %s" % str(version.upstream_version))
648@@ -887,13 +891,13 @@
649 finally:
650 tf.close()
651 self.db1.import_upstream(basedir, "package", version.upstream_version,
652- [], upstream_tarballs=[(os.path.abspath(tar_path), None, self.fake_md5_1)])
653+ {}, upstream_tarballs=[(os.path.abspath(tar_path), None, self.fake_md5_1)])
654 tree = self.up_tree1
655 branch = tree.branch
656 rh = branch.revision_history()
657 self.assertEqual(len(rh), 1)
658- self.assertEqual(self.db1.pristine_upstream_source.version_as_revision(
659- "package", version.upstream_version), rh[0])
660+ self.assertEqual(self.db1.pristine_upstream_source.version_as_revisions(
661+ "package", version.upstream_version), {None: rh[0]})
662 rev = branch.repository.get_revision(rh[0])
663 self.assertEqual(rev.message,
664 "Import upstream version %s" % str(version.upstream_version))
665@@ -936,13 +940,13 @@
666 finally:
667 f.close()
668 self.db1.import_upstream(basedir, "package", version.upstream_version,
669- [], upstream_tarballs=[(os.path.abspath(tar_path), None, self.fake_md5_1)])
670+ {}, upstream_tarballs=[(os.path.abspath(tar_path), None, self.fake_md5_1)])
671 tree = self.up_tree1
672 branch = tree.branch
673 rh = branch.revision_history()
674 self.assertEqual(len(rh), 1)
675- self.assertEqual(self.db1.pristine_upstream_source.version_as_revision(
676- "package", version.upstream_version), rh[0])
677+ self.assertEqual(self.db1.pristine_upstream_source.version_as_revisions(
678+ "package", version.upstream_version), {None: rh[0]})
679 rev = branch.repository.get_revision(rh[0])
680 self.assertEqual(rev.message,
681 "Import upstream version %s" % str(version.upstream_version))
682@@ -1381,8 +1385,9 @@
683 self.assertEqual(self.db1.revid_of_version(version2), rh1[2])
684 self.assertEqual(self.db1.revid_of_version(version3), rh1[3])
685 self.assertEqual(
686- self.db1.pristine_upstream_source.version_as_revision("package", version1.upstream_version),
687- up_rh1[0])
688+ self.db1.pristine_upstream_source.version_as_revisions(
689+ "package", version1.upstream_version),
690+ {None: up_rh1[0]})
691 self.tree1.lock_read()
692 self.addCleanup(self.tree1.unlock)
693 self.assertFalse(self.db1.is_version_native(version1))
694@@ -1434,11 +1439,13 @@
695 self.assertEqual(self.db1.revid_of_version(version2), rh1[2])
696 self.assertEqual(self.db1.revid_of_version(version3), rh1[3])
697 self.assertEqual(
698- self.db1.pristine_upstream_source.version_as_revision("package", version1.upstream_version),
699- up_rh1[0])
700+ self.db1.pristine_upstream_source.version_as_revisions("package",
701+ version1.upstream_version),
702+ {None: up_rh1[0]})
703 self.assertEqual(
704- self.db1.pristine_upstream_source.version_as_revision("package", version3.upstream_version),
705- up_rh1[1])
706+ self.db1.pristine_upstream_source.version_as_revisions("package",
707+ version3.upstream_version),
708+ {None: up_rh1[1]})
709 self.tree1.lock_read()
710 self.addCleanup(self.tree1.unlock)
711 self.assertFalse(self.db1.is_version_native(version1))
712@@ -1489,11 +1496,13 @@
713 self.assertEqual(self.db1.revid_of_version(version2), rh1[2])
714 self.assertEqual(self.db1.revid_of_version(version3), rh1[3])
715 self.assertEqual(
716- self.db1.pristine_upstream_source.version_as_revision("package", version1.upstream_version),
717- up_rh1[0])
718+ self.db1.pristine_upstream_source.version_as_revisions("package",
719+ version1.upstream_version),
720+ { None: up_rh1[0] })
721 self.assertEqual(
722- self.db1.pristine_upstream_source.version_as_revision("package", version3.upstream_version),
723- up_rh1[1])
724+ self.db1.pristine_upstream_source.version_as_revisions("package",
725+ version3.upstream_version),
726+ { None: up_rh1[1] })
727 self.tree1.lock_read()
728 self.addCleanup(self.tree1.unlock)
729 self.assertFalse(self.db1.is_version_native(version1))
730@@ -1604,7 +1613,7 @@
731 tf.close()
732 conflicts = db.merge_upstream([(tarball_filename, None)], "foo", "0.2", "0.1",
733 upstream_branch=upstream_tree.branch,
734- upstream_revision=upstream_rev)
735+ upstream_revisions={None: upstream_rev})
736 self.assertEqual(0, conflicts)
737
738 def test_merge_upstream_initial_with_removed_debian(self):
739@@ -1644,7 +1653,7 @@
740 tf.close()
741 conflicts = db.merge_upstream([(tarball_filename, None)], "foo", "0.2", "0.1",
742 upstream_branch=upstream_tree.branch,
743- upstream_revision=upstream_rev)
744+ upstream_revisions={None: upstream_rev})
745 # ./debian conflicts.
746 self.assertEqual(3, conflicts)
747
748@@ -1686,7 +1695,7 @@
749 db.merge_upstream([(builder.tar_name(), None)], "package", str(version2),
750 version1.upstream_version,
751 upstream_branch=upstream_tree.branch,
752- upstream_revision=upstream_rev)
753+ upstream_revisions={None: upstream_rev})
754 rh1 = tree.branch.revision_history()
755 self.assertEqual(2, len(rh1))
756 packaging_upstream_tip = tree.get_parent_ids()[1]
757@@ -1765,7 +1774,7 @@
758 version2.upstream_version,
759 version1.upstream_version,
760 upstream_branch=upstream_tree.branch,
761- upstream_revision=upstream_rev2)
762+ upstream_revisions={None: upstream_rev2})
763 self.assertEqual("a-id", tree.path2id("b"))
764
765 def test_merge_upstream_rename_on_top(self):
766@@ -1802,7 +1811,7 @@
767 version2.upstream_version,
768 version1.upstream_version,
769 upstream_branch=upstream_tree.branch,
770- upstream_revision=upstream_rev2)
771+ upstream_revisions={None:upstream_rev2})
772 self.assertEqual("a-id", tree.path2id("b"))
773
774 def test_merge_upstream_rename_in_packaging_branch(self):
775
776=== modified file 'tests/test_upstream.py'
777--- tests/test_upstream.py 2011-09-09 13:20:42 +0000
778+++ tests/test_upstream.py 2011-09-27 00:50:26 +0000
779@@ -25,7 +25,6 @@
780 from base64 import standard_b64encode
781
782 import bz2
783-import gzip
784 import os
785 import tarfile
786 import zipfile
787@@ -432,6 +431,20 @@
788 self.tree.commit("msg")
789 self.assertEquals("2.1+bzr2", source.get_latest_version("foo", "1.0"))
790
791+ def test_version_as_revisions(self):
792+ revid1 = self.tree.commit("msg")
793+ self.tree.branch.tags.set_tag("2.1", self.tree.branch.last_revision())
794+ config = DebBuildConfig(
795+ [('user.conf', True), ('default.conf', False)],
796+ branch=self.tree.branch)
797+ source = UpstreamBranchSource(self.tree.branch,
798+ {"2.1": self.tree.branch.last_revision()},
799+ config=config)
800+ revid2 = self.tree.commit("msg")
801+ self.assertEquals(revid2,
802+ source.version_as_revision("foo", "2.1+bzr2"))
803+ self.assertEquals({None: revid1}, source.version_as_revisions("foo", "2.1"))
804+
805 def test_version_as_revision(self):
806 revid1 = self.tree.commit("msg")
807 self.tree.branch.tags.set_tag("2.1", self.tree.branch.last_revision())
808@@ -699,14 +712,24 @@
809 class TestUpstreamTagVersion(TestCase):
810
811 def test_simple_upstream(self):
812- self.assertEqual('2.1', upstream_tag_version('upstream-2.1'))
813+ self.assertEqual((None, '2.1'), upstream_tag_version('upstream-2.1'))
814
815 def test_distro_upstream(self):
816- self.assertEqual('2.1',
817+ self.assertEqual((None, '2.1'),
818 upstream_tag_version('upstream-debian-2.1'))
819
820 def test_git_upstream(self):
821- self.assertEqual('2.1', upstream_tag_version('upstream/2.1'))
822+ self.assertEqual((None, '2.1'), upstream_tag_version('upstream/2.1'))
823+
824+ def test_git_upstream_component(self):
825+ self.assertEqual(("lib", '2.1'), upstream_tag_version('upstream/2.1/lib'))
826+
827+ def test_simple_upstream_component(self):
828+ self.assertEqual(("lib", '2.1'), upstream_tag_version('upstream-2.1/lib'))
829+
830+ def test_distro_upstream_component(self):
831+ self.assertEqual(("lib", '2.1'),
832+ upstream_tag_version('upstream-debian-2.1/lib'))
833
834
835 class PristineTarSourceTests(TestCaseWithTransport):
836@@ -766,14 +789,31 @@
837 rev.properties["deb-pristine-delta"] = standard_b64encode("bla")
838 self.assertEquals("bla", self.source.pristine_tar_delta(rev))
839
840- def test_version_as_revision_missing(self):
841+ def test_version_as_revisions_missing(self):
842 self.assertRaises(PackageVersionNotPresent,
843- self.source.version_as_revision, None, "1.2")
844-
845- def test_version_as_revision(self):
846- revid1 = self.tree.commit("msg")
847- self.tree.branch.tags.set_tag("upstream-2.1", revid1)
848- self.assertEquals(revid1, self.source.version_as_revision(None, "2.1"))
849+ self.source.version_as_revisions, None, "1.2")
850+
851+ def test_version_as_revisions_single(self):
852+ revid1 = self.tree.commit("msg")
853+ self.tree.branch.tags.set_tag("upstream-2.1", revid1)
854+ self.assertEquals({None: revid1},
855+ self.source.version_as_revisions(None, "2.1"))
856+
857+ def test_version_component_as_revision(self):
858+ revid1 = self.tree.commit("msg")
859+ self.tree.branch.tags.set_tag("upstream-2.1/lib", revid1)
860+ self.assertEquals(revid1,
861+ self.source.version_component_as_revision(None, "2.1", "lib"))
862+
863+ def test_version_as_revisions(self):
864+ revid1 = self.tree.commit("msg")
865+ revid2 = self.tree.commit("msg")
866+ self.tree.branch.tags.set_tag("upstream-2.1", revid1)
867+ self.tree.branch.tags.set_tag("upstream-2.1/lib", revid2)
868+ self.assertEquals({ None: revid1, "lib": revid2 },
869+ self.source.version_as_revisions(None, "2.1", [
870+ ("upstream_2.1.orig.tar.gz", None, "somemd5sum"),
871+ ("upstream_2.1.orig-lib.tar.gz", "lib", "othermd5sum")]))
872
873
874 class TarfileSourceTests(TestCaseWithTransport):
875
876=== modified file 'upstream/__init__.py'
877--- upstream/__init__.py 2011-09-07 20:11:50 +0000
878+++ upstream/__init__.py 2011-09-27 00:50:26 +0000
879@@ -75,15 +75,16 @@
880 """
881 raise NotImplementedError(self.get_latest_version)
882
883- def version_as_revision(self, package, version):
884- """Lookup the revision id for a particular version.
885+ def version_as_revisions(self, package, version, tarballs=None):
886+ """Lookup the revision ids for a particular version.
887
888 :param package: Package name
889- :package version: Version string
890+ :param version: Version string
891 :raise PackageVersionNotPresent: When the specified version was not
892 found
893+ :return: dictionary mapping component names to revision ids
894 """
895- raise NotImplementedError(self.version_as_revision)
896+ raise NotImplementedError(self.version_as_revisions)
897
898 def has_version(self, package, version, md5=None):
899 """Check whether this upstream source contains a particular package.
900@@ -94,12 +95,14 @@
901 """
902 raise NotImplementedError(self.has_version)
903
904- def fetch_tarballs(self, package, version, target_dir):
905+ def fetch_tarballs(self, package, version, target_dir, components=None):
906 """Fetch the source tarball for a particular version.
907
908 :param package: Name of the package
909 :param version: Version string of the version to fetch
910 :param target_dir: Directory in which to store the tarball
911+ :param components: List of component names to fetch; may be None,
912+ in which case the backend will have to find out.
913 :return: Paths of the fetched tarballs
914 """
915 raise NotImplementedError(self.fetch_tarballs)
916@@ -113,7 +116,7 @@
917 """Upstream source that uses apt-source."""
918
919 def fetch_tarballs(self, package, upstream_version, target_dir,
920- _apt_pkg=None):
921+ _apt_pkg=None, components=None):
922 if _apt_pkg is None:
923 import apt_pkg
924 else:
925@@ -197,7 +200,7 @@
926 note("get-orig-source did not create file with prefix %s", prefix)
927 return None
928
929- def fetch_tarballs(self, package, version, target_dir):
930+ def fetch_tarballs(self, package, version, target_dir, components=None):
931 if self.larstiq:
932 rules_name = 'rules'
933 else:
934@@ -279,7 +282,7 @@
935 os.unlink(tempfilename)
936 return self._xml_report_extract_upstream_version(stdout)
937
938- def fetch_tarballs(self, package, version, target_dir):
939+ def fetch_tarballs(self, package, version, target_dir, components=None):
940 note("Using uscan to look for the upstream tarball.")
941 try:
942 tempfilename = self._export_watchfile()
943@@ -326,7 +329,7 @@
944 finally:
945 shutil.rmtree(tmpdir)
946
947- def fetch_tarballs(self, package, version, target_dir):
948+ def fetch_tarballs(self, package, version, target_dir, components=None):
949 note("Using the current branch without the 'debian' directory "
950 "to create the tarball")
951 tarball_path = self._tarball_path(package, version, None, target_dir)
952@@ -346,10 +349,10 @@
953 def __repr__(self):
954 return "%s(%r)" % (self.__class__.__name__, self._sources)
955
956- def fetch_tarballs(self, package, version, target_dir):
957+ def fetch_tarballs(self, package, version, target_dir, components=None):
958 for source in self._sources:
959 try:
960- paths = source.fetch_tarballs(package, version, target_dir)
961+ paths = source.fetch_tarballs(package, version, target_dir, components)
962 except PackageVersionNotPresent:
963 pass
964 else:
965@@ -496,7 +499,7 @@
966 self.path = path
967 self.version = version
968
969- def fetch_tarballs(self, package, version, target_dir):
970+ def fetch_tarballs(self, package, version, target_dir, components=None):
971 if version != self.version:
972 raise PackageVersionNotPresent(package, version, self)
973 dest_name = new_tarball_name(package, version, self.path)
974@@ -541,7 +544,7 @@
975 else:
976 self.project = project
977
978- def fetch_tarballs(self, package, version, target_dir):
979+ def fetch_tarballs(self, package, version, target_dir, components=None):
980 release = self.project.getRelease(version=version)
981 if release is None:
982 raise PackageVersionNotPresent(package, version, self)
983
984=== modified file 'upstream/branch.py'
985--- upstream/branch.py 2011-06-26 21:02:48 +0000
986+++ upstream/branch.py 2011-09-27 00:50:26 +0000
987@@ -28,7 +28,10 @@
988 from bzrlib.revisionspec import RevisionSpec
989 from bzrlib.trace import note
990
991-from bzrlib.plugins.builddeb.errors import PackageVersionNotPresent
992+from bzrlib.plugins.builddeb.errors import (
993+ MultipleUpstreamTarballsNotSupported,
994+ PackageVersionNotPresent,
995+ )
996 from bzrlib.plugins.builddeb.upstream import UpstreamSource
997 from bzrlib.plugins.builddeb.util import (
998 export,
999@@ -228,7 +231,7 @@
1000 else:
1001 self.upstream_revision_map = upstream_revision_map
1002
1003- def version_as_revision(self, package, version):
1004+ def version_as_revision(self, package, version, tarballs=None):
1005 assert isinstance(version, str)
1006 if version in self.upstream_revision_map:
1007 revspec = self.upstream_revision_map[version]
1008@@ -242,6 +245,13 @@
1009 raise PackageVersionNotPresent(package, version, self)
1010 raise PackageVersionNotPresent(package, version, self)
1011
1012+ def version_as_revisions(self, package, version, tarballs=None):
1013+ # FIXME: Support multiple upstream locations if there are multiple
1014+ # components
1015+ if tarballs is not None and tarballs.keys() != [None]:
1016+ raise MultipleUpstreamTarballsNotSupported()
1017+ return { None: self.version_as_revision(package, version, tarballs) }
1018+
1019 def get_latest_version(self, package, current_version):
1020 return self.get_version(package, current_version,
1021 self.upstream_branch.last_revision())
1022@@ -254,7 +264,7 @@
1023 finally:
1024 self.upstream_branch.unlock()
1025
1026- def fetch_tarballs(self, package, version, target_dir):
1027+ def fetch_tarballs(self, package, version, target_dir, components=None):
1028 self.upstream_branch.lock_read()
1029 try:
1030 revid = self.version_as_revision(package, version)
1031
1032=== modified file 'upstream/pristinetar.py'
1033--- upstream/pristinetar.py 2011-09-09 13:20:42 +0000
1034+++ upstream/pristinetar.py 2011-09-27 00:50:26 +0000
1035@@ -39,13 +39,17 @@
1036 subprocess_setup,
1037 )
1038
1039-from bzrlib import osutils
1040+from bzrlib import (
1041+ osutils,
1042+ revision as _mod_revision,
1043+ )
1044 from bzrlib.errors import (
1045 BzrError,
1046 NoSuchRevision,
1047 NoSuchTag,
1048 )
1049 from bzrlib.trace import (
1050+ mutter,
1051 note,
1052 warning,
1053 )
1054@@ -156,42 +160,35 @@
1055 self.branch.tags.set_tag(tag_name, revid)
1056 return tag_name, revid
1057
1058- def import_tarballs(self, package, version, tree, parent_ids, tarballs,
1059- timestamp=None, author=None):
1060- """Import the upstream tarballs.
1061-
1062- :param package: Package name
1063- :param version: Package version
1064- :param path: Path with tree to import
1065- :param parent_ids: Parent revisions
1066- :param tarballs: List of (path, component, md5)
1067- :param timestamp: Optional timestamp for new commits
1068- :param author: Optional author for new commits
1069- :return: List of tuples with (component, tag, revid)
1070- """
1071- ret = []
1072- for (tarball, component, md5) in tarballs:
1073- (tag, revid) = self.import_component_tarball(
1074- package, version, tree, parent_ids, component,
1075- md5, tarball, author=author, timestamp=timestamp)
1076- ret.append((component, tag, revid))
1077- return ret
1078-
1079 def import_component_tarball(self, package, version, tree, parent_ids,
1080- component=None, md5=None, tarball=None, author=None, timestamp=None):
1081+ component=None, md5=None, tarball=None, author=None, timestamp=None,
1082+ subdir=None, exclude=None):
1083 """Import a tarball.
1084
1085 :param package: Package name
1086 :param version: Upstream version
1087+ :param parent_ids: Dictionary mapping component names to revision ids
1088 :param component: Component name (None for base)
1089+ :param exclude: Exclude directories
1090 """
1091- if component is not None:
1092- raise BzrError("Importing non-base tarballs not yet supported")
1093- tree.set_parent_ids(parent_ids)
1094+ if exclude is None:
1095+ exclude = []
1096+ def include_change(c):
1097+ if not exclude:
1098+ return True
1099+ path = c[1][1]
1100+ if path is None:
1101+ return True
1102+ for e in exclude:
1103+ if path == e or path.startswith(e+"/"):
1104+ return False
1105+ else:
1106+ return True
1107 revprops = {}
1108 if md5 is not None:
1109 revprops["deb-md5"] = md5
1110- delta = self.make_pristine_tar_delta(tree, tarball)
1111+ delta = self.make_pristine_tar_delta(tree, tarball, subdir=subdir,
1112+ exclude=exclude)
1113 uuencoded = standard_b64encode(delta)
1114 if tarball.endswith(".tar.bz2"):
1115 revprops["deb-pristine-delta-bz2"] = uuencoded
1116@@ -208,9 +205,32 @@
1117 message = "Import upstream version %s" % (version,)
1118 if component is not None:
1119 message += ", component %s" % component
1120- revid = tree.commit(message, revprops=revprops, timestamp=timestamp,
1121- timezone=timezone)
1122- tag_name, _ = self.tag_version(version, revid=revid)
1123+ if len(parent_ids) == 0:
1124+ base_revid = _mod_revision.NULL_REVISION
1125+ else:
1126+ base_revid = parent_ids[0]
1127+ basis_tree = tree.branch.repository.revision_tree(base_revid)
1128+ tree.lock_write()
1129+ try:
1130+ builder = tree.branch.get_commit_builder(parents=parent_ids,
1131+ revprops=revprops, timestamp=timestamp, timezone=timezone)
1132+ builder.will_record_deletes()
1133+ try:
1134+ changes = [c for c in tree.iter_changes(basis_tree) if
1135+ include_change(c)]
1136+ list(builder.record_iter_changes(tree, base_revid, changes))
1137+ builder.finish_inventory()
1138+ except:
1139+ builder.abort()
1140+ raise
1141+ revid = builder.commit(message)
1142+ tag_name, _ = self.tag_version(version, revid=revid, component=component)
1143+ tree.update_basis_by_delta(revid, builder.get_basis_delta())
1144+ finally:
1145+ tree.unlock()
1146+ mutter(
1147+ 'imported %s version %s component %r as revid %s, tagged %s',
1148+ package, version, component, revid, tag_name)
1149 return tag_name, revid
1150
1151 def fetch_component_tarball(self, package, version, component, target_dir):
1152@@ -219,13 +239,13 @@
1153 rev = self.branch.repository.get_revision(revid)
1154 except NoSuchRevision:
1155 raise PackageVersionNotPresent(package, version, self)
1156- note("Using pristine-tar to reconstruct the needed tarball.")
1157 if self.has_pristine_tar_delta(rev):
1158 format = self.pristine_tar_format(rev)
1159 else:
1160 format = 'gz'
1161 target_filename = self._tarball_path(package, version, component,
1162 target_dir, format=format)
1163+ note("Using pristine-tar to reconstruct %s.", os.path.basename(target_filename))
1164 try:
1165 self.reconstruct_pristine_tar(revid, package, version, target_filename)
1166 except PristineTarError:
1167@@ -234,8 +254,15 @@
1168 raise PackageVersionNotPresent(package, version, self)
1169 return target_filename
1170
1171- def fetch_tarballs(self, package, version, target_dir):
1172- return [self.fetch_component_tarball(package, version, None, target_dir)]
1173+ def fetch_tarballs(self, package, version, target_dir, components=None):
1174+ if components is None:
1175+ # Scan tags for components
1176+ try:
1177+ components = self._components_by_version()[version].keys()
1178+ except KeyError:
1179+ raise PackageVersionNotPresent(package, version, self)
1180+ return [self.fetch_component_tarball(package, version, component, target_dir)
1181+ for component in components]
1182
1183 def _has_revision(self, revid, md5=None):
1184 self.branch.lock_read()
1185@@ -256,14 +283,16 @@
1186 "revision %s", revid)
1187 return True
1188
1189- def version_as_revision(self, package, version, tarballs=None):
1190+ def version_as_revisions(self, package, version, tarballs=None):
1191 if tarballs is None:
1192- return self.version_component_as_revision(package, version, component=None)
1193- elif len(tarballs) > 1:
1194- raise MultipleUpstreamTarballsNotSupported()
1195- else:
1196- return self.version_component_as_revision(package, version, tarballs[0][1],
1197- tarballs[0][2])
1198+ # FIXME: What if there are multiple tarballs?
1199+ return {
1200+ None: self.version_component_as_revision(package, version, component=None) }
1201+ ret = {}
1202+ for (tarball, component, md5) in tarballs:
1203+ ret[component] = self.version_component_as_revision(
1204+ package, version, component, md5)
1205+ return ret
1206
1207 def version_component_as_revision(self, package, version, component, md5=None):
1208 assert isinstance(version, str)
1209@@ -359,7 +388,7 @@
1210 finally:
1211 shutil.rmtree(tmpdir)
1212
1213- def make_pristine_tar_delta(self, tree, tarball_path):
1214+ def make_pristine_tar_delta(self, tree, tarball_path, subdir=None, exclude=None):
1215 tmpdir = tempfile.mkdtemp(prefix="builddeb-pristine-")
1216 try:
1217 dest = os.path.join(tmpdir, "orig")
1218@@ -367,22 +396,29 @@
1219 try:
1220 for (dp, ie) in tree.inventory.iter_entries():
1221 ie._read_tree_state(dp, tree)
1222- export(tree, dest, format='dir')
1223+ export(tree, dest, format='dir', subdir=subdir)
1224 finally:
1225 tree.unlock()
1226 return make_pristine_tar_delta(dest, tarball_path)
1227 finally:
1228 shutil.rmtree(tmpdir)
1229
1230+ def _components_by_version(self):
1231+ ret = {}
1232+ for tag_name, tag_revid in self.branch.tags.get_tag_dict().iteritems():
1233+ if not is_upstream_tag(tag_name):
1234+ continue
1235+ (component, version) = upstream_tag_version(tag_name)
1236+ ret.setdefault(version, {})[component] = tag_revid
1237+ return ret
1238+
1239 def iter_versions(self):
1240 """Iterate over all upstream versions.
1241
1242 :return: Iterator over (tag_name, version, revid) tuples
1243 """
1244- for tag_name, tag_revid in self.branch.tags.get_tag_dict().iteritems():
1245- if not is_upstream_tag(tag_name):
1246- continue
1247- yield (tag_name, upstream_tag_version(tag_name), tag_revid)
1248+ ret = self._components_by_version()
1249+ return ret.iteritems()
1250
1251
1252 def is_upstream_tag(tag):
1253@@ -398,7 +434,7 @@
1254 """Return the upstream version portion of an upstream tag name.
1255
1256 :param tag: The string name of the tag.
1257- :return: The version portion of the tag.
1258+ :return: tuple with version portion of the tag and component name
1259 """
1260 assert is_upstream_tag(tag), "Not an upstream tag: %s" % tag
1261 if tag.startswith('upstream/'):
1262@@ -409,4 +445,9 @@
1263 tag = tag[len('debian-'):]
1264 elif tag.startswith('ubuntu-'):
1265 tag = tag[len('ubuntu-'):]
1266- return tag
1267+ if not '/' in tag:
1268+ return (None, tag)
1269+ (version, component) = tag.rsplit('/', 1)
1270+ if component == "":
1271+ component = None
1272+ return (component, version)

Subscribers

People subscribed via source and target branches