import bz2
import gzip
import hashlib
import os
import shutil
import tarfile
from debian.changelog import Changelog, Version
from debmutate.changelog import strip_changelog_message
from ..config import (
BUILD_TYPE_MERGE,
BUILD_TYPE_NATIVE,
BUILD_TYPE_NORMAL,
)
from . import (
LzmaFeature,
SourcePackageBuilder,
TestCaseInTempDir,
TestCaseWithTransport,
)
from ..util import (
AddChangelogError,
InconsistentSourceFormatError,
NoPreviousUpload,
NoSuchFile,
changelog_find_previous_upload,
component_from_orig_tarball,
dget,
dget_changes,
extract_orig_tarballs,
find_bugs_fixed,
find_changelog,
find_extra_authors,
find_thanks,
get_files_excluded,
get_commit_info_from_changelog,
guess_build_type,
lookup_distribution,
move_file_if_different,
get_parent_dir,
recursive_copy,
suite_to_distribution,
tarball_name,
tree_contains_upstream_source,
tree_get_source_format,
write_if_different,
MissingChangelogError,
)
from .... import errors as bzr_errors
from ....tests import (
TestCase,
)
from ....tests.features import (
SymlinkFeature,
ModuleAvailableFeature,
)
class RecursiveCopyTests(TestCaseInTempDir):
def test_recursive_copy(self):
os.mkdir('a')
os.mkdir('b')
os.mkdir('c')
os.mkdir('a/d')
os.mkdir('a/d/e')
with open('a/f', 'w') as f:
f.write('f')
os.mkdir('b/g')
recursive_copy('a', 'b')
self.assertPathExists('a')
self.assertPathExists('b')
self.assertPathExists('c')
self.assertPathExists('b/d')
self.assertPathExists('b/d/e')
self.assertPathExists('b/f')
self.assertPathExists('a/d')
self.assertPathExists('a/d/e')
self.assertPathExists('a/f')
def test_recursive_copy_symlink(self):
os.mkdir('a')
os.symlink('c', 'a/link')
os.mkdir('b')
recursive_copy('a', 'b')
self.assertPathExists('b')
self.assertPathExists('b/link')
self.assertEqual('c', os.readlink('b/link'))
cl_block1 = """\
bzr-builddeb (0.17) unstable; urgency=low
[ James Westby ]
* Pass max_blocks=1 when constructing changelogs as that is all that is
needed currently.
-- James Westby <jw+debian@jameswestby.net> Sun, 17 Jun 2007 18:48:28 +0100
"""
class FindChangelogTests(TestCaseWithTransport):
def write_changelog(self, filename):
f = open(filename, 'w')
try:
f.write(cl_block1)
f.write("""\
bzr-builddeb (0.16.2) unstable; urgency=low
* loosen the dependency on bzr. bzr-builddeb seems to be not be broken
by bzr version 0.17, so remove the upper bound of the dependency.
-- Reinhard Tartler <siretart@tauware.de> Tue, 12 Jun 2007 19:45:38 +0100
""")
finally:
f.close()
def test_find_changelog_std(self):
tree = self.make_branch_and_tree('.')
os.mkdir('debian')
self.write_changelog('debian/changelog')
tree.add(['debian', 'debian/changelog'])
(cl, lq) = find_changelog(tree, merge=False)
self.assertEqual(str(cl), cl_block1)
self.assertEqual(lq, False)
def test_find_changelog_merge(self):
tree = self.make_branch_and_tree('.')
os.mkdir('debian')
self.write_changelog('debian/changelog')
tree.add(['debian', 'debian/changelog'])
(cl, lq) = find_changelog(tree, merge=True)
self.assertEqual(str(cl), cl_block1)
self.assertEqual(lq, False)
def test_find_changelog_merge_lq(self):
tree = self.make_branch_and_tree('.')
self.write_changelog('changelog')
tree.add(['changelog'])
(cl, lq) = find_changelog(tree, merge=True)
self.assertEqual(str(cl), cl_block1)
self.assertEqual(lq, True)
def test_find_changelog_lq_unversioned_debian_symlink(self):
try:
self.requireFeature(SymlinkFeature(self.test_dir))
except TypeError: self.requireFeature(SymlinkFeature)
tree = self.make_branch_and_tree('.')
self.write_changelog('changelog')
tree.add(['changelog'])
os.symlink('.', 'debian')
self.assertRaises(AddChangelogError, find_changelog, tree, merge=True)
def test_find_changelog_nomerge_lq(self):
tree = self.make_branch_and_tree('.')
self.write_changelog('changelog')
tree.add(['changelog'])
self.assertRaises(
MissingChangelogError, find_changelog, tree, merge=False)
def test_find_changelog_nochangelog(self):
tree = self.make_branch_and_tree('.')
self.write_changelog('changelog')
self.assertRaises(
MissingChangelogError, find_changelog, tree, merge=False)
def test_find_changelog_nochangelog_merge(self):
tree = self.make_branch_and_tree('.')
self.assertRaises(
MissingChangelogError, find_changelog, tree, merge=True)
def test_find_changelog_symlink(self):
try:
self.requireFeature(SymlinkFeature(self.test_dir))
except TypeError: self.requireFeature(SymlinkFeature)
tree = self.make_branch_and_tree('.')
self.write_changelog('changelog')
tree.add(['changelog'])
os.symlink('.', 'debian')
tree.add(['debian'])
(cl, lq) = find_changelog(tree, merge=True)
self.assertEqual(str(cl), cl_block1)
self.assertEqual(lq, True)
def test_find_changelog_symlink_naughty(self):
tree = self.make_branch_and_tree('.')
os.mkdir('debian')
self.write_changelog('debian/changelog')
with open('changelog', 'w') as f:
f.write('Naughty, naughty')
tree.add(['changelog', 'debian', 'debian/changelog'])
(cl, lq) = find_changelog(tree, merge=True)
self.assertEqual(str(cl), cl_block1)
self.assertEqual(lq, False)
def test_changelog_not_added(self):
tree = self.make_branch_and_tree('.')
os.mkdir('debian')
self.write_changelog('debian/changelog')
self.assertRaises(AddChangelogError, find_changelog, tree, merge=False)
class TarballNameTests(TestCase):
def test_tarball_name(self):
self.assertEqual(
tarball_name("package", "0.1", None),
"package_0.1.orig.tar.gz")
self.assertEqual(
tarball_name("package", Version("0.1"), None),
"package_0.1.orig.tar.gz")
self.assertEqual(
tarball_name("package", Version("0.1"), None, format='bz2'),
"package_0.1.orig.tar.bz2")
self.assertEqual(
tarball_name("package", Version("0.1"), None, format='xz'),
"package_0.1.orig.tar.xz")
self.assertEqual(
tarball_name("package", Version("0.1"), "la", format='xz'),
"package_0.1.orig-la.tar.xz")
DistroInfoFeature = ModuleAvailableFeature('distro_info')
class SuiteToDistributionTests(TestCase):
_test_needs_features = [DistroInfoFeature]
def _do_lookup(self, target):
return suite_to_distribution(target)
def lookup_ubuntu(self, target):
self.assertEqual(self._do_lookup(target), 'ubuntu')
def lookup_debian(self, target):
self.assertEqual(self._do_lookup(target), 'debian')
def lookup_kali(self, target):
self.assertEqual(self._do_lookup(target), 'kali')
def lookup_other(self, target):
self.assertEqual(self._do_lookup(target), None)
def test_lookup_ubuntu(self):
self.lookup_ubuntu('intrepid')
self.lookup_ubuntu('hardy-proposed')
self.lookup_ubuntu('gutsy-updates')
self.lookup_ubuntu('feisty-security')
self.lookup_ubuntu('dapper-backports')
def test_lookup_debian(self):
self.lookup_debian('unstable')
self.lookup_debian('stable-security')
self.lookup_debian('testing-proposed-updates')
self.lookup_debian('etch-backports')
def test_lookup_kali(self):
self.lookup_kali('kali-dev')
self.lookup_kali('kali-rolling')
self.lookup_kali('kali')
def test_lookup_other(self):
self.lookup_other('not-a-target')
self.lookup_other("debian")
self.lookup_other("ubuntu")
class LookupDistributionTests(SuiteToDistributionTests):
_test_needs_features = [DistroInfoFeature]
def _do_lookup(self, target):
return lookup_distribution(target)
def test_lookup_other(self):
self.lookup_other('not-a-target')
self.lookup_debian("debian")
self.lookup_ubuntu("ubuntu")
self.lookup_ubuntu("Ubuntu")
class MoveFileTests(TestCaseInTempDir):
def test_move_file_non_extant(self):
self.build_tree(['a'])
move_file_if_different('a', 'b', None)
self.assertPathDoesNotExist('a')
self.assertPathExists('b')
def test_move_file_samefile(self):
self.build_tree(['a'])
move_file_if_different('a', 'a', None)
self.assertPathExists('a')
def test_move_file_same_md5(self):
self.build_tree(['a'])
md5sum = hashlib.md5()
with open('a', 'rb') as f:
md5sum.update(f.read())
shutil.copy('a', 'b')
move_file_if_different('a', 'b', md5sum.hexdigest())
self.assertPathExists('a')
self.assertPathExists('b')
def test_move_file_diff_md5(self):
self.build_tree(['a', 'b'])
md5sum = hashlib.md5()
with open('a', 'rb') as f:
md5sum.update(f.read())
a_hexdigest = md5sum.hexdigest()
md5sum = hashlib.md5()
with open('b', 'rb') as f:
md5sum.update(f.read())
b_hexdigest = md5sum.hexdigest()
self.assertNotEqual(a_hexdigest, b_hexdigest)
move_file_if_different('a', 'b', a_hexdigest)
self.assertPathDoesNotExist('a')
self.assertPathExists('b')
md5sum = hashlib.md5()
with open('b', 'rb') as f:
md5sum.update(f.read())
self.assertEqual(md5sum.hexdigest(), a_hexdigest)
class WriteFileTests(TestCaseInTempDir):
def test_write_non_extant(self):
write_if_different(b"foo", 'a')
self.assertPathExists('a')
self.check_file_contents('a', b"foo")
def test_write_file_same(self):
write_if_different(b"foo", 'a')
self.assertPathExists('a')
self.check_file_contents('a', b"foo")
write_if_different(b"foo", 'a')
self.assertPathExists('a')
self.check_file_contents('a', b"foo")
def test_write_file_different(self):
write_if_different(b"foo", 'a')
self.assertPathExists('a')
self.check_file_contents('a', b"foo")
write_if_different(b"bar", 'a')
self.assertPathExists('a')
self.check_file_contents('a', b"bar")
class DgetTests(TestCaseWithTransport):
def test_dget_local(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
builder.build()
self.build_tree(["target/"])
dget(builder.dsc_name(), 'target')
self.assertPathExists(os.path.join("target", builder.dsc_name()))
self.assertPathExists(os.path.join("target", builder.tar_name()))
self.assertPathExists(os.path.join("target", builder.diff_name()))
def test_dget_transport(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
builder.build()
self.build_tree(["target/"])
dget(self.get_url(builder.dsc_name()), 'target')
self.assertPathExists(os.path.join("target", builder.dsc_name()))
self.assertPathExists(os.path.join("target", builder.tar_name()))
self.assertPathExists(os.path.join("target", builder.diff_name()))
def test_dget_missing_dsc(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
self.build_tree(["target/"])
self.assertRaises(
NoSuchFile, dget,
self.get_url(builder.dsc_name()), 'target')
def test_dget_missing_file(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
builder.build()
os.unlink(builder.tar_name())
self.build_tree(["target/"])
self.assertRaises(
NoSuchFile, dget,
self.get_url(builder.dsc_name()), 'target')
def test_dget_missing_target(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
builder.build()
self.assertRaises(
bzr_errors.NotADirectory, dget,
self.get_url(builder.dsc_name()), 'target')
def test_dget_changes(self):
builder = SourcePackageBuilder("package", Version("0.1-1"))
builder.add_upstream_file("foo")
builder.add_default_control()
builder.build()
self.build_tree(["target/"])
dget_changes(builder.changes_name(), 'target')
self.assertPathExists(os.path.join("target", builder.dsc_name()))
self.assertPathExists(os.path.join("target", builder.tar_name()))
self.assertPathExists(os.path.join("target", builder.diff_name()))
self.assertPathExists(os.path.join("target", builder.changes_name()))
class ParentDirTests(TestCase):
def test_get_parent_dir(self):
self.assertEqual(get_parent_dir("a"), '')
self.assertEqual(get_parent_dir("a/"), '')
self.assertEqual(get_parent_dir("a/b"), 'a')
self.assertEqual(get_parent_dir("a/b/"), 'a')
self.assertEqual(get_parent_dir("a/b/c"), 'a/b')
class ChangelogInfoTests(TestCaseWithTransport):
def test_find_extra_authors_none(self):
changes = [" * Do foo", " * Do bar"]
authors = find_extra_authors(changes)
self.assertEqual([], authors)
def test_find_extra_authors(self):
changes = [" * Do foo", "", " [ A. Hacker ]", " * Do bar", "",
" [ B. Hacker ]", " [ A. Hacker}"]
authors = find_extra_authors(changes)
self.assertEqual(["A. Hacker", "B. Hacker"], authors)
self.assertEqual([str]*len(authors), list(map(type, authors)))
def test_find_extra_authors_utf8(self):
changes = [" * Do foo", "", " [ \xe1. Hacker ]", " * Do bar", "",
" [ \xe7. Hacker ]", " [ A. Hacker}"]
authors = find_extra_authors(changes)
self.assertEqual(["\xe1. Hacker", "\xe7. Hacker"], authors)
self.assertEqual([str]*len(authors), list(map(type, authors)))
def test_find_extra_authors_iso_8859_1(self):
changes = [" * Do foo", "", " [ \xe1. Hacker ]", " * Do bar", "",
" [ \xe7. Hacker ]", " [ A. Hacker}"]
authors = find_extra_authors(changes)
self.assertEqual(["\xe1. Hacker", "\xe7. Hacker"], authors)
self.assertEqual([str]*len(authors), list(map(type, authors)))
def test_find_extra_authors_no_changes(self):
authors = find_extra_authors([])
self.assertEqual([], authors)
def assert_thanks_is(self, changes, expected_thanks):
thanks = find_thanks(changes)
self.assertEqual(expected_thanks, thanks)
self.assertEqual([str]*len(thanks), list(map(type, thanks)))
def test_find_thanks_no_changes(self):
self.assert_thanks_is([], [])
def test_find_thanks_none(self):
changes = [" * Do foo", " * Do bar"]
self.assert_thanks_is(changes, [])
def test_find_thanks(self):
changes = [" * Thanks to A. Hacker"]
self.assert_thanks_is(changes, ["A. Hacker"])
changes = [" * Thanks to James A. Hacker"]
self.assert_thanks_is(changes, ["James A. Hacker"])
changes = [" * Thankyou to B. Hacker"]
self.assert_thanks_is(changes, ["B. Hacker"])
changes = [" * thanks to A. Hacker"]
self.assert_thanks_is(changes, ["A. Hacker"])
changes = [" * thankyou to B. Hacker"]
self.assert_thanks_is(changes, ["B. Hacker"])
changes = [" * Thanks A. Hacker"]
self.assert_thanks_is(changes, ["A. Hacker"])
changes = [" * Thankyou B. Hacker"]
self.assert_thanks_is(changes, ["B. Hacker"])
changes = [" * Thanks to Mark A. Super-Hacker"]
self.assert_thanks_is(changes, ["Mark A. Super-Hacker"])
changes = [" * Thanks to A. Hacker <ahacker@example.com>"]
self.assert_thanks_is(changes, ["A. Hacker <ahacker@example.com>"])
changes = [" * Thanks to Adeodato Sim\xc3\xb3"]
self.assert_thanks_is(changes, ["Adeodato Sim\xc3\xb3"])
changes = [" * Thanks to \xc1deodato Sim\xc3\xb3"]
self.assert_thanks_is(changes, ["\xc1deodato Sim\xc3\xb3"])
def test_find_bugs_fixed_no_changes(self):
self.assertEqual([], find_bugs_fixed([], None, _lplib=MockLaunchpad()))
def test_find_bugs_fixed_none(self):
changes = [" * Do foo", " * Do bar"]
bugs = find_bugs_fixed(changes, None, _lplib=MockLaunchpad())
self.assertEqual([], bugs)
def test_find_bugs_fixed_debian(self):
wt = self.make_branch_and_tree(".")
changes = [" * Closes: #12345, 56789", " * closes:bug45678"]
bugs = find_bugs_fixed(changes, wt.branch, _lplib=MockLaunchpad())
self.assertEqual(
["http://bugs.debian.org/12345 fixed",
"http://bugs.debian.org/56789 fixed",
"http://bugs.debian.org/45678 fixed"], bugs)
def test_find_bugs_fixed_debian_with_ubuntu_links(self):
wt = self.make_branch_and_tree(".")
changes = [" * Closes: #12345", " * closes:bug45678"]
lplib = MockLaunchpad(
debian_bug_to_ubuntu_bugs={
"12345": ("998877", "987654"),
"45678": ("87654",)})
bugs = find_bugs_fixed(changes, wt.branch, _lplib=lplib)
self.assertEqual([], lplib.ubuntu_bug_lookups)
self.assertEqual(["12345", "45678"], lplib.debian_bug_lookups)
self.assertEqual(
["http://bugs.debian.org/12345 fixed",
"http://bugs.debian.org/45678 fixed",
"https://launchpad.net/bugs/87654 fixed"], bugs)
def test_find_bugs_fixed_lp(self):
wt = self.make_branch_and_tree(".")
changes = [" * LP: #12345,#56789", " * lp: #45678"]
bugs = find_bugs_fixed(changes, wt.branch, _lplib=MockLaunchpad())
self.assertEqual(
["https://launchpad.net/bugs/12345 fixed",
"https://launchpad.net/bugs/56789 fixed",
"https://launchpad.net/bugs/45678 fixed"], bugs)
def test_find_bugs_fixed_lp_with_debian_links(self):
wt = self.make_branch_and_tree(".")
changes = [" * LP: #12345", " * lp: #45678"]
lplib = MockLaunchpad(
ubuntu_bug_to_debian_bugs={
"12345": ("998877", "987654"), "45678": ("87654",)})
bugs = find_bugs_fixed(changes, wt.branch, _lplib=lplib)
self.assertEqual([], lplib.debian_bug_lookups)
self.assertEqual(["12345", "45678"], lplib.ubuntu_bug_lookups)
self.assertEqual(
["https://launchpad.net/bugs/12345 fixed",
"https://launchpad.net/bugs/45678 fixed",
"http://bugs.debian.org/87654 fixed"], bugs)
def test_get_commit_info_none(self):
wt = self.make_branch_and_tree(".")
changelog = Changelog()
message, authors, thanks, bugs = get_commit_info_from_changelog(
changelog, wt.branch, _lplib=MockLaunchpad())
self.assertEqual(None, message)
self.assertEqual([], authors)
self.assertEqual([], thanks)
self.assertEqual([], bugs)
def test_get_commit_message_info(self):
wt = self.make_branch_and_tree(".")
changelog = Changelog()
changes = [" [ A. Hacker ]", " * First change, LP: #12345",
" * Second change, thanks to B. Hacker"]
author = "J. Maintainer <maint@example.com"
changelog.new_block(changes=changes, author=author)
message, authors, thanks, bugs = get_commit_info_from_changelog(
changelog, wt.branch, _lplib=MockLaunchpad())
self.assertEqual("\n".join(strip_changelog_message(changes)), message)
self.assertEqual([author]+find_extra_authors(changes), authors)
self.assertEqual(str, type(authors[0]))
self.assertEqual(find_thanks(changes), thanks)
self.assertEqual(find_bugs_fixed(
changes, wt.branch, _lplib=MockLaunchpad()), bugs)
def assertUnicodeCommitInfo(self, changes):
wt = self.make_branch_and_tree(".")
changelog = Changelog()
author = "J. Maintainer <maint@example.com>"
changelog.new_block(changes=changes, author=author)
message, authors, thanks, bugs = get_commit_info_from_changelog(
changelog, wt.branch, _lplib=MockLaunchpad())
self.assertEqual('[ \xc1. Hacker ]\n'
'* First ch\xe1nge, LP: #12345\n'
'* Second change, thanks to \xde. Hacker',
message)
self.assertEqual([author, '\xc1. Hacker'], authors)
self.assertEqual(str, type(authors[0]))
self.assertEqual(['\xde. Hacker'], thanks)
self.assertEqual(['https://launchpad.net/bugs/12345 fixed'], bugs)
def test_get_commit_info_unicode(self):
changes = [" [ \xc1. Hacker ]",
" * First ch\xe1nge, LP: #12345",
" * Second change, thanks to \xde. Hacker"]
self.assertUnicodeCommitInfo(changes)
class MockLaunchpad:
def __init__(self, debian_bug_to_ubuntu_bugs={},
ubuntu_bug_to_debian_bugs={}):
self.debian_bug_to_ubuntu_bugs = debian_bug_to_ubuntu_bugs
self.ubuntu_bug_to_debian_bugs = ubuntu_bug_to_debian_bugs
self.debian_bug_lookups = []
self.ubuntu_bug_lookups = []
def ubuntu_bugs_for_debian_bug(self, debian_bug):
self.debian_bug_lookups.append(debian_bug)
try:
return self.debian_bug_to_ubuntu_bugs[debian_bug]
except KeyError:
return []
def debian_bugs_for_ubuntu_bug(self, ubuntu_bug):
self.ubuntu_bug_lookups.append(ubuntu_bug)
try:
return self.ubuntu_bug_to_debian_bugs[ubuntu_bug]
except KeyError:
return []
class FindPreviousUploadTests(TestCase):
def make_changelog(self, versions_and_distributions):
cl = Changelog()
changes = [" [ A. Hacker ]", " * Something"]
author = "J. Maintainer <maint@example.com>"
for version, distro in versions_and_distributions:
cl.new_block(changes=changes, author=author,
distributions=distro, version=version)
return cl
def test_find_previous_upload_debian(self):
cl = self.make_changelog(
[("0.1-1", "unstable"),
("0.1-2", "unstable")])
self.assertEqual(Version("0.1-1"), changelog_find_previous_upload(cl))
cl = self.make_changelog(
[("0.1-1", "unstable"),
("0.1-1.1", "stable-security"), ("0.1-2", "unstable")])
self.assertEqual(Version("0.1-1"), changelog_find_previous_upload(cl))
def test_find_previous_upload_ubuntu(self):
cl = self.make_changelog(
[("0.1-1", "lucid"),
("0.1-2", "lucid")])
self.assertEqual(Version("0.1-1"), changelog_find_previous_upload(cl))
cl = self.make_changelog(
[("0.1-1", "lucid"),
("0.1-1.1", "unstable"), ("0.1-2", "maverick")])
self.requireFeature(DistroInfoFeature)
self.assertEqual(
Version("0.1-1"), changelog_find_previous_upload(cl))
def test_find_previous_upload_ubuntu_pocket(self):
cl = self.make_changelog(
[("0.1-1", "lucid-updates"),
("0.1-2", "lucid-updates")])
self.assertEqual(Version("0.1-1"), changelog_find_previous_upload(cl))
def test_find_previous_upload_unknown(self):
cl = self.make_changelog(
[("0.1-1", "lucid"),
("0.1-2", "dunno")])
self.assertRaises(NoPreviousUpload, changelog_find_previous_upload, cl)
def test_find_previous_upload_missing(self):
cl = self.make_changelog(
[("0.1-1", "unstable"),
("0.1-2", "lucid")])
self.assertRaises(NoPreviousUpload, changelog_find_previous_upload, cl)
cl = self.make_changelog([("0.1-1", "unstable")])
self.assertRaises(NoPreviousUpload, changelog_find_previous_upload, cl)
def test_find_previous_upload_unreleased(self):
cl = self.make_changelog(
[("0.1-1", "unstable"),
("0.1-2", "UNRELEASED")])
self.assertEqual(Version("0.1-1"), changelog_find_previous_upload(cl))
class SourceFormatTests(TestCaseWithTransport):
def test_no_source_format_file(self):
tree = self.make_branch_and_tree('.')
self.assertEqual("1.0", tree_get_source_format(tree))
def test_source_format_newline(self):
tree = self.make_branch_and_tree('.')
self.build_tree_contents(
[("debian/", ), ("debian/source/",),
("debian/source/format", "3.0 (native)\n")])
tree.add(["debian", "debian/source", "debian/source/format"])
self.assertEqual("3.0 (native)", tree_get_source_format(tree))
def test_source_format(self):
tree = self.make_branch_and_tree('.')
self.build_tree_contents(
[("debian/",), ("debian/source/",),
("debian/source/format", "3.0 (quilt)")])
tree.add(["debian", "debian/source", "debian/source/format"])
self.assertEqual("3.0 (quilt)", tree_get_source_format(tree))
def test_source_format_file_unversioned(self):
tree = self.make_branch_and_tree('.')
self.build_tree_contents(
[("debian/",), ("debian/source/",),
("debian/source/format", "3.0 (quilt)")])
self.assertEqual("3.0 (quilt)", tree_get_source_format(tree))
class GuessBuildTypeTests(TestCaseWithTransport):
def writeVersionFile(self, tree, format_string):
self.build_tree_contents(
[("debian/",), ("debian/source/",),
("debian/source/format", format_string)])
tree.add(["debian", "debian/source", "debian/source/format"])
def test_normal_source_format(self):
tree = self.make_branch_and_tree('.')
self.writeVersionFile(tree, "3.0 (quilt)")
self.assertEqual(
BUILD_TYPE_NORMAL,
guess_build_type(tree, None, contains_upstream_source=True))
def test_normal_source_format_merge(self):
tree = self.make_branch_and_tree('.')
self.writeVersionFile(tree, "3.0 (quilt)")
self.assertEqual(
BUILD_TYPE_MERGE,
guess_build_type(tree, None, contains_upstream_source=False))
def test_native_source_format(self):
tree = self.make_branch_and_tree('.')
self.writeVersionFile(tree, "3.0 (native)")
self.assertEqual(
BUILD_TYPE_NATIVE,
guess_build_type(tree, None, contains_upstream_source=True))
def test_prev_version_native(self):
tree = self.make_branch_and_tree('.')
self.assertEqual(
BUILD_TYPE_NATIVE,
guess_build_type(
tree, Version("1.0"), contains_upstream_source=True))
def test_empty(self):
tree = self.make_branch_and_tree('.')
self.assertEqual(
BUILD_TYPE_NORMAL,
guess_build_type(
tree, Version("1.0-1"), contains_upstream_source=None))
def test_no_upstream_source(self):
tree = self.make_branch_and_tree('.')
tree.mkdir("debian")
self.assertEqual(
BUILD_TYPE_MERGE,
guess_build_type(
tree, Version("1.0-1"), contains_upstream_source=False))
def test_default(self):
tree = self.make_branch_and_tree('.')
self.assertEqual(
BUILD_TYPE_NORMAL,
guess_build_type(
tree, Version("1.0-1"), contains_upstream_source=True))
def test_inconsistent(self):
tree = self.make_branch_and_tree('.')
self.writeVersionFile(tree, "3.0 (quilt)")
e = self.assertRaises(
InconsistentSourceFormatError, guess_build_type, tree,
Version("1.0"), contains_upstream_source=True)
self.assertEqual(
"Inconsistency between source format and version: "
"version 1.0 is native, format '3.0 (quilt)' is not native.",
str(e))
class TestExtractOrigTarballs(TestCaseInTempDir):
def create_tarball(self, package, version, compression, part=None):
basedir = "{}-{}".format(package, version)
os.mkdir(basedir)
try:
f = open(os.path.join(basedir, "README"), 'w')
try:
f.write("Hi\n")
finally:
f.close()
prefix = "{}_{}.orig".format(package, version)
if part is not None:
prefix += "-%s" % part
tar_path = os.path.abspath(prefix + ".tar." + compression)
if compression == "gz":
f = gzip.GzipFile(tar_path, "w")
elif compression == "bz2":
f = bz2.BZ2File(tar_path, "w")
elif compression == "xz":
import lzma
f = lzma.LZMAFile(tar_path, "w")
else:
raise AssertionError(
"Unknown compressin type %r" % compression)
try:
tf = tarfile.open(None, 'w', f)
try:
tf.add(basedir)
finally:
tf.close()
finally:
f.close()
finally:
shutil.rmtree(basedir)
return tar_path
def test_single_orig_tar_gz(self):
tar_path = self.create_tarball("package", "0.1", "gz")
os.mkdir("target")
extract_orig_tarballs(
[(tar_path, None)], "target", strip_components=1)
self.assertEqual(os.listdir("target"), ["README"])
def test_single_orig_tar_bz2(self):
tar_path = self.create_tarball("package", "0.1", "bz2")
os.mkdir("target")
extract_orig_tarballs(
[(tar_path, None)], "target", strip_components=1)
self.assertEqual(os.listdir("target"), ["README"])
def test_single_orig_tar_xz(self):
self.requireFeature(LzmaFeature)
tar_path = self.create_tarball("package", "0.1", "xz")
os.mkdir("target")
extract_orig_tarballs(
[(tar_path, None)], "target", strip_components=1)
self.assertEqual(os.listdir("target"), ["README"])
def test_multiple_tarballs(self):
base_tar_path = self.create_tarball("package", "0.1", "bz2")
tar_path_extra = self.create_tarball(
"package", "0.1", "bz2", part="extra")
os.mkdir("target")
extract_orig_tarballs(
[(base_tar_path, None), (tar_path_extra, "extra")], "target",
strip_components=1)
self.assertEqual(
sorted(os.listdir("target")),
sorted(["README", "extra"]))
class ComponentFromOrigTarballTests(TestCase):
def test_base_tarball(self):
self.assertIs(
None,
component_from_orig_tarball(
"foo_0.1.orig.tar.gz", "foo", "0.1"))
self.assertRaises(
ValueError,
component_from_orig_tarball, "foo_0.1.orig.tar.gz", "bar", "0.1")
def test_invalid_extension(self):
self.assertRaises(
ValueError,
component_from_orig_tarball, "foo_0.1.orig.unknown", "foo", "0.1")
def test_component(self):
self.assertEqual(
"comp",
component_from_orig_tarball(
"foo_0.1.orig-comp.tar.gz", "foo", "0.1"))
self.assertEqual(
"comp-dash",
component_from_orig_tarball(
"foo_0.1.orig-comp-dash.tar.gz", "foo", "0.1"))
def test_invalid_character(self):
self.assertRaises(
ValueError,
component_from_orig_tarball, "foo_0.1.orig;.tar.gz", "foo", "0.1")
class TreeContainsUpstreamSourceTests(TestCaseWithTransport):
def test_empty(self):
tree = self.make_branch_and_tree('.')
tree.lock_read()
self.addCleanup(tree.unlock)
self.assertIs(None, tree_contains_upstream_source(tree))
def test_debian_dir_only(self):
tree = self.make_branch_and_tree('.')
self.build_tree(['debian/'])
tree.add(['debian'])
tree.lock_read()
self.addCleanup(tree.unlock)
self.assertFalse(tree_contains_upstream_source(tree))
def test_debian_dir_and_bzr_builddeb(self):
tree = self.make_branch_and_tree('.')
self.build_tree(['debian/', '.bzr-builddeb/'])
tree.add(['debian', '.bzr-builddeb'])
tree.lock_read()
self.addCleanup(tree.unlock)
self.assertFalse(tree_contains_upstream_source(tree))
def test_with_upstream_source(self):
tree = self.make_branch_and_tree('.')
self.build_tree(['debian/', 'src/'])
tree.add(['debian', 'src'])
tree.lock_read()
self.addCleanup(tree.unlock)
self.assertTrue(tree_contains_upstream_source(tree))
def test_with_unversioned_extra_data(self):
tree = self.make_branch_and_tree('.')
self.build_tree(['debian/', 'x'])
tree.add(['debian'])
tree.lock_read()
self.addCleanup(tree.unlock)
self.assertFalse(tree_contains_upstream_source(tree))
class FilesExcludedTests(TestCaseWithTransport):
def test_file_missing(self):
tree = self.make_branch_and_tree('.')
self.assertRaises(NoSuchFile, get_files_excluded, tree)
def test_not_set(self):
tree = self.make_branch_and_tree('.')
self.build_tree_contents([
('debian/', ),
('debian/copyright', """\
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: blah
Files: *
Copyright:
(c) Somebody
License: MIT
""")])
tree.add(['debian', 'debian/copyright'])
self.assertEqual([], get_files_excluded(tree))
def test_set(self):
tree = self.make_branch_and_tree('.')
self.build_tree_contents([
('debian/', ),
('debian/copyright', """\
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: blah
Files-Excluded: blah/* flattr.png
Files: *
Copyright:
(c) Somebody
License: MIT
""")])
tree.add(['debian', 'debian/copyright'])
self.assertEqual(['blah/*', 'flattr.png'], get_files_excluded(tree))