Rev 400: Merge trunk. in http://people.canonical.com/~robertc/baz2.0/plugins/builddeb/trunk

Robert Collins robertc at robertcollins.net
Mon Feb 1 20:51:40 GMT 2010


At http://people.canonical.com/~robertc/baz2.0/plugins/builddeb/trunk

------------------------------------------------------------
revno: 400 [merge]
revision-id: robertc at robertcollins.net-20100201205135-r8fy14mnaale7whu
parent: robertc at robertcollins.net-20100201064322-ibllu0bsskckvlzu
parent: james.westby at canonical.com-20100201175219-17gyr4aoszuviv2a
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Tue 2010-02-02 07:51:35 +1100
message:
  Merge trunk.
modified:
  cmds.py                        commands.py-20090212140847-xar6smw4yyx06egs-1
  import_dsc.py                  import_dsc.py-20070624210539-6nr2xvw6kqbh4bzc-1
  tests/__init__.py              __init__.py-20070227200631-dcfgd9vfbozyyhhi-2
  tests/test_import_dsc.py       test_import_dsc.py-20070624210539-6nr2xvw6kqbh4bzc-3
  upstream.py                    upstream.py-20090219103202-594x435451s8tu1g-1
=== modified file 'cmds.py'
--- a/cmds.py	2010-01-29 09:30:27 +0000
+++ b/cmds.py	2010-02-01 17:52:19 +0000
@@ -213,8 +213,6 @@
         if location is None:
             location = "."
         is_local = urlparse.urlsplit(location)[0] in ('', 'file')
-        if is_local:
-            os.chdir(location)
         tree, branch, relpath = BzrDir.open_containing_tree_or_branch(location)
         return tree, branch, is_local
 
@@ -269,26 +267,26 @@
             builder += " " + " ".join(build_options)
         return builder
 
-    def _get_dirs(self, config, is_local, result_dir, result, build_dir, orig_dir):
-        if result_dir is None:
-            result_dir = result
-        if result_dir is None:
-            if is_local:
-                result_dir = config.result_dir
-            else:
-                result_dir = config.user_result_dir
-        if result_dir is not None:
-            result_dir = os.path.realpath(result_dir)
-        if build_dir is None:
-            if is_local:
-                build_dir = config.build_dir or default_build_dir
-            else:
-                build_dir = config.user_build_dir or 'build-area'
-        if orig_dir is None:
-            if is_local:
-                orig_dir = config.orig_dir or default_orig_dir
-            else:
-                orig_dir = config.user_orig_dir or 'build-area'
+    def _get_dirs(self, config, branch, is_local, result_dir, build_dir, orig_dir):
+        def _get_dir(supplied, if_local, if_not):
+            if supplied is None:
+                if is_local:
+                    supplied = if_local
+                else:
+                    supplied = if_not
+            if supplied is not None:
+                if is_local:
+                    supplied = os.path.join(
+                            urlutils.local_path_from_url(branch.base),
+                            supplied)
+                    supplied = os.path.realpath(supplied)
+            return supplied
+
+        result_dir = _get_dir(result_dir, config.result_dir, config.user_result_dir)
+        build_dir = _get_dir(build_dir, config.build_dir or default_build_dir,
+                config.user_build_dir or 'build-area')
+        orig_dir = _get_dir(orig_dir, config.orig_dir or default_orig_dir,
+                config.user_orig_dir or 'build-area')
         return result_dir, build_dir, orig_dir
 
     def _branch_and_build_options(self, branch_or_build_options_list,
@@ -375,8 +373,8 @@
             build_cmd = self._get_build_command(config, builder, quick,
                     build_options)
             (changelog, larstiq) = find_changelog(tree, merge)
-            result_dir, build_dir, orig_dir = self._get_dirs(config, is_local,
-                    result_dir, result, build_dir, orig_dir)
+            result_dir, build_dir, orig_dir = self._get_dirs(config, branch,
+                    is_local, result_dir or result, build_dir, orig_dir)
 
             upstream_branch, upstream_revision = \
                     self._get_upstream_branch(merge, export_upstream,
@@ -433,7 +431,13 @@
                         raise BzrCommandError("Could not find the .changes "
                                 "file from the build: %s" % changes_path)
                 else:
-                    target_dir = result_dir or default_result_dir
+                    if is_local:
+                        target_dir = result_dir or default_result_dir
+                        target_dir = os.path.join(
+                                urlutils.local_path_from_url(branch.base),
+                                target_dir)
+                    else:
+                        target_dir = "."
                     if not os.path.exists(target_dir):
                         os.makedirs(target_dir)
                     dget_changes(changes_path, target_dir)
@@ -486,7 +490,7 @@
             entry_description = "New upstream snapshot."
         else:
             entry_description = "New upstream release."
-        proc = subprocess.Popen(["/usr/bin/dch", "-v",
+        proc = subprocess.Popen(["dch", "-v",
                 str(package_version(version, distribution_name)),
                 "-D", "UNRELEASED", "--release-heuristic", "changelog",
                 entry_description], cwd=tree.basedir)

=== modified file 'import_dsc.py'
--- a/import_dsc.py	2010-02-01 06:43:22 +0000
+++ b/import_dsc.py	2010-02-01 20:51:35 +0000
@@ -29,6 +29,7 @@
         standard_b64decode,
         standard_b64encode,
         )
+import errno
 try:
     import hashlib as md5
 except ImportError:
@@ -36,7 +37,7 @@
 import os
 import shutil
 import stat
-from subprocess import Popen, PIPE
+from subprocess import Popen, PIPE, STDOUT
 from StringIO import StringIO
 import tempfile
 
@@ -1079,7 +1080,8 @@
 
     def import_upstream(self, upstream_part, version, md5, upstream_parents,
             upstream_tarball=None, upstream_branch=None,
-            upstream_revision=None, timestamp=None, author=None):
+            upstream_revision=None, timestamp=None, author=None,
+            file_ids_from=None):
         """Import an upstream part on to the upstream branch.
 
         This imports the upstream part of the code and places it on to
@@ -1124,6 +1126,8 @@
             upstream_trees.insert(0,
                     self.upstream_branch.repository.revision_tree(
                         upstream_revision))
+        if file_ids_from is not None:
+            upstream_trees = file_ids_from + upstream_trees
         import_dir(self.upstream_tree, upstream_part,
                 file_ids_from=upstream_trees + [self.tree])
         self.upstream_tree.set_parent_ids(upstream_parents)
@@ -1193,7 +1197,7 @@
                                 '.bzr-builddeb/default.conf'])
 
     def import_debian(self, debian_part, version, parents, md5,
-            native=False, timestamp=None):
+            native=False, timestamp=None, file_ids_from=None):
         """Import the debian part of a source package.
 
         :param debian_part: the path of a directory containing the unpacked
@@ -1233,6 +1237,8 @@
         debian_trees = [get_last_revision_tree(o.branch)
             for o in other_branches]
         parent_trees = []
+        if file_ids_from is not None:
+            parent_trees = file_ids_from[:]
         for parent in parents:
             parent_trees.append(self.branch.repository.revision_tree(
                         parent))
@@ -1276,51 +1282,6 @@
                 timezone=timezone)
         self.tag_version(version)
 
-    def _get_dsc_part(self, dsc, end):
-        """Get the path and md5 of a file ending with end in dsc."""
-        files = dsc['files']
-        for file_info in files:
-            name = file_info['name']
-            if name.endswith(end):
-                filename = name
-                md5 = file_info['md5sum']
-                return (filename, md5)
-        return (None, None)
-
-    def get_upstream_part(self, dsc):
-        """Gets the information about the upstream part from the dsc.
-
-        :param dsc: a deb822.Dsc object to take the information from.
-        :return: a tuple (path, md5), both strings, the former being
-            the path to the .orig.tar.gz, the latter being the md5
-            reported for it. If there is no upstream part both will
-            be None.
-        """
-        return self._get_dsc_part(dsc, ".orig.tar.gz")
-
-    def get_diff_part(self, dsc):
-        """Gets the information about the diff part from the dsc.
-
-        :param dsc: a deb822.Dsc object to take the information from.
-        :return: a tuple (path, md5), both strings, the former being
-            the path to the .diff.gz, the latter being the md5
-            reported for it. If there is no diff part both will be
-            None.
-        """
-        return self._get_dsc_part(dsc, ".diff.gz")
-
-    def get_native_part(self, dsc):
-        """Gets the information about the native part from the dsc.
-
-        :param dsc: a deb822.Dsc object to take the information from.
-        :return: a tuple (path, md5), both strings, the former being
-            the path to the .tar.gz, the latter being the md5 reported
-            for it. If there is not native part both will be None.
-        """
-        (path, md5) = self._get_dsc_part(dsc, ".tar.gz")
-        assert not path.endswith(".orig.tar.gz")
-        return (path, md5)
-
     def upstream_parents(self, versions, version):
         """Get the parents for importing a new upstream.
 
@@ -1373,21 +1334,9 @@
         cl.parse_changelog(open(cl_filename).read(), strict=False)
         return cl
 
-    def extract_dsc(self, dsc_filename):
-        """Extract a dsc file in to a temporary directory."""
-        tempdir = tempfile.mkdtemp()
-        dsc_filename = os.path.abspath(dsc_filename)
-        proc = Popen("dpkg-source -su -x %s" % (dsc_filename,), shell=True,
-                cwd=tempdir, stdout=PIPE, stderr=PIPE,
-                preexec_fn=subprocess_setup)
-        (stdout, stderr) = proc.communicate()
-        assert proc.returncode == 0, "dpkg-source -x failed, output:\n%s\n%s" % \
-                    (stdout, stderr)
-        return tempdir
-
     def _do_import_package(self, version, versions, debian_part, md5,
             upstream_part, upstream_md5, upstream_tarball=None,
-            timestamp=None, author=None):
+            timestamp=None, author=None, file_ids_from=None):
         pull_branch = self.branch_to_pull_version_from(version, md5)
         if pull_branch is not None:
             if (self.branch_to_pull_upstream_from(version.upstream_version,
@@ -1417,7 +1366,8 @@
                             version.upstream_version,
                             upstream_md5, upstream_parents,
                             upstream_tarball=upstream_tarball,
-                            timestamp=timestamp, author=author)
+                            timestamp=timestamp, author=author,
+                            file_ids_from=file_ids_from)
                     self._fetch_upstream_to_branch(new_revid)
             else:
                 mutter("We already have the needed upstream part")
@@ -1425,7 +1375,7 @@
                     force_upstream_parent=imported_upstream)
             # Now we have the list of parents we need to import the .diff.gz
             self.import_debian(debian_part, version, parents, md5,
-                    timestamp=timestamp)
+                    timestamp=timestamp, file_ids_from=file_ids_from)
 
     def get_native_parents(self, version, versions):
         last_contained_version = self.last_contained_version(versions)
@@ -1467,14 +1417,15 @@
 
 
     def _import_native_package(self, version, versions, debian_part, md5,
-            timestamp=None):
+            timestamp=None, file_ids_from=None):
         pull_branch = self.branch_to_pull_version_from(version, md5)
         if pull_branch is not None:
             self.pull_version_from_branch(pull_branch, version, native=True)
         else:
             parents = self.get_native_parents(version, versions)
             self.import_debian(debian_part, version, parents, md5,
-                    native=True, timestamp=timestamp)
+                    native=True, timestamp=timestamp,
+                    file_ids_from=file_ids_from)
 
     def _get_safe_versions_from_changelog(self, cl):
         versions = []
@@ -1485,7 +1436,8 @@
                 break
         return versions
 
-    def import_package(self, dsc_filename, use_time_from_changelog=True):
+    def import_package(self, dsc_filename, use_time_from_changelog=True,
+            file_ids_from=None):
         """Import a source package.
 
         :param dsc_filename: a path to a .dsc file for the version
@@ -1496,29 +1448,15 @@
         base_path = osutils.dirname(dsc_filename)
         dsc = deb822.Dsc(open(dsc_filename).read())
         version = Version(dsc['Version'])
-        name = dsc['Source']
-        upstream_tarball = None
-        for part in dsc['files']:
-            if part['name'].endswith(".orig.tar.gz"):
-                assert upstream_tarball is None, "Two .orig.tar.gz?"
-                upstream_tarball = os.path.abspath(
-                        os.path.join(base_path, part['name']))
-        tempdir = self.extract_dsc(dsc_filename)
+        format = dsc['Format'].strip()
+        extractor_cls = SOURCE_EXTRACTORS.get(format)
+        if extractor_cls is None:
+            raise AssertionError("Don't know how to import source format %s yet"
+                    % format)
+        extractor = extractor_cls(dsc_filename, dsc)
         try:
-            # TODO: make more robust against strange .dsc files.
-            upstream_part = os.path.join(tempdir,
-                    "%s-%s.orig" % (name, str(version.upstream_version)))
-            debian_part = os.path.join(tempdir,
-                    "%s-%s" % (name, str(version.upstream_version)))
-            native = False
-            if not os.path.exists(upstream_part):
-                mutter("It's a native package")
-                native = True
-                (_, md5) = self.get_native_part(dsc)
-            else:
-                (_, upstream_md5) = self.get_upstream_part(dsc)
-                (_, md5) = self.get_diff_part(dsc)
-            cl = self.get_changelog_from_source(debian_part)
+            extractor.extract()
+            cl = self.get_changelog_from_source(extractor.extracted_debianised)
             timestamp = None
             author = None
             if use_time_from_changelog and len(cl._blocks) > 0:
@@ -1534,16 +1472,22 @@
             #TODO: check that the versions list is correctly ordered,
             # as some methods assume that, and it's not clear what
             # should happen if it isn't.
-            if not native:
-                self._do_import_package(version, versions, debian_part, md5,
-                        upstream_part, upstream_md5,
-                        upstream_tarball=upstream_tarball,
-                        timestamp=timestamp, author=author)
+            if extractor.extracted_upstream is not None:
+                self._do_import_package(version, versions,
+                        extractor.extracted_debianised,
+                        extractor.unextracted_debian_md5,
+                        extractor.extracted_upstream,
+                        extractor.unextracted_upstream_md5,
+                        upstream_tarball=extractor.unextracted_upstream,
+                        timestamp=timestamp, author=author,
+                        file_ids_from=file_ids_from)
             else:
-                self._import_native_package(version, versions, debian_part,
-                        md5, timestamp=timestamp)
+                self._import_native_package(version, versions,
+                        extractor.extracted_debianised,
+                        extractor.unextracted_debian_md5,
+                        timestamp=timestamp, file_ids_from=file_ids_from)
         finally:
-            shutil.rmtree(tempdir)
+            extractor.cleanup()
 
     def extract_upstream_tree(self, upstream_tip, basedir):
         # Extract that to a tempdir so we can get a working
@@ -1721,18 +1665,22 @@
     def reconstruct_pristine_tar(self, revid, package, version,
             dest_filename):
         """Reconstruct a pristine-tar tarball from a bzr revision."""
-        if not os.path.exists("/usr/bin/pristine-tar"):
-            raise PristineTarError("/usr/bin/pristine-tar is not available")
         tree = self.branch.repository.revision_tree(revid)
         tmpdir = tempfile.mkdtemp(prefix="builddeb-pristine-")
         try:
             dest = os.path.join(tmpdir, "orig")
             export(tree, dest, format='dir')
             delta = self.pristine_tar_delta(revid)
-            command = ["/usr/bin/pristine-tar", "gentar", "-",
+            command = ["pristine-tar", "gentar", "-",
                        os.path.abspath(dest_filename)]
-            proc = Popen(command, stdin=PIPE, cwd=dest,
-                    preexec_fn=subprocess_setup)
+            try:
+                proc = Popen(command, stdin=PIPE, cwd=dest,
+                        preexec_fn=subprocess_setup)
+            except OSError, e:
+                if e.errno == errno.ENOENT:
+                    raise PristineTarError("pristine-tar is not installed")
+                else:
+                    raise
             (stdout, stderr) = proc.communicate(delta)
             if proc.returncode != 0:
                 raise PristineTarError("Generating tar from delta failed: %s" % stderr)
@@ -1740,8 +1688,6 @@
             shutil.rmtree(tmpdir)
 
     def make_pristine_tar_delta(self, tree, tarball_path):
-        if not os.path.exists("/usr/bin/pristine-tar"):
-            raise PristineTarError("/usr/bin/pristine-tar is not available")
         tmpdir = tempfile.mkdtemp(prefix="builddeb-pristine-")
         try:
             dest = os.path.join(tmpdir, "orig")
@@ -1752,13 +1698,135 @@
                 export(tree, dest, format='dir')
             finally:
                 tree.unlock()
-            command = ["/usr/bin/pristine-tar", "gendelta", tarball_path, "-"]
+            command = ["pristine-tar", "gendelta", tarball_path, "-"]
             note(" ".join(command))
-            proc = Popen(command, stdout=PIPE, cwd=dest,
-                    preexec_fn=subprocess_setup)
+            try:
+                proc = Popen(command, stdout=PIPE, cwd=dest,
+                        preexec_fn=subprocess_setup)
+            except OSError, e:
+                if e.errno == errno.ENOENT:
+                    raise PristineTarError("pristine-tar is not installed")
+                else:
+                    raise
             (stdout, stderr) = proc.communicate()
             if proc.returncode != 0:
                 raise PristineTarError("Generating delta from tar failed: %s" % stderr)
             return stdout
         finally:
             shutil.rmtree(tmpdir)
+
+
+class SourceExtractor(object):
+    """A class to extract a source package to its constituent parts"""
+
+    def __init__(self, dsc_path, dsc):
+        self.dsc_path = dsc_path
+        self.dsc = dsc
+        self.extracted_upstream = None
+        self.extracted_debianised = None
+        self.unextracted_upstream = None
+        self.unextracted_debian_md5 = None
+        self.unextracted_upstream_md5 = None
+
+    def extract(self):
+        """Extract the package to a new temporary directory."""
+        self.tempdir = tempfile.mkdtemp()
+        dsc_filename = os.path.abspath(self.dsc_path)
+        proc = Popen("dpkg-source -su -x %s" % (dsc_filename,), shell=True,
+                cwd=self.tempdir, stdout=PIPE, stderr=STDOUT,
+                preexec_fn=subprocess_setup)
+        (stdout, _) = proc.communicate()
+        assert proc.returncode == 0, "dpkg-source -x failed, output:\n%s" % \
+                    (stdout,)
+        name = self.dsc['Source']
+        version = Version(self.dsc['Version'])
+        self.extracted_upstream = os.path.join(self.tempdir,
+                "%s-%s.orig" % (name, str(version.upstream_version)))
+        self.extracted_debianised = os.path.join(self.tempdir,
+                "%s-%s" % (name, str(version.upstream_version)))
+        if not os.path.exists(self.extracted_upstream):
+            mutter("It's a native package")
+            self.extracted_upstream = None
+        for part in self.dsc['files']:
+            if self.extracted_upstream is None:
+                if part['name'].endswith(".tar.gz"):
+                    self.unextracted_debian_md5 = part['md5sum']
+            else:
+                if part['name'].endswith(".orig.tar.gz"):
+                    assert self.unextracted_upstream is None, "Two .orig.tar.gz?"
+                    self.unextracted_upstream = os.path.abspath(
+                            os.path.join(osutils.dirname(self.dsc_path),
+                                part['name']))
+                    self.unextracted_upstream_md5 = part['md5sum']
+                elif part['name'].endswith(".diff.gz"):
+                    self.unextracted_debian_md5 = part['md5sum']
+
+    def cleanup(self):
+        if os.path.exists(self.tempdir):
+            shutil.rmtree(self.tempdir)
+
+
+class ThreeDotZeroNativeSourceExtractor(SourceExtractor):
+
+    def extract(self):
+        self.tempdir = tempfile.mkdtemp()
+        dsc_filename = os.path.abspath(self.dsc_path)
+        proc = Popen("dpkg-source -x %s" % (dsc_filename,), shell=True,
+                cwd=self.tempdir, stdout=PIPE, stderr=STDOUT,
+                preexec_fn=subprocess_setup)
+        (stdout, _) = proc.communicate()
+        assert proc.returncode == 0, "dpkg-source -x failed, output:\n%s" % \
+                    (stdout,)
+        name = self.dsc['Source']
+        version = Version(self.dsc['Version'])
+        self.extracted_debianised = os.path.join(self.tempdir,
+                "%s-%s" % (name, str(version.upstream_version)))
+        self.extracted_upstream = None
+        for part in self.dsc['files']:
+            if part['name'].endswith(".tar.gz"):
+                self.unextracted_debian_md5 = part['md5sum']
+
+
+class ThreeDotZeroQuiltSourceExtractor(SourceExtractor):
+
+    def extract(self):
+        self.tempdir = tempfile.mkdtemp()
+        dsc_filename = os.path.abspath(self.dsc_path)
+        proc = Popen("dpkg-source --skip-debianization -x %s"
+                % (dsc_filename,), shell=True,
+                cwd=self.tempdir, stdout=PIPE, stderr=STDOUT,
+                preexec_fn=subprocess_setup)
+        (stdout, _) = proc.communicate()
+        assert proc.returncode == 0, "dpkg-source -x failed, output:\n%s" % \
+                    (stdout,)
+        name = self.dsc['Source']
+        version = Version(self.dsc['Version'])
+        self.extracted_debianised = os.path.join(self.tempdir,
+                "%s-%s" % (name, str(version.upstream_version)))
+        self.extracted_upstream = self.extracted_debianised + ".orig"
+        os.rename(self.extracted_debianised, self.extracted_upstream)
+        proc = Popen("dpkg-source -x %s" % (dsc_filename,), shell=True,
+                cwd=self.tempdir, stdout=PIPE, stderr=STDOUT,
+                preexec_fn=subprocess_setup)
+        (stdout, _) = proc.communicate()
+        assert proc.returncode == 0, "dpkg-source -x failed, output:\n%s" % \
+                    (stdout,)
+        for part in self.dsc['files']:
+            if part['name'].endswith(".orig.tar.gz"):
+                assert self.unextracted_upstream is None, "Two .orig.tar.gz?"
+                self.unextracted_upstream = os.path.abspath(
+                        os.path.join(osutils.dirname(self.dsc_path),
+                            part['name']))
+                self.unextracted_upstream_md5 = part['md5sum']
+            elif part['name'].endswith(".debian.tar.gz"):
+                self.unextracted_debian_md5 = part['md5sum']
+        assert self.unextracted_upstream is not None, \
+            "Can't handle non gz tarballs yet"
+        assert self.unextracted_debian_md5 is not None, \
+            "Can't handle non gz tarballs yet"
+
+
+SOURCE_EXTRACTORS = {}
+SOURCE_EXTRACTORS["1.0"] = SourceExtractor
+SOURCE_EXTRACTORS["3.0 (native)"] = ThreeDotZeroNativeSourceExtractor
+SOURCE_EXTRACTORS["3.0 (quilt)"] = ThreeDotZeroQuiltSourceExtractor

=== modified file 'tests/__init__.py'
--- a/tests/__init__.py	2010-01-29 09:30:27 +0000
+++ b/tests/__init__.py	2010-02-01 17:52:19 +0000
@@ -231,12 +231,13 @@
     >>> builder.dsc_name()
     """
 
-    def __init__(self, name, version, native=False):
+    def __init__(self, name, version, native=False, version3=False):
         self.upstream_files = {}
         self.upstream_symlinks = {}
         self.debian_files = {}
         self.name = name
         self.native = native
+        self.version3 = version3
         self._cl = Changelog()
         self.new_version(version)
 
@@ -329,26 +330,43 @@
 
     def build(self):
         basedir = self._make_base()
-        if not self.native:
-            orig_basedir = basedir + ".orig"
-            shutil.copytree(basedir, orig_basedir, symlinks=True)
-            cmd = "dpkg-source -sa -b %s" % (basedir)
-            if os.path.exists("%s_%s.orig.tar.gz"
-                    % (self.name, self._cl.version.upstream_version)):
-                cmd = "dpkg-source -ss -b %s" % (basedir)
+        if not self.version3:
+            if not self.native:
+                orig_basedir = basedir + ".orig"
+                shutil.copytree(basedir, orig_basedir, symlinks=True)
+                cmd = ["dpkg-source", "-sa", "-b", basedir]
+                if os.path.exists("%s_%s.orig.tar.gz"
+                        % (self.name, self._cl.version.upstream_version)):
+                    cmd = ["dpkg-source", "-ss", "-b", basedir]
+            else:
+                cmd = ["dpkg-source", "-sn", "-b", basedir]
         else:
-            cmd = "dpkg-source -sn -b %s" % (basedir)
+            if not self.native:
+                tar_path = "%s_%s.orig.tar.gz" % (self.name,
+                        self._cl.version.upstream_version)
+                if os.path.exists(tar_path):
+                    os.unlink(tar_path)
+                tar = tarfile.open(tar_path, 'w:gz')
+                try:
+                    tar.add(basedir)
+                finally:
+                    tar.close()
+                cmd = ["dpkg-source", "--format=3.0 (quilt)", "-b",
+                        basedir]
+            else:
+                cmd = ["dpkg-source", "--format=3.0 (native)", "-b",
+                        basedir]
         self._make_files(self.debian_files, basedir)
         self._make_files({"debian/changelog": str(self._cl)}, basedir)
-        proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE)
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT)
         ret = proc.wait()
-        assert ret == 0, "dpkg-source failed, output:\n%s\n%s" % \
-                (proc.stdout.read(), proc.stderr.read())
+        assert ret == 0, "dpkg-source failed, output:\n%s" % \
+                (proc.stdout.read(),)
         cmd = "dpkg-genchanges -S > ../%s" % self.changes_name()
         proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE, cwd=basedir)
+                stderr=subprocess.STDOUT, cwd=basedir)
         ret = proc.wait()
-        assert ret == 0, "dpkg-genchanges failed, output:\n%s\n%s" % \
-                (proc.stdout.read(), proc.stderr.read())
+        assert ret == 0, "dpkg-genchanges failed, output:\n%s" % \
+                (proc.stdout.read(),)
         shutil.rmtree(basedir)

=== modified file 'tests/test_import_dsc.py'
--- a/tests/test_import_dsc.py	2009-09-16 14:49:04 +0000
+++ b/tests/test_import_dsc.py	2010-01-08 00:05:06 +0000
@@ -24,15 +24,19 @@
 import shutil
 
 from debian_bundle.changelog import Version
+from debian_bundle import deb822
 
 from bzrlib import (
-  errors,
   tests,
   )
 
 from bzrlib.plugins.builddeb.import_dsc import (
         DistributionBranch,
         DistributionBranchSet,
+        SourceExtractor,
+        SOURCE_EXTRACTORS,
+        ThreeDotZeroNativeSourceExtractor,
+        ThreeDotZeroQuiltSourceExtractor,
         )
 from bzrlib.plugins.builddeb.tests import SourcePackageBuilder
 
@@ -711,33 +715,6 @@
         self.assertEqual(self.db2.revid_of_upstream_version(version),
                 up_revid)
 
-    def test_extract_dsc(self):
-        version = Version("0.1-1")
-        name = "package"
-        builder = SourcePackageBuilder(name, version)
-        builder.add_upstream_file("README", "Hi\n")
-        builder.add_upstream_file("BUGS")
-        builder.add_default_control()
-        builder.build()
-        tempdir = self.db1.extract_dsc(builder.dsc_name())
-        self.assertTrue(os.path.exists(tempdir))
-        try:
-            unpacked_dir = os.path.join(tempdir,
-                            name+"-"+str(version.upstream_version))
-            orig_dir = unpacked_dir + ".orig"
-            self.assertTrue(os.path.exists(unpacked_dir))
-            self.assertTrue(os.path.exists(orig_dir))
-            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
-                            "README")))
-            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
-                            "debian", "control")))
-            self.assertTrue(os.path.exists(os.path.join(orig_dir,
-                            "README")))
-            self.assertFalse(os.path.exists(os.path.join(orig_dir,
-                            "debian", "control")))
-        finally:
-            shutil.rmtree(tempdir)
-
     def check_changes(self, changes, added=[], removed=[], modified=[],
                       renamed=[]):
         def check_one_type(type, expected, actual):
@@ -1419,3 +1396,116 @@
         builder.add_upstream_symlink("a", "b")
         builder.build()
         self.db1.import_package(builder.dsc_name())
+
+
+class SourceExtractorTests(tests.TestCaseInTempDir):
+
+    def test_extract_format1(self):
+        version = Version("0.1-1")
+        name = "package"
+        builder = SourcePackageBuilder(name, version)
+        builder.add_upstream_file("README", "Hi\n")
+        builder.add_upstream_file("BUGS")
+        builder.add_default_control()
+        builder.build()
+        dsc = deb822.Dsc(open(builder.dsc_name()).read())
+        self.assertEqual(SourceExtractor, SOURCE_EXTRACTORS[dsc['Format']])
+        extractor = SourceExtractor(builder.dsc_name(), dsc)
+        try:
+            extractor.extract()
+            unpacked_dir = extractor.extracted_debianised
+            orig_dir = extractor.extracted_upstream
+            self.assertTrue(os.path.exists(unpacked_dir))
+            self.assertTrue(os.path.exists(orig_dir))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "README")))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "debian", "control")))
+            self.assertTrue(os.path.exists(os.path.join(orig_dir,
+                            "README")))
+            self.assertFalse(os.path.exists(os.path.join(orig_dir,
+                            "debian", "control")))
+            self.assertTrue(os.path.exists(extractor.unextracted_upstream))
+        finally:
+            extractor.cleanup()
+
+    def test_extract_format1_native(self):
+        version = Version("0.1-1")
+        name = "package"
+        builder = SourcePackageBuilder(name, version, native=True)
+        builder.add_upstream_file("README", "Hi\n")
+        builder.add_upstream_file("BUGS")
+        builder.add_default_control()
+        builder.build()
+        dsc = deb822.Dsc(open(builder.dsc_name()).read())
+        self.assertEqual(SourceExtractor, SOURCE_EXTRACTORS[dsc['Format']])
+        extractor = SourceExtractor(builder.dsc_name(), dsc)
+        try:
+            extractor.extract()
+            unpacked_dir = extractor.extracted_debianised
+            orig_dir = extractor.extracted_upstream
+            self.assertTrue(os.path.exists(unpacked_dir))
+            self.assertEqual(None, orig_dir)
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "README")))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "debian", "control")))
+        finally:
+            extractor.cleanup()
+
+    def test_extract_format3_native(self):
+        version = Version("0.1-1")
+        name = "package"
+        builder = SourcePackageBuilder(name, version, native=True,
+                version3=True)
+        builder.add_upstream_file("README", "Hi\n")
+        builder.add_upstream_file("BUGS")
+        builder.add_default_control()
+        builder.build()
+        dsc = deb822.Dsc(open(builder.dsc_name()).read())
+        self.assertEqual(ThreeDotZeroNativeSourceExtractor,
+                SOURCE_EXTRACTORS[dsc['Format']])
+        extractor = ThreeDotZeroNativeSourceExtractor(builder.dsc_name(),
+                dsc)
+        try:
+            extractor.extract()
+            unpacked_dir = extractor.extracted_debianised
+            orig_dir = extractor.extracted_upstream
+            self.assertTrue(os.path.exists(unpacked_dir))
+            self.assertEqual(None, orig_dir)
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "README")))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "debian", "control")))
+        finally:
+            extractor.cleanup()
+
+    def test_extract_format3_quilt(self):
+        version = Version("0.1-1")
+        name = "package"
+        builder = SourcePackageBuilder(name, version, version3=True)
+        builder.add_upstream_file("README", "Hi\n")
+        builder.add_upstream_file("BUGS")
+        builder.add_default_control()
+        builder.build()
+        dsc = deb822.Dsc(open(builder.dsc_name()).read())
+        self.assertEqual(ThreeDotZeroQuiltSourceExtractor,
+                SOURCE_EXTRACTORS[dsc['Format']])
+        extractor = ThreeDotZeroQuiltSourceExtractor(builder.dsc_name(), dsc)
+        try:
+            extractor.extract()
+            unpacked_dir = extractor.extracted_debianised
+            orig_dir = extractor.extracted_upstream
+            self.assertTrue(os.path.exists(unpacked_dir))
+            self.assertTrue(os.path.exists(orig_dir))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "README")))
+            self.assertTrue(os.path.exists(os.path.join(unpacked_dir,
+                            "debian", "control")))
+            self.assertTrue(os.path.exists(os.path.join(orig_dir,
+                            "README")))
+            self.assertFalse(os.path.exists(os.path.join(orig_dir,
+                            "debian", "control")))
+            self.assertTrue(os.path.exists(extractor.unextracted_upstream))
+        finally:
+            extractor.cleanup()

=== modified file 'upstream.py'
--- a/upstream.py	2009-12-01 17:14:15 +0000
+++ b/upstream.py	2010-02-01 17:37:17 +0000
@@ -28,7 +28,7 @@
 
 from bzrlib.export import export
 from bzrlib.revisionspec import RevisionSpec
-from bzrlib.trace import note
+from bzrlib.trace import info
 
 from bzrlib.plugins.builddeb.errors import (
     MissingUpstreamTarball,
@@ -46,13 +46,16 @@
 class UpstreamSource(object):
     """A source for upstream versions (uscan, get-orig-source, etc)."""
 
-    def get_latest_version(self, package, target_dir):
+    def get_latest_version(self, package, version, target_dir):
         """Fetch the source tarball for the latest available version.
 
         :param package: Name of the package
+        :param version: The current version of the package.
         :param target_dir: Directory in which to store the tarball
+        :return: The version number of the new version, or None if no newer
+                version is available.
         """
-        raise NotImplemented(self.get_latest_version)
+        raise NotImplementedError(self.get_latest_version)
 
     def get_specific_version(self, package, version, target_dir):
         """Fetch the source tarball for a particular version.
@@ -61,7 +64,7 @@
         :param version: Version string of the version to fetch
         :param target_dir: Directory in which to store the tarball
         """
-        raise NotImplemented(self.get_specific_version)
+        raise NotImplementedError(self.get_specific_version)
 
     def _tarball_path(self, package, version, target_dir):
         return os.path.join(target_dir, tarball_name(package, version))
@@ -83,7 +86,7 @@
         revid = db.revid_of_upstream_version_from_branch(version)
         if not db.has_pristine_tar_delta(revid):
             raise PackageVersionNotPresent(package, version, self)
-        note("Using pristine-tar to reconstruct the needed tarball.")
+        info("Using pristine-tar to reconstruct the needed tarball.")
         try:
             db.reconstruct_pristine_tar(revid, package, version, target_filename)
         except PristineTarError:
@@ -109,14 +112,14 @@
             raise PackageVersionNotPresent(package, upstream_version, self)
 
         sources.Restart()
-        note("Using apt to look for the upstream tarball.")
+        info("Using apt to look for the upstream tarball.")
         while sources.Lookup(package):
             if upstream_version \
                 == Version(sources.Version).upstream_version:
                 if self._run_apt_source(package, sources.Version, target_dir):
                     return
                 break
-        note("apt could not find the needed tarball.")
+        info("apt could not find the needed tarball.")
         raise PackageVersionNotPresent(package, upstream_version, self)
 
     def _get_command(self, package, version_str):
@@ -157,7 +160,7 @@
         self.upstream_branch.lock_read()
         try:
             revid = self._get_revision_id(version)
-            note("Exporting upstream branch revision %s to create the tarball",
+            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)
@@ -176,16 +179,16 @@
 
     def _get_orig_source(self, source_dir, desired_tarball_name,
                         target_dir):
-        note("Trying to use get-orig-source to retrieve needed tarball.")
-        command = ["/usr/bin/make", "-f", "debian/rules", "get-orig-source"]
+        info("Trying to use get-orig-source to retrieve needed tarball.")
+        command = ["make", "-f", "debian/rules", "get-orig-source"]
         proc = subprocess.Popen(command, cwd=source_dir)
         ret = proc.wait()
         if ret != 0:
-            note("Trying to run get-orig-source rule failed")
+            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):
-            note("get-orig-source did not create %s", desired_tarball_name)
+            info("get-orig-source did not create %s", desired_tarball_name)
             return False
         repack_tarball(fetched_tarball, desired_tarball_name, 
                        target_dir=target_dir)
@@ -213,7 +216,7 @@
                 return
             finally:
                 shutil.rmtree(tmpdir)
-        note("No debian/rules file to try and use for a get-orig-source rule")
+        info("No debian/rules file to try and use for a get-orig-source rule")
         raise PackageVersionNotPresent(package, version, self)
 
 
@@ -225,14 +228,14 @@
         self.larstiq = larstiq
 
     def _uscan(self, package, upstream_version, watch_file, target_dir):
-        note("Using uscan to look for the upstream tarball.")
+        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:
-            note("uscan could not find the needed tarball.")
+            info("uscan could not find the needed tarball.")
             return False
         return True
 
@@ -243,7 +246,7 @@
             watchfile = 'debian/watch'
         watch_id = self.tree.path2id(watchfile)
         if watch_id is None:
-            note("No watch file to use to retrieve upstream tarball.")
+            info("No watch file to use to retrieve upstream tarball.")
             return None
         (tmp, tempfilename) = tempfile.mkstemp()
         try:
@@ -263,7 +266,10 @@
                     target_dir):
                 raise PackageVersionNotPresent(package, version, self)
         finally:
-          os.unlink(tempfilename)
+            os.unlink(tempfilename)
+
+    def get_latest_version(self, package, version, target_dir):
+        pass
 
 
 class SelfSplitSource(UpstreamSource):
@@ -287,7 +293,7 @@
             shutil.rmtree(tmpdir)
 
     def get_specific_version(self, package, version, target_dir):
-        note("Using the current branch without the 'debian' directory "
+        info("Using the current branch without the 'debian' directory "
                 "to create the tarball")
         self._split(package, version, 
                     self._tarball_path(package, version, target_dir))
@@ -313,6 +319,16 @@
                 pass
         raise PackageVersionNotPresent(package, version, self)
 
+    def get_latest_version(self, package, version, target_dir):
+        for source in self._sources:
+            try:
+                new_version = source.get_latest_version(package, version, target_dir)
+                if new_version is not None:
+                    return new_version
+            except NotImplementedError:
+                pass
+        return None
+
 
 def get_upstream_sources(tree, branch, larstiq=False, upstream_branch=None,
                          upstream_revision=None, allow_split=False):
@@ -387,9 +403,9 @@
         :param target_dir: The directory to place the tarball in.
         :return: The path to the tarball.
         """
-        note("Looking for a way to retrieve the upstream tarball")
+        info("Looking for a way to retrieve the upstream tarball")
         if self.already_exists_in_target(target_dir):
-            note("Upstream tarball already exists in build directory, "
+            info("Upstream tarball already exists in build directory, "
                     "using that")
             return os.path.join(target_dir, self._tarball_name())
         if not self.already_exists_in_store():
@@ -401,7 +417,7 @@
             except PackageVersionNotPresent:
                 raise MissingUpstreamTarball(self._tarball_name())
         else:
-             note("Using the upstream tarball that is present in "
+             info("Using the upstream tarball that is present in "
                      "%s" % self.store_dir)
         assert self.provide_from_store_dir(target_dir)
         return os.path.join(target_dir, self._tarball_name())




More information about the bazaar-commits mailing list