~ubuntu-branches/debian/sid/bzr-builddeb/sid

« back to all changes in this revision

Viewing changes to util.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij, Jelmer Vernooij, Jonathan Riddell, Scott Kitterman
  • Date: 2011-07-15 12:15:22 UTC
  • Revision ID: james.westby@ubuntu.com-20110715121522-avtc0uc3uuzcg7zn
Tags: 2.7.5
[ Jelmer Vernooij ]
* New 'bzr dep3-patch' subcommand that can generate DEP-3 compliant
  patches. LP: #460576

[ Jonathan Riddell ]
* Use new set_commit_message() hook in bzr to set the commit
  message from debian/changelog and set fixed bugs in tags. LP: #707274

[ Jelmer Vernooij ]
* Add dependency on devscripts >= 2.10.59, required now that 'dch --
  package' is used. LP: #783122
* Fix support for native packages with dashes in their version in
  sources.list. LP: #796853
* Fix deprecation warnings for TestCase.failUnlessExists and
  TestCase.failIfExists in bzr 2.4.

[ Scott Kitterman ]
* Delete debian/bzr-builddeb.dirs so the long obsolete and empty
  /usr/lib/python2.4/site-packages/bzrlib/plugins/bzr-builddeb/ is no
  longer created. Closes: #631564

[ Jelmer Vernooij ]
* Add support for xz and lzma tarballs. LP: #553668
* When importing upstream component tarballs, don't repack bz2/lzma
  tarballs to gz if the package is in v3 source format. LP: #810531

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
    import hashlib as md5
23
23
except ImportError:
24
24
    import md5
25
 
import errno
26
25
import signal
27
26
import shutil
28
27
import subprocess
43
42
from bzrlib import (
44
43
    bugtracker,
45
44
    errors,
46
 
    osutils,
47
45
    urlutils,
48
46
    version_info as bzr_version_info,
49
47
    )
69
67
    AddChangelogError,
70
68
    InconsistentSourceFormatError,
71
69
    NoPreviousUpload,
72
 
    PristineTarError,
 
70
    TarFailed,
73
71
    UnableToFindPreviousUpload,
74
72
    UnparseableChangelog,
75
73
    )
158
156
            else:
159
157
                raise MissingChangelogError('"debian/changelog"')
160
158
        elif merge and t.has_filename('changelog'):
161
 
            # If it is a "larstiq" pacakge and debian is a symlink to
 
159
            # If it is a "larstiq" package and debian is a symlink to
162
160
            # "." then it will have found debian/changelog. Try and detect
163
161
            # this.
164
162
            debian_file_id = t.path2id('debian')
211
209
        return changes
212
210
 
213
211
 
214
 
def tarball_name(package, version, format=None):
 
212
def tarball_name(package, version, component=None, format=None):
215
213
    """Return the name of the .orig.tar.gz for the given package and version.
216
214
 
217
215
    :param package: the name of the source package.
218
216
    :param version: the upstream version of the package.
 
217
    :param component: Component name (None for base)
219
218
    :param format: the format for the tarball. If None then 'gz' will be
220
219
         used. You probably want on of 'gz', 'bz2', or 'lzma'.
221
220
    :return: a string that is the name of the upstream tarball to use.
222
221
    """
223
222
    if format is None:
224
223
        format = 'gz'
225
 
    return "%s_%s.orig.tar.%s" % (package, str(version), format)
226
 
 
 
224
    name = "%s_%s.orig" % (package, str(version))
 
225
    if component is not None:
 
226
        name += "-" + component
 
227
    return "%s.tar.%s" % (name, format)
227
228
 
228
229
 
229
230
def suite_to_distribution(suite):
345
346
 
346
347
 
347
348
def open_transport(path):
348
 
  """Obtain an appropriate transport instance for the given path."""
349
 
  base_dir, path = urlutils.split(path)
350
 
  transport = get_transport(base_dir)
351
 
  return (path, transport)
 
349
    """Obtain an appropriate transport instance for the given path."""
 
350
    base_dir, path = urlutils.split(path)
 
351
    transport = get_transport(base_dir)
 
352
    return (path, transport)
352
353
 
353
354
 
354
355
def open_file_via_transport(filename, transport):
355
 
  """Open a file using the transport, follow redirects as necessary."""
356
 
  def open_file(transport):
357
 
    return transport.get(filename)
358
 
  def follow_redirection(transport, e, redirection_notice):
359
 
    mutter(redirection_notice)
360
 
    _filename, redirected_transport = open_transport(e.target)
361
 
    return redirected_transport
 
356
    """Open a file using the transport, follow redirects as necessary."""
 
357
    def open_file(transport):
 
358
        return transport.get(filename)
 
359
    def follow_redirection(transport, e, redirection_notice):
 
360
        mutter(redirection_notice)
 
361
        _filename, redirected_transport = open_transport(e.target)
 
362
        return redirected_transport
362
363
 
363
 
  result = do_catching_redirections(open_file, transport, follow_redirection)
364
 
  return result
 
364
    result = do_catching_redirections(open_file, transport, follow_redirection)
 
365
    return result
365
366
 
366
367
 
367
368
def _dget(cls, dsc_location, target_dir):
396
397
def find_bugs_fixed(changes, branch, _lplib=None):
397
398
    """Find the bugs marked fixed in a changelog entry.
398
399
 
399
 
    :param changes: The contents of the changelog entry.
 
400
    :param changes: A list of the contents of the changelog entry.
400
401
    :param branch: Bazaar branch associated with the package
401
402
    :return: String with bugs closed, as appropriate for a Bazaar "bugs" revision 
402
403
        property.
638
639
    :param path: Path to the package
639
640
    :return: String with package format
640
641
    """
641
 
    if not tree.has_filename("debian/source/format"):
 
642
    filename = "debian/source/format"
 
643
    if not tree.has_filename(filename):
642
644
        return FORMAT_1_0
643
 
    return tree.get_file_text(tree.path2id("debian/source/format")).strip()
 
645
    text = tree.get_file_text(tree.path2id(filename), filename)
 
646
    return text.strip()
644
647
 
645
648
 
646
649
FORMAT_1_0 = "1.0"
686
689
        return BUILD_TYPE_NORMAL
687
690
 
688
691
 
689
 
def reconstruct_pristine_tar(dest, delta, dest_filename):
690
 
    """Reconstruct a pristine tarball from a directory and a delta.
691
 
 
692
 
    :param dest: Directory to pack
693
 
    :param delta: pristine-tar delta
694
 
    :param dest_filename: Destination filename
695
 
    """
696
 
    command = ["pristine-tar", "gentar", "-",
697
 
               os.path.abspath(dest_filename)]
698
 
    try:
699
 
        proc = subprocess.Popen(command, stdin=subprocess.PIPE,
700
 
                cwd=dest, preexec_fn=subprocess_setup,
701
 
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
702
 
    except OSError, e:
703
 
        if e.errno == errno.ENOENT:
704
 
            raise PristineTarError("pristine-tar is not installed")
705
 
        else:
706
 
            raise
707
 
    (stdout, stderr) = proc.communicate(delta)
708
 
    if proc.returncode != 0:
709
 
        raise PristineTarError("Generating tar from delta failed: %s" % stdout)
710
 
 
711
 
 
712
 
def make_pristine_tar_delta(dest, tarball_path):
713
 
    """Create a pristine-tar delta for a tarball.
714
 
 
715
 
    :param dest: Directory to generate pristine tar delta for
716
 
    :param tarball_path: Path to the tarball
717
 
    :return: pristine-tarball
718
 
    """
719
 
    # If tarball_path is relative, the cwd=dest parameter to Popen will make
720
 
    # pristine-tar faaaail. pristine-tar doesn't use the VFS either, so we
721
 
    # assume local paths.
722
 
    tarball_path = osutils.abspath(tarball_path)
723
 
    command = ["pristine-tar", "gendelta", tarball_path, "-"]
724
 
    try:
725
 
        proc = subprocess.Popen(command, stdout=subprocess.PIPE,
726
 
                cwd=dest, preexec_fn=subprocess_setup,
727
 
                stderr=subprocess.PIPE)
728
 
    except OSError, e:
729
 
        if e.errno == errno.ENOENT:
730
 
            raise PristineTarError("pristine-tar is not installed")
731
 
        else:
732
 
            raise
733
 
    (stdout, stderr) = proc.communicate()
734
 
    if proc.returncode != 0:
735
 
        raise PristineTarError("Generating delta from tar failed: %s" % stderr)
736
 
    return stdout
 
692
def component_from_orig_tarball(tarball_filename, package, version):
 
693
    tarball_filename = os.path.basename(tarball_filename)
 
694
    prefix = "%s_%s.orig" % (package, version)
 
695
    if not tarball_filename.startswith(prefix):
 
696
        raise ValueError(
 
697
            "invalid orig tarball file %s does not have expected prefix %s" % (
 
698
                tarball_filename, prefix))
 
699
    base = tarball_filename[len(prefix):]
 
700
    for ext in (".tar.gz", ".tar.bz2", ".tar.lzma"):
 
701
        if tarball_filename.endswith(ext):
 
702
            base = base[:-len(ext)]
 
703
            break
 
704
    else:
 
705
        raise ValueError(
 
706
            "orig tarball file %s has unknown extension" % tarball_filename)
 
707
    if base == "":
 
708
        return None
 
709
    elif base[0] == "-":
 
710
        # Extra component
 
711
        return base[1:]
 
712
    else:
 
713
        raise ValueError("Invalid extra characters in tarball filename %s" %
 
714
            tarball_filename)
 
715
 
 
716
 
 
717
def extract_orig_tarball(tarball_filename, component, target, strip_components=None):
 
718
    """Extract an orig tarball.
 
719
 
 
720
    :param tarball: Path to the tarball
 
721
    :param component: Component name (or None for top-level)
 
722
    :param target: Target path
 
723
    :param strip_components: Optional number of components to strip
 
724
    """
 
725
    tar_args = ["tar"]
 
726
    if tarball_filename.endswith(".tar.bz2"):
 
727
        tar_args.append('xjf')
 
728
    elif tarball_filename.endswith(".tar.lzma"):
 
729
        tar_args.append('xJf')
 
730
    else:
 
731
        tar_args.append('xzf')
 
732
    if component is not None:
 
733
        target_path = os.path.join(target, component)
 
734
        os.mkdir(target_path)
 
735
    else:
 
736
        target_path = target
 
737
    tar_args.extend([tarball_filename, "-C", target_path])
 
738
    if strip_components is not None:
 
739
        tar_args.extend(["--strip-components", "1"])
 
740
    proc = subprocess.Popen(tar_args, preexec_fn=subprocess_setup)
 
741
    proc.communicate()
 
742
    if proc.returncode != 0:
 
743
        raise TarFailed("extract", tarball_filename)
 
744
 
 
745
 
 
746
def extract_orig_tarballs(tarballs, target, strip_components=None):
 
747
    """Extract orig tarballs to a directory.
 
748
 
 
749
    :param tarballs: List of tarball filenames
 
750
    :param target: Target directory (must already exist)
 
751
    """
 
752
    for tarball_filename, component in tarballs:
 
753
        extract_orig_tarball(tarball_filename, component, target,
 
754
            strip_components=strip_components)