[Pkg-bazaar-commits] ./bzr-builddeb/trunk r356: Add UpstreamSource that abstracts methods more.
James Westby
james.westby at canonical.com
Sun Jul 26 08:05:34 UTC 2009
------------------------------------------------------------
revno: 356
committer: James Westby <james.westby at canonical.com>
branch nick: trunk
timestamp: Sun 2009-07-26 10:05:34 +0200
message:
Add UpstreamSource that abstracts methods more.
They currently can only provide the source for a specific version if they can
find it. The intention is that they will also be able to list availble
versions and the like at some point.
Thanks Jelmer.
modified:
cmds.py
directory.py
import_dsc.py
tests/test_upstream.py
upstream.py
------------------------------------------------------------
revno: 334.4.1
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Wed 2009-04-15 15:41:09 +0200
message:
Store available sources in a list rather than checking each manually.
modified:
upstream.py
------------------------------------------------------------
revno: 334.4.2
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Wed 2009-04-15 16:32:25 +0200
message:
Move all upstream sources to separate objects.
modified:
upstream.py
------------------------------------------------------------
revno: 334.4.3
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Wed 2009-04-15 17:41:56 +0200
message:
Move apt-related functions onto AptSource.
modified:
tests/test_upstream.py
upstream.py
------------------------------------------------------------
revno: 334.4.4
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Wed 2009-04-15 21:49:24 +0200
message:
Move all source functions onto objects.
modified:
tests/test_upstream.py
upstream.py
------------------------------------------------------------
revno: 334.4.5
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Wed 2009-04-15 22:06:39 +0200
message:
Support parsing revision id from version string.
modified:
upstream.py
------------------------------------------------------------
revno: 334.4.6
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Wed 2009-04-15 22:13:40 +0200
message:
Use UpstreamBranchSource inside of merge-upstream.
modified:
cmds.py
------------------------------------------------------------
revno: 334.4.7
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Wed 2009-04-15 22:50:33 +0200
message:
Fix merging of upstream branch in merge-upstream.
modified:
cmds.py
import_dsc.py
upstream.py
------------------------------------------------------------
revno: 334.4.8
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Thu 2009-04-16 00:06:09 +0200
message:
Add a stacked upstream source object.
modified:
upstream.py
------------------------------------------------------------
revno: 334.4.9
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: obj
timestamp: Thu 2009-04-16 01:17:50 +0200
message:
Fix tests.
modified:
tests/test_upstream.py
upstream.py
------------------------------------------------------------
revno: 334.2.3
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Wed 2009-04-15 23:36:10 +0200
message:
Use common function for iterating over the available tags.
modified:
import_dsc.py
------------------------------------------------------------
revno: 334.2.4
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: trunk
timestamp: Thu 2009-04-16 00:04:11 +0200
message:
Support more tags for upstream versions.
modified:
import_dsc.py
-------------- next part --------------
=== modified file 'cmds.py'
--- a/cmds.py 2009-07-15 18:41:07 +0000
+++ b/cmds.py 2009-07-26 08:05:34 +0000
@@ -34,7 +34,6 @@
urlutils,
)
from bzrlib.branch import Branch
-from bzrlib.bzrdir import BzrDir
from bzrlib.commands import Command
from bzrlib.errors import (BzrCommandError,
NoWorkingTree,
@@ -74,7 +73,7 @@
MergeModeDistiller,
NativeSourceDistiller,
)
-from bzrlib.plugins.builddeb.upstream import UpstreamProvider
+from bzrlib.plugins.builddeb.upstream import UpstreamProvider, UpstreamBranchSource
from bzrlib.plugins.builddeb.util import (find_changelog,
get_export_upstream_revision,
find_last_distribution,
@@ -212,7 +211,12 @@
is_local = urlparse.urlsplit(location)[0] in ('', 'file')
if is_local:
os.chdir(location)
- tree, branch, relpath = BzrDir.open_containing_tree_or_branch(location)
+ try:
+ tree, _ = WorkingTree.open_containing(location)
+ branch = tree.branch
+ except NoWorkingTree:
+ tree = None
+ branch, _ = Branch.open_containing(location)
return tree, branch, is_local
def _get_build_tree(self, revision, tree, branch):
@@ -574,11 +578,10 @@
tarball_filename = os.path.join(orig_dir, dest_name)
if upstream_branch and no_tarball:
- info("Exporting the upstream branch to create the tarball")
- rev_tree = upstream_branch.repository.revision_tree(
+ upstream = UpstreamBranchSource(upstream_branch,
upstream_revision)
- export(rev_tree, tarball_filename, format='tgz',
- root="%s-%s" % (package, version.upstream_version))
+ upstream.get_specific_version(package, version.upstream_version,
+ orig_dir)
else:
try:
repack_tarball(location, dest_name, target_dir=orig_dir)
=== modified file 'directory.py'
--- a/directory.py 2009-03-23 23:50:11 +0000
+++ b/directory.py 2009-04-15 23:17:50 +0000
@@ -86,15 +86,5 @@
else:
return urls[version]["Git"]
- if "Hg" in urls[version]:
- try:
- import bzrlib.plugins.hg
- except ImportError:
- info("This package uses hg. If you would like to "
- "access it with bzr then please install bzr-hg"
- "and re-run the command.")
- else:
- return urls[version]["Hg"]
-
raise errors.InvalidURL(path=url,
extra='unsupported VCSes %r found' % urls[version].keys())
=== modified file 'import_dsc.py'
--- a/import_dsc.py 2009-07-21 22:49:34 +0000
+++ b/import_dsc.py 2009-07-26 08:05:34 +0000
@@ -57,6 +57,7 @@
)
from bzrlib.export import export
from bzrlib.osutils import file_iterator, isdir, basename, splitpath
+from bzrlib.revisionspec import RevisionSpec
from bzrlib.revision import NULL_REVISION
from bzrlib.trace import warning, info, mutter
from bzrlib.transform import TreeTransform, cook_conflicts, resolve_conflicts
@@ -73,7 +74,7 @@
UpstreamAlreadyImported,
UpstreamBranchAlreadyMerged,
)
-from bzrlib.plugins.builddeb.util import get_commit_info_from_changelog
+from bzrlib.plugins.builddeb.util import get_commit_info_from_changelog, get_snapshot_revision
files_to_ignore = set(['.cvsignore', '.arch-inventory', '.bzrignore',
@@ -1634,16 +1635,23 @@
"Should use self.upstream_branch if set"
tempdir = tempfile.mkdtemp(dir=os.path.join(self.tree.basedir, '..'))
try:
+ previous_upstream_revision = get_snapshot_revision(previous_version.upstream_version)
if previous_version is not None:
- if not self.has_upstream_version_in_packaging_branch(
+ if self.has_upstream_version_in_packaging_branch(
previous_version.upstream_version):
+ upstream_tip = self._revid_of_upstream_version_from_branch(
+ previous_version.upstream_version)
+ self._extract_upstream_tree(upstream_tip, tempdir)
+ elif (upstream_branch is not None and
+ previous_upstream_revision is not None):
+ upstream_tip = RevisionSpec.from_string(previous_upstream_revision).as_revision_id(upstream_branch)
+ assert isinstance(upstream_tip, str)
+ self._extract_upstream_tree(upstream_tip, tempdir)
+ else:
raise BzrCommandError("Unable to find the tag for the "
"previous upstream version, %s, in the branch: "
"%s" % (previous_version,
self.upstream_tag_name(previous_version)))
- upstream_tip = self._revid_of_upstream_version_from_branch(
- previous_version.upstream_version)
- self._extract_upstream_tree(upstream_tip, tempdir)
else:
self._create_empty_upstream_tree(tempdir)
if self.has_upstream_version_in_packaging_branch(version.upstream_version):
=== modified file 'tests/test_upstream.py'
--- a/tests/test_upstream.py 2009-07-15 18:36:36 +0000
+++ b/tests/test_upstream.py 2009-07-26 08:05:34 +0000
@@ -24,14 +24,18 @@
from debian_bundle.changelog import Version
-from bzrlib.tests import TestCaseWithTransport
+from bzrlib.tests import (
+ TestCase,
+ TestCaseWithTransport,
+ )
from bzrlib.plugins.builddeb.errors import (
MissingUpstreamTarball,
)
from bzrlib.plugins.builddeb.upstream import (
UpstreamProvider,
- get_apt_command_for_source,
- provide_with_apt,
+ UpstreamSource,
+ AptSource,
+ PristineTarSource,
)
from bzrlib.plugins.builddeb.util import (
get_parent_dir,
@@ -39,7 +43,7 @@
)
-class MockProvider(object):
+class MockProvider(UpstreamSource):
def create_target(self, path):
parent_dir = get_parent_dir(path)
@@ -51,9 +55,6 @@
finally:
f.close()
- def tarball_name(self, package, upstream_version):
- return tarball_name(package, upstream_version)
-
class MockAptProvider(MockProvider):
@@ -64,14 +65,14 @@
self.upstream_version = None
self.target_dir = None
- def provide(self, package, upstream_version, target_dir):
+ def get_specific_version(self, package, upstream_version, target_dir):
self.called_times += 1
self.package = package
self.upstream_version = upstream_version
self.target_dir = target_dir
if self.find:
self.create_target(os.path.join(target_dir,
- self.tarball_name(package, upstream_version)))
+ tarball_name(package, upstream_version)))
return self.find
@@ -97,7 +98,7 @@
self.target_dir = target_dir
if self.find:
self.create_target(os.path.join(target_dir,
- self.tarball_name(package, upstream_version)))
+ tarball_name(package, upstream_version)))
return self.find
@@ -226,23 +227,6 @@
return self.sources
-class MockAptCaller(object):
-
- def __init__(self, work=False):
- self.work = work
- self.called = 0
- self.package = None
- self.version_str = None
- self.target_dir = None
-
- def call(self, package, version_str, target_dir):
- self.package = package
- self.version_str = version_str
- self.target_dir = target_dir
- self.called += 1
- return self.work
-
-
class UpstreamProviderTests(TestCaseWithTransport):
def setUp(self):
@@ -258,20 +242,22 @@
self.store_dir = "store"
self.provider = UpstreamProvider(self.tree, self.branch,
self.package, self.version, self.store_dir)
+ self.provider._sources = []
self.providers = {}
- self.providers["apt"]= MockAptProvider()
- self.provider._apt_provider = self.providers["apt"].provide
+ self.providers["apt"] = MockAptProvider()
+ self.provider._sources.append(self.providers["apt"])
self.providers["uscan"] = MockUscanProvider()
- self.provider._uscan_provider = self.providers["uscan"].provide
+ self.provider._sources.append(self.providers["uscan"])
self.providers["pristine"] = MockPristineProvider()
- self.provider._pristine_provider = self.providers["pristine"].provide
+ self.provider._sources.append(self.providers["pristine"])
self.providers["orig"] = MockOrigSourceProvider()
- self.provider._orig_source_provider = self.providers["orig"].provide
+ self.provider._sources.append(self.providers["orig"])
self.providers["upstream"] = MockOtherBranchProvider()
+ self.provider._sources.append(self.providers["upstream"])
self.provider._upstream_branch_provider = \
self.providers["upstream"].provide
self.providers["split"] = MockSplitProvider()
- self.provider._split_provider = self.providers["split"].provide
+ self.provider._sources.append(self.providers["split"])
self.target_dir = "target"
self.target_filename = os.path.join(self.target_dir,
self.desired_tarball_name)
@@ -436,17 +422,37 @@
self.provider.allow_split = True
self.assertSuccesfulCall("uscan", ["pristine", "apt"])
+
+class MockAptCaller(object):
+
+ def __init__(self, work=False):
+ self.work = work
+ self.called = 0
+ self.package = None
+ self.version_str = None
+ self.target_dir = None
+
+ def call(self, package, version_str, target_dir):
+ self.package = package
+ self.version_str = version_str
+ self.target_dir = target_dir
+ self.called += 1
+ return self.work
+
+
+class AptSourceTests(TestCase):
+
def test_get_apt_command_for_source(self):
self.assertEqual("apt-get source -y --only-source --tar-only "
"apackage=someversion",
- get_apt_command_for_source("apackage", "someversion"))
+ AptSource()._get_command("apackage", "someversion"))
def test_apt_provider_no_package(self):
caller = MockAptCaller()
sources = MockSources([])
apt_pkg = MockAptPkg(sources)
- self.assertEqual(False, provide_with_apt("apackage", "0.2",
- "target", _apt_pkg=apt_pkg, _apt_caller=caller))
+ self.assertEqual(False, AptSource().get_specific_version(
+ "apackage", "0.2", "target", _apt_pkg=apt_pkg, _apt_caller=caller))
self.assertEqual(1, apt_pkg.init_called_times)
self.assertEqual(1, apt_pkg.get_pkg_source_records_called_times)
self.assertEqual(1, sources.restart_called_times)
@@ -458,8 +464,8 @@
caller = MockAptCaller()
sources = MockSources(["0.1-1"])
apt_pkg = MockAptPkg(sources)
- self.assertEqual(False, provide_with_apt("apackage", "0.2",
- "target", _apt_pkg=apt_pkg, _apt_caller=caller))
+ self.assertEqual(False, AptSource().get_specific_version(
+ "apackage", "0.2", "target", _apt_pkg=apt_pkg, _apt_caller=caller))
self.assertEqual(1, apt_pkg.init_called_times)
self.assertEqual(1, apt_pkg.get_pkg_source_records_called_times)
self.assertEqual(1, sources.restart_called_times)
@@ -471,8 +477,9 @@
caller = MockAptCaller(work=True)
sources = MockSources(["0.1-1", "0.2-1"])
apt_pkg = MockAptPkg(sources)
- self.assertEqual(True, provide_with_apt("apackage", "0.2",
- "target", _apt_pkg=apt_pkg, _apt_caller=caller.call))
+ self.assertEqual(True, AptSource().get_specific_version(
+ "apackage", "0.2", "target",
+ _apt_pkg=apt_pkg, _apt_caller=caller.call))
self.assertEqual(1, apt_pkg.init_called_times)
self.assertEqual(1, apt_pkg.get_pkg_source_records_called_times)
self.assertEqual(1, sources.restart_called_times)
@@ -488,8 +495,9 @@
caller = MockAptCaller()
sources = MockSources(["0.1-1", "0.2-1"])
apt_pkg = MockAptPkg(sources)
- self.assertEqual(False, provide_with_apt("apackage", "0.2",
- "target", _apt_pkg=apt_pkg, _apt_caller=caller.call))
+ self.assertEqual(False, AptSource().get_specific_version(
+ "apackage", "0.2", "target",
+ _apt_pkg=apt_pkg, _apt_caller=caller.call))
self.assertEqual(1, apt_pkg.init_called_times)
self.assertEqual(1, apt_pkg.get_pkg_source_records_called_times)
self.assertEqual(1, sources.restart_called_times)
=== modified file 'upstream.py'
--- a/upstream.py 2009-07-15 18:36:36 +0000
+++ b/upstream.py 2009-07-26 08:05:34 +0000
@@ -26,120 +26,271 @@
from debian_bundle.changelog import Version
from bzrlib.export import export
+from bzrlib.revisionspec import RevisionSpec
from bzrlib.trace import info
from bzrlib.plugins.builddeb.errors import MissingUpstreamTarball
from bzrlib.plugins.builddeb.import_dsc import DistributionBranch
from bzrlib.plugins.builddeb.repack_tarball import repack_tarball
-
-
-def get_apt_command_for_source(package, version_str):
- return 'apt-get source -y --only-source --tar-only %s=%s' % \
- (package, version_str)
-
-
-def call_apt_for_source(package, version_str, target_dir):
- command = get_apt_command_for_source(package, version_str)
- proc = subprocess.Popen(command, shell=True, cwd=target_dir)
- proc.wait()
- if proc.returncode != 0:
- return False
- return True
-
-
-def provide_with_apt(package, upstream_version, target_dir, _apt_pkg=None,
- _apt_caller=None):
- if _apt_pkg is None:
- import apt_pkg
- else:
- apt_pkg = _apt_pkg
- if _apt_caller is None:
- _apt_caller = call_apt_for_source
- apt_pkg.init()
- sources = apt_pkg.GetPkgSrcRecords()
- sources.Restart()
- info("Using apt to look for the upstream tarball.")
- while sources.Lookup(package):
- if upstream_version \
- == Version(sources.Version).upstream_version:
- if _apt_caller(package, sources.Version, target_dir):
+from bzrlib.plugins.builddeb.util import (
+ get_snapshot_revision,
+ tarball_name,
+ )
+
+
+class UpstreamSource(object):
+ """A source for upstream versions (uscan, get-orig-source, etc)."""
+
+ def get_latest_version(self, package, target_dir):
+ """Fetch the source tarball for the latest available version.
+
+ :param package: Name of the package
+ :param target_dir: Directory in which to store the tarball
+ """
+ raise NotImplemented(self.get_latest_version)
+
+ def get_specific_version(self, package, version, target_dir):
+ """Fetch the source tarball for a particular version.
+
+ :param package: Name of the package
+ :param version: Version string of the version to fetch
+ :param target_dir: Directory in which to store the tarball
+ :return: Boolean indicating whether a tarball was fetched
+ """
+ raise NotImplemented(self.get_specific_version)
+
+ def _tarball_path(self, package, version, target_dir):
+ return os.path.join(target_dir, tarball_name(package, version))
+
+
+class PristineTarSource(UpstreamSource):
+ """Source that uses the pristine-tar revisions in the packaging branch."""
+
+ def __init__(self, tree, branch):
+ self.branch = branch
+ self.tree = tree
+
+ def get_specific_version(self, package, upstream_version, target_dir):
+ target_filename = self._tarball_path(package, upstream_version,
+ target_dir)
+ db = DistributionBranch(self.branch, None, tree=self.tree)
+ if not db.has_upstream_version_in_packaging_branch(upstream_version):
+ return False
+ revid = db._revid_of_upstream_version_from_branch(upstream_version)
+ if not db.has_pristine_tar_delta(revid):
+ return False
+ info("Using pristine-tar to reconstruct the needed tarball.")
+ db.reconstruct_pristine_tar(revid, package, upstream_version,
+ target_filename)
+ return True
+
+
+class AptSource(UpstreamSource):
+ """Upstream source that uses apt-source."""
+
+ def get_specific_version(self, package, upstream_version, target_dir,
+ _apt_pkg=None, _apt_caller=None):
+ if _apt_pkg is None:
+ import apt_pkg
+ else:
+ apt_pkg = _apt_pkg
+ if _apt_caller is None:
+ _apt_caller = self._run_apt_source
+ apt_pkg.init()
+ sources = apt_pkg.GetPkgSrcRecords()
+ sources.Restart()
+ info("Using apt to look for the upstream tarball.")
+ while sources.Lookup(package):
+ if upstream_version \
+ == Version(sources.Version).upstream_version:
+ if _apt_caller(package, sources.Version, target_dir):
+ return True
+ break
+ info("apt could not find the needed tarball.")
+ return False
+
+ def _get_command(self, package, version_str):
+ return 'apt-get source -y --only-source --tar-only %s=%s' % \
+ (package, version_str)
+
+ def _run_apt_source(self, package, version_str, target_dir):
+ command = self._get_command(package, version_str)
+ proc = subprocess.Popen(command, shell=True, cwd=target_dir)
+ proc.wait()
+ if proc.returncode != 0:
+ return False
+ return True
+
+
+class UpstreamBranchSource(UpstreamSource):
+ """Upstream source that uses the upstream branch."""
+
+ def __init__(self, upstream_branch, upstream_revision=None,
+ fallback_revspec=None):
+ self.upstream_branch = upstream_branch
+ self.upstream_revision = upstream_revision
+ self.fallback_revspec = fallback_revspec
+
+ def _get_revision_id(self, version):
+ if self.upstream_revision is not None:
+ # Explicit revision id to use set
+ return self.upstream_revision
+ revspec = get_snapshot_revision(version)
+ if revspec is None:
+ revspec = self.fallback_revspec
+ if revspec is not None:
+ return RevisionSpec.from_string(
+ revspec).as_revision_id(self.upstream_branch)
+ return self.upstream_branch.last_revision()
+
+ def get_specific_version(self, package, version, target_dir):
+ self.upstream_branch.lock_read()
+ try:
+ revid = self._get_revision_id(version)
+ info("Exporting upstream branch revision %s to create the tarball",
+ revid)
+ target_filename = self._tarball_path(package, version, target_dir)
+ tarball_base = "%s-%s" % (package, version)
+ rev_tree = self.upstream_branch.repository.revision_tree(revid)
+ export(rev_tree, target_filename, 'tgz', tarball_base)
+ return True
+ finally:
+ self.upstream_branch.unlock()
+
+
+class GetOrigSourceSource(UpstreamSource):
+ """Upstream source that uses the get-orig-source rule in debian/rules."""
+
+ def __init__(self, tree, larstiq):
+ self.tree = tree
+ self.larstiq = larstiq
+
+ def _get_orig_source(self, source_dir, desired_tarball_name,
+ target_dir):
+ info("Trying to use get-orig-source to retrieve needed tarball.")
+ command = ["/usr/bin/make", "-f", "debian/rules", "get-orig-source"]
+ proc = subprocess.Popen(command, cwd=source_dir)
+ ret = proc.wait()
+ if ret != 0:
+ info("Trying to run get-orig-source rule failed")
+ return False
+ fetched_tarball = os.path.join(source_dir, desired_tarball_name)
+ if not os.path.exists(fetched_tarball):
+ info("get-orig-source did not create %s", desired_tarball_name)
+ return False
+ repack_tarball(fetched_tarball, desired_tarball_name,
+ target_dir=target_dir)
+ return True
+
+ def get_specific_version(self, package, version, target_dir):
+ if self.larstiq:
+ rules_name = 'rules'
+ else:
+ rules_name = 'debian/rules'
+ rules_id = self.tree.path2id(rules_name)
+ if rules_id is not None:
+ desired_tarball_name = tarball_name(package, version)
+ tmpdir = tempfile.mkdtemp(prefix="builddeb-get-orig-source-")
+ try:
+ base_export_dir = os.path.join(tmpdir, "export")
+ export_dir = base_export_dir
+ if self.larstiq:
+ os.mkdir(export_dir)
+ export_dir = os.path.join(export_dir, "debian")
+ export(self.tree, export_dir, format="dir")
+ return self._get_orig_source(base_export_dir,
+ desired_tarball_name, target_dir)
+ finally:
+ shutil.rmtree(tmpdir)
+ info("No debian/rules file to try and use for a get-orig-source "
+ "rule")
+ return False
+
+
+class UScanSource(UpstreamSource):
+ """Upstream source that uses uscan."""
+
+ def __init__(self, tree, larstiq):
+ self.tree = tree
+ self.larstiq = larstiq
+
+ def _uscan(self, package, upstream_version, watch_file, target_dir):
+ info("Using uscan to look for the upstream tarball.")
+ r = os.system("uscan --upstream-version %s --force-download --rename "
+ "--package %s --watchfile %s --check-dirname-level 0 "
+ "--download --repack --destdir %s --download-version %s" %
+ (upstream_version, package, watch_file, target_dir,
+ upstream_version))
+ if r != 0:
+ info("uscan could not find the needed tarball.")
+ return False
+ return True
+
+ def get_specific_version(self, package, version, target_dir):
+ if self.larstiq:
+ watchfile = 'watch'
+ else:
+ watchfile = 'debian/watch'
+ watch_id = self.tree.path2id(watchfile)
+ if watch_id is None:
+ info("No watch file to use to retrieve upstream tarball.")
+ return False
+ (tmp, tempfilename) = tempfile.mkstemp()
+ try:
+ tmp = os.fdopen(tmp, 'wb')
+ watch = self.tree.get_file_text(watch_id)
+ tmp.write(watch)
+ finally:
+ tmp.close()
+ try:
+ return self._uscan(package, version, tempfilename,
+ target_dir)
+ finally:
+ os.unlink(tempfilename)
+
+
+class SelfSplitSource(UpstreamSource):
+
+ def __init__(self, tree):
+ self.tree = tree
+
+ def _split(self, package, upstream_version, target_filename):
+ tmpdir = tempfile.mkdtemp(prefix="builddeb-get-orig-source-")
+ try:
+ export_dir = os.path.join(tmpdir,
+ "%s-%s" % (package, upstream_version))
+ export(self.tree, export_dir, format="dir")
+ shutil.rmtree(os.path.join(export_dir, "debian"))
+ tar = tarfile.open(target_filename, "w:gz")
+ try:
+ tar.add(export_dir, "%s-%s" % (package, upstream_version))
+ finally:
+ tar.close()
+ return True
+ finally:
+ shutil.rmtree(tmpdir)
+
+ def get_specific_version(self, package, version, target_dir):
+ info("Using the current branch without the 'debian' directory "
+ "to create the tarball")
+ return self._split(package,
+ version, self._tarball_path(package, version, target_dir))
+
+
+class StackedUpstreamSource(UpstreamSource):
+ """An upstream source that checks a list of other upstream sources.
+
+ The first source that can provide a tarball, wins.
+ """
+
+ def __init__(self, sources):
+ self._sources = sources
+
+ def get_specific_version(self, package, version, target_dir):
+ for source in self._sources:
+ if source.get_specific_version(package, version, target_dir):
return True
- break
- info("apt could not find the needed tarball.")
- return False
-
-
-def provide_with_uscan(package, upstream_version, watch_file, target_dir):
- info("Using uscan to look for the upstream tarball.")
- r = os.system("uscan --upstream-version %s --force-download --rename "
- "--package %s --watchfile %s --check-dirname-level 0 "
- "--download --repack --destdir %s --download-version %s" %
- (upstream_version, package, watch_file, target_dir,
- upstream_version))
- if r != 0:
- info("uscan could not find the needed tarball.")
- return False
- return True
-
-
-def provide_with_pristine_tar(tree, branch, package, version,
- target_filename):
- db = DistributionBranch(branch, None, tree=tree)
- if not db.has_upstream_version_in_packaging_branch(version):
- return False
- revid = db._revid_of_upstream_version_from_branch(version)
- if not db.has_pristine_tar_delta(revid):
- return False
- info("Using pristine-tar to reconstruct the needed tarball.")
- db.reconstruct_pristine_tar(revid, package, version, target_filename)
- return True
-
-
-def provide_with_get_orig_source(source_dir, desired_tarball_name,
- target_dir):
- info("Trying to use get-orig-source to retrieve needed tarball.")
- command = ["/usr/bin/make", "-f", "debian/rules", "get-orig-source"]
- proc = subprocess.Popen(command, cwd=source_dir)
- ret = proc.wait()
- if ret != 0:
- info("Trying to run get-orig-source rule failed")
- return False
- fetched_tarball = os.path.join(source_dir, desired_tarball_name)
- if not os.path.exists(fetched_tarball):
- info("get-orig-source did not create %s"
- % desired_tarball_name)
- return False
- repack_tarball(fetched_tarball, desired_tarball_name,
- target_dir=target_dir)
- return True
-
-
-def provide_from_other_branch(branch, revision, target_filename,
- tarball_base):
- branch.lock_read()
- try:
- rev_tree = branch.repository.revision_tree(revision)
- export(rev_tree, target_filename, 'tgz', tarball_base)
- return True
- finally:
- branch.unlock()
-
-
-def provide_by_split(tree, package, upstream_version, target_filename):
- tmpdir = tempfile.mkdtemp(prefix="builddeb-get-orig-source-")
- try:
- export_dir = os.path.join(tmpdir,
- "%s-%s" % (package, upstream_version))
- export(tree, export_dir, format="dir")
- shutil.rmtree(os.path.join(export_dir, "debian"))
- tar = tarfile.open(target_filename, "w:gz")
- try:
- tar.add(export_dir, "%s-%s" % (package, upstream_version))
- finally:
- tar.close()
- return True
- finally:
- shutil.rmtree(tmpdir)
+ return False
class UpstreamProvider(object):
@@ -167,22 +318,23 @@
:param allow_split: Whether the provider can provide the tarball
by exporting the branch and removing the "debian" dir.
"""
- self.tree = tree
- self.branch = branch
self.package = package
self.version = Version(version)
self.store_dir = store_dir
- self.larstiq = larstiq
- self.upstream_branch = upstream_branch
- self.upstream_revision = upstream_revision
- self.allow_split = allow_split
- # for testing
- self._apt_provider = provide_with_apt
- self._uscan_provider = provide_with_uscan
- self._pristine_provider = provide_with_pristine_tar
- self._orig_source_provider = provide_with_get_orig_source
- self._upstream_branch_provider = provide_from_other_branch
- self._split_provider = provide_by_split
+ sources = [
+ PristineTarSource(tree, branch),
+ AptSource(),
+ ]
+ if upstream_branch is not None:
+ sources.append(
+ UpstreamBranchSource(upstream_branch, upstream_revision))
+ sources.extend([
+ GetOrigSourceSource(tree, larstiq),
+ UScanSource(tree, larstiq),
+ ])
+ if allow_split:
+ sources.append(SelfSplitSource(tree))
+ self.source = StackedUpstreamSource(sources)
def provide(self, target_dir):
"""Provide the upstream tarball any way possible.
@@ -215,18 +367,9 @@
if not self.already_exists_in_store():
if not os.path.exists(self.store_dir):
os.makedirs(self.store_dir)
- if self.provide_with_pristine_tar(self.store_dir):
- pass
- elif self.provide_with_apt(self.store_dir):
- pass
- elif self.provide_from_upstream_branch(self.store_dir):
- pass
- elif self.provide_with_get_orig_source(self.store_dir):
- pass
- elif self.provide_with_uscan(self.store_dir):
- pass
- elif self.provide_from_self_by_split(self.store_dir):
- pass
+ self.source.get_specific_version(self.package,
+ self.version.upstream_version,
+ target_dir)
else:
info("Using the upstream tarball that is present in "
"%s" % self.store_dir)
@@ -248,83 +391,8 @@
return True
return False
- def provide_with_apt(self, target_dir):
- return self._apt_provider(self.package, self.version.upstream_version,
- target_dir)
-
- def provide_with_uscan(self, target_dir):
- if self.larstiq:
- watchfile = 'watch'
- else:
- watchfile = 'debian/watch'
- watch_id = self.tree.path2id(watchfile)
- if watch_id is None:
- info("No watch file to use to retrieve upstream tarball.")
- return False
- (tmp, tempfilename) = tempfile.mkstemp()
- try:
- tmp = os.fdopen(tmp, 'wb')
- watch = self.tree.get_file_text(watch_id)
- tmp.write(watch)
- finally:
- tmp.close()
- try:
- return self._uscan_provider(self.package,
- self.version.upstream_version, tempfilename, target_dir)
- finally:
- os.unlink(tempfilename)
-
- def provide_with_pristine_tar(self, target_dir):
- target_filename = os.path.join(target_dir, self._tarball_name())
- return self._pristine_provider(self.tree, self.branch, self.package,
- self.version.upstream_version, target_filename)
-
- def provide_with_get_orig_source(self, target_dir):
- if self.larstiq:
- rules_name = 'rules'
- else:
- rules_name = 'debian/rules'
- rules_id = self.tree.path2id(rules_name)
- if rules_id is not None:
- desired_tarball_name = self._tarball_name()
- tmpdir = tempfile.mkdtemp(prefix="builddeb-get-orig-source-")
- try:
- base_export_dir = os.path.join(tmpdir, "export")
- export_dir = base_export_dir
- if self.larstiq:
- os.mkdir(export_dir)
- export_dir = os.path.join(export_dir, "debian")
- export(self.tree, export_dir, format="dir")
- return self._orig_source_provider(base_export_dir,
- desired_tarball_name, target_dir)
- finally:
- shutil.rmtree(tmpdir)
- info("No debian/rules file to try and use for a get-orig-source "
- "rule")
- return False
-
def _tarball_name(self):
- return "%s_%s.orig.tar.gz" % (self.package,
- self.version.upstream_version)
-
- def provide_from_upstream_branch(self, target_dir):
- if self.upstream_branch is None:
- return False
- assert self.upstream_revision is not None
- info("Exporting the upstream branch to create the tarball")
- target_filename = os.path.join(target_dir, self._tarball_name())
- tarball_base = "%s-%s" % (self.package, self.version.upstream_version)
- return self._upstream_branch_provider(self.upstream_branch,
- self.upstream_revision, target_filename, tarball_base)
-
- def provide_from_self_by_split(self, target_dir):
- if not self.allow_split:
- return False
- info("Using the current branch without the 'debian' directory "
- "to create the tarball")
- target_filename = os.path.join(target_dir, self._tarball_name())
- return self._split_provider(self.tree, self.package,
- self.version.upstream_version, target_filename)
+ return tarball_name(self.package, self.version.upstream_version)
class _MissingUpstreamProvider(UpstreamProvider):
@@ -348,6 +416,7 @@
f.write("I am a tarball, honest\n")
f.close()
+
class _SimpleUpstreamProvider(UpstreamProvider):
"""For tests"""
More information about the Pkg-bazaar-commits
mailing list