diff -Nru breezy-debian-2.8.32ubuntu1/bzrtools_import.py breezy-debian-2.8.35/bzrtools_import.py --- breezy-debian-2.8.32ubuntu1/bzrtools_import.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/bzrtools_import.py 2020-05-08 01:12:30.000000000 +0000 @@ -22,6 +22,12 @@ from ...bzr import generate_ids except ImportError: # brz < 3.0.0 from ... import generate_ids + +try: + from contextlib import ExitStack +except ImportError: # python < 3 + from breezy.cleanup import ExitStack + from ... import urlutils from ...controldir import ControlDir from ...errors import NoSuchFile, BzrCommandError, NotBranchError @@ -94,15 +100,12 @@ exclude=None): if file_ids_from is None: file_ids_from = [] - for other_tree in file_ids_from: - other_tree.lock_read() - try: + with ExitStack() as es: + for other_tree in file_ids_from: + es.enter_context(other_tree.lock_read()) return _import_archive( tree, archive_file, file_ids_from, target_tree=target_tree, exclude=exclude) - finally: - for other_tree in file_ids_from: - other_tree.unlock() def _get_paths_to_process(archive_file, prefix, implied_parents, exclude=None): @@ -131,8 +134,7 @@ def _import_archive(tree, archive_file, file_ids_from, target_tree=None, exclude=None): prefix = common_directory(names_of_files(archive_file)) - tt = TreeTransform(tree) - try: + with TreeTransform(tree) as tt: removed = set() for path, entry in tree.iter_entries_by_dir(): if entry.parent_id is None: @@ -256,8 +258,6 @@ for conflict in cook_conflicts(resolve_conflicts(tt), tt): warning('%s', conflict) tt.apply() - finally: - tt.finalize() def do_import(source, tree_directory=None): diff -Nru breezy-debian-2.8.32ubuntu1/changelog.py breezy-debian-2.8.35/changelog.py --- breezy-debian-2.8.32ubuntu1/changelog.py 2020-02-10 16:57:39.000000000 +0000 +++ breezy-debian-2.8.35/changelog.py 2020-05-08 01:12:30.000000000 +0000 @@ -18,7 +18,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -from __future__ import absolute_import def changelog_changes(tree, basis_tree, cl_path='debian/changelog'): changes = [] diff -Nru breezy-debian-2.8.32ubuntu1/cmds.py breezy-debian-2.8.35/cmds.py --- breezy-debian-2.8.32ubuntu1/cmds.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/cmds.py 2020-05-08 01:12:30.000000000 +0000 @@ -43,7 +43,6 @@ NoWorkingTree, ) from ...option import Option -from ...sixish import text_type from ...trace import mutter, note from ...transport import get_transport from ...workingtree import WorkingTree @@ -95,7 +94,7 @@ export_upstream_opt = Option( 'export-upstream', help="Create the .orig.tar.gz from specified bzr branch before building.", - type=text_type, argname="BRANCH") + type=str, argname="BRANCH") export_upstream_revision_opt = Option( 'export-upstream-revision', help="Select the upstream revision that will be exported.", @@ -549,7 +548,7 @@ directory_opt = Option( 'directory', help='Directory from which to retrieve the packaging data', - short_name='d', type=text_type) + short_name='d', type=str) takes_options = [directory_opt] takes_args = ["version?"] @@ -652,10 +651,10 @@ "this release is targetted at.", type=str) directory_opt = Option('directory', help='Working tree into which to merge.', - short_name='d', type=text_type) + short_name='d', type=str) last_version_opt = Option('last-version', help='The full version of the last time ' - 'upstream was merged.', type=text_type) + 'upstream was merged.', type=str) force_opt = Option('force', help=('Force a merge even if the upstream branch ' 'has not changed.')) @@ -672,11 +671,17 @@ 'Force the use of pristine-tar, even if no ' 'pristine-tar branch exists')) + dist_command_opt = Option( + 'dist-command', type=str, + help='Command to run for creating an upstream tarball from a ' + 'VCS snapshot.') + takes_options = [ package_opt, version_opt, distribution_opt, directory_opt, last_version_opt, force_opt, 'revision', 'merge-type', - snapshot_opt, launchpad_opt, force_pristine_tar_opt] + snapshot_opt, launchpad_opt, force_pristine_tar_opt, + dist_command_opt] def _add_changelog_entry(self, tree, subpath, package, version, distribution_name, changelog): @@ -699,7 +704,7 @@ distribution=None, package=None, directory=".", revision=None, merge_type=None, last_version=None, force=None, snapshot=False, launchpad=False, - force_pristine_tar=False): + force_pristine_tar=False, dist_command=None): from debian.changelog import Version from .errors import PackageVersionNotPresent @@ -781,7 +786,8 @@ if upstream_branch is not None: upstream_branch_source = UpstreamBranchSource.from_branch( - upstream_branch, config=config, local_dir=tree.controldir) + upstream_branch, config=config, local_dir=tree.controldir, + dist_command=dist_command) else: upstream_branch_source = None @@ -789,7 +795,8 @@ try: primary_upstream_source = UpstreamBranchSource.from_branch( Branch.open(location), config=config, - local_dir=tree.controldir) + local_dir=tree.controldir, + dist_command=dist_command) except NotBranchError: primary_upstream_source = TarfileSource(location, version) else: @@ -980,7 +987,7 @@ if files_list is None: files_list = [] if file is not None: - if isinstance(file, text_type): + if isinstance(file, str): file = file.encode('utf-8') sources_file = open_file(file) for line in sources_file: @@ -1006,8 +1013,8 @@ last_version = changelog.version except MissingChangelogError: last_version = None - tempdir = tempfile.mkdtemp(dir=os.path.join(tree.basedir, '..')) - try: + with tempfile.TemporaryDirectory( + dir=os.path.join(tree.basedir, '..')) as tempdir: if last_version is not None: if not db.pristine_upstream_source.has_version( changelog.package, last_version.upstream_version): @@ -1026,10 +1033,8 @@ last_version.upstream_version) db.extract_upstream_tree(upstream_tips, tempdir) else: - db._create_empty_upstream_tree(tempdir) + db.create_empty_upstream_tree(tempdir) self.import_many(db, files_list, orig_target) - finally: - shutil.rmtree(tempdir) class cmd_import_upstream(Command): @@ -1121,7 +1126,7 @@ parents[name] = [base_revid] else: parents = {} - db._create_empty_upstream_tree(tempdir) + db.create_empty_upstream_tree(tempdir) tree = db.branch.basis_tree() tree.lock_read() dbs = DistributionBranchSet() @@ -1417,7 +1422,7 @@ directory_opt = Option('directory', help='Packaging tree for which to generate patch.', - short_name='d', type=text_type) + short_name='d', type=str) no_upstream_check_opt = Option( 'no-upstream-check', @@ -1474,7 +1479,7 @@ origin = describe_origin(branch, revision_id) if packaging_tree is None: packaging_tree = packaging_branch.basis_tree() - builddeb_config = debuild_config(packaging_tree, directory) + builddeb_config = debuild_config(packaging_tree, '') if not no_upstream_check and builddeb_config.upstream_branch: upstream_branch = Branch.open(builddeb_config.upstream_branch) applied_upstream = determine_applied_upstream( diff -Nru breezy-debian-2.8.32ubuntu1/config.py breezy-debian-2.8.35/config.py --- breezy-debian-2.8.32ubuntu1/config.py 2020-02-10 17:04:57.000000000 +0000 +++ breezy-debian-2.8.35/config.py 2020-05-08 01:12:30.000000000 +0000 @@ -126,6 +126,23 @@ The sample files used in this test are included in the builddeb source tree. + >>> import os + >>> import breezy.plugins.debian + >>> d = os.path.dirname(breezy.plugins.debian.__file__) + '/' + >>> c = DebBuildConfig([ + ... (d + 'local.conf', False), + ... (d + 'user.conf', True), + ... (d + 'default.conf', False)]) + >>> print(c.orig_dir) + None + >>> print(c.merge) + True + >>> print(c.build_dir) + defaultbuild + >>> print(c.result_dir) + userresult + >>> print(c.builder) + userbuild """ self._config_files = [] for input in files: @@ -315,10 +332,6 @@ merge = _bool_property('merge', "Run in merge mode") - debug_pristine_tar = _bool_property( - 'debug-pristine-tar', - "Save some context when pristine-tar fails") - @property def build_type(self): if self.merge: diff -Nru breezy-debian-2.8.32ubuntu1/debian/changelog breezy-debian-2.8.35/debian/changelog --- breezy-debian-2.8.32ubuntu1/debian/changelog 2020-02-10 17:04:57.000000000 +0000 +++ breezy-debian-2.8.35/debian/changelog 2020-05-08 01:12:30.000000000 +0000 @@ -1,12 +1,31 @@ -breezy-debian (2.8.32ubuntu1) focal; urgency=medium +breezy-debian (2.8.35) unstable; urgency=medium - * Keep breezy autopkgtest happy: - - Enable absolute_import in many files - - Install quilt plugint tests - - Drop code example from documentation in config.py because it returns - slightly different results in breezy autopkgtest + * Wrap long lines in changelog entries: 2.8.0, 2.5.1, 2.1~0ubuntu1, + 0.14ubuntu1. + * Update standards version to 4.5.0, no changes needed. - -- Balint Reczey Mon, 10 Feb 2020 18:04:57 +0100 + -- Jelmer Vernooij Fri, 08 May 2020 01:12:30 +0000 + +breezy-debian (2.8.34) unstable; urgency=medium + + * If there is no explicit tag set for an imported upstream revision, + scan the revision history for it. + * Try more possible tag options for possible upstream releases. + * Add a --dist-command option to 'bzr merge-upstream'. + * Support falling back to strip-components=0 when the orig tarball + requires it. + + -- Jelmer Vernooij Fri, 17 Apr 2020 23:44:17 +0000 + +breezy-debian (2.8.33) unstable; urgency=medium + + * Update standards version to 4.4.1, no changes needed. + * Set Rules-Requires-Root. + * Rely on -Dpristine-tar to enable pristine-tar debugging, rather than + the custom debug-pristine-tar configuration setting. + * Don't follow symlinks when exporting directories. + + -- Jelmer Vernooij Sun, 22 Mar 2020 13:18:22 +0000 breezy-debian (2.8.32) unstable; urgency=medium @@ -363,8 +382,8 @@ * Support svn-buildpackage tag names to find upstream versions. LP: #874263 * Support --revision argument to merge-package. LP: #888590 - * By default, don't override the commit message from debian/changelog - unless 'commit-message-from-changelog' is explicitly set to True. LP: #812749 + * By default, don't override the commit message from debian/changelog unless + 'commit-message-from-changelog' is explicitly set to True. LP: #812749 * Support running dep3-patch against remote repositories, and with open-ended revision ranges. LP: #893608 * Fix finding orig tarballs in directories also containing filenames @@ -609,7 +628,8 @@ * Don't crash when doing merge-upstream with a branch that does a rename and then ships another file with the old path in the tarball that isn't in the branch. - * Accept None as a valid previous_version value in merge_upstream(). LP: #680945 + * Accept None as a valid previous_version value in merge_upstream(). + LP: #680945 [ Jelmer Vernooij ] @@ -879,7 +899,8 @@ bzr-builddeb (2.1~0ubuntu1) jaunty; urgency=low [ Jelmer Vernooij ] - * Add simple deb: directory service for Bazaar that uses the dpkg Vcs-* fields. + * Add simple deb: directory service for Bazaar that uses the dpkg Vcs-* + fields. * Fix mark-uploaded when used in merge mode. (Closes: #500851) * Support merging upstream from a Bazaar branch. (Closes: #493386) + Also support merging from upstream Subversion branches. (LP: #295275) @@ -1267,7 +1288,8 @@ bzr-builddeb (0.14ubuntu1) feisty; urgency=low - * revert the smart options patch so that the package gets usable with bzr 0.13 again. + * revert the smart options patch so that the package gets usable with bzr 0.13 + again. -- Reinhard Tartler Tue, 16 Jan 2007 23:16:44 +0100 diff -Nru breezy-debian-2.8.32ubuntu1/debian/control breezy-debian-2.8.35/debian/control --- breezy-debian-2.8.32ubuntu1/debian/control 2020-02-10 17:04:57.000000000 +0000 +++ breezy-debian-2.8.35/debian/control 2020-05-08 01:12:30.000000000 +0000 @@ -1,14 +1,14 @@ Source: breezy-debian Section: vcs Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Bazaar Maintainers +Maintainer: Debian Bazaar Maintainers Uploaders: Jelmer Vernooij Build-Depends: python3-all (>= 2.6.6-3), xz-utils, dh-python, debhelper-compat (= 12) Build-Depends-Indep: brz (>= 3.0.0~bzr7290), python3-docutils, python3-debian, python3-apt, patchutils, python3-testtools, pristine-tar, devscripts (>= 2.10.59), python3-subunit, python3-breezy.tests (>= 3.0.0), libalgorithm-merge-perl, python3-distro-info, quilt, python3-dulwich (>= 0.19.9), python3-yaml Vcs-Bzr: https://code.breezy-vcs.org/breezy-debian/unstable Vcs-Browser: https://code.breezy-vcs.org/breezy-debian/unstable -Standards-Version: 4.4.0 +Rules-Requires-Root: no +Standards-Version: 4.5.0 Package: brz-debian Architecture: all diff -Nru breezy-debian-2.8.32ubuntu1/directory.py breezy-debian-2.8.35/directory.py --- breezy-debian-2.8.32ubuntu1/directory.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/directory.py 2020-05-08 01:12:30.000000000 +0000 @@ -21,13 +21,13 @@ from __future__ import absolute_import import re +import sys from ... import urlutils from ...directory_service import directories -from ...sixish import PY3 +from ...errors import DependencyNotPresent from ...trace import note, warning -import apt_pkg from debian.deb822 import Deb822 from debian.changelog import Version @@ -100,8 +100,6 @@ url = git_url_to_bzr_url(url) if branch: branch = urlutils.quote(branch, '') - if not PY3: - branch = branch.encode('utf-8') url = urlutils.join_segment_parameters( url, {'branch': branch}) if subpath: @@ -125,8 +123,6 @@ if branch: branch = urlutils.quote(branch, '') - if not PY3: - branch = branch.encode('utf-8') url = urlutils.join_segment_parameters( url, {'branch': branch}) return url @@ -145,19 +141,31 @@ ] +def source_package_vcs(control): + """Extract the Vcs URL from a source package. + + Args: + control: A source control paragraph + Returns: + Tuple with Vcs type and Vcs URL + Raises: + KeyError: When no Vcs header was found + """ + for prefix in ['Vcs-', 'XS-Vcs-', 'X-Vcs']: + for field, value in control.items(): + if field.startswith(prefix): + vcs_type = field[len(prefix):] + if vcs_type == 'Browser': + continue + return vcs_type, value + raise KeyError + + def source_package_vcs_url(control): """Extract a Breezy-compatible URL from a source package. """ - for vcs, converter in vcs_field_to_bzr_url_converters: - for prefix in ("Vcs-", "X-Vcs-", "XS-Vcs-"): - try: - vcs_url = control[prefix + vcs] - except KeyError: - pass - else: - return (vcs, converter(vcs_url)) - else: - raise KeyError + (vcs_type, vcs_url) = source_package_vcs(control) + return vcs_type, dict(vcs_field_to_bzr_url_converters)[vcs_type](vcs_url) class AptDirectory(object): @@ -169,6 +177,10 @@ else: version = None + try: + import apt_pkg + except ImportError as e: + raise DependencyNotPresent('apt_pkg', e) apt_pkg.init() sources = apt_pkg.SourceRecords() @@ -211,6 +223,11 @@ else: version = None + try: + import apt_pkg + except ImportError as e: + raise DependencyNotPresent('apt_pkg', e) + apt_pkg.init() sources = apt_pkg.SourceRecords() diff -Nru breezy-debian-2.8.32ubuntu1/errors.py breezy-debian-2.8.35/errors.py --- breezy-debian-2.8.32ubuntu1/errors.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/errors.py 2020-05-08 01:12:30.000000000 +0000 @@ -38,13 +38,6 @@ BzrError.__init__(self, package=package, version=version) -class TarFailed(BzrError): - _fmt = "There was an error executing tar to %(operation)s %(tarball)s." - - def __init__(self, operation, tarball): - BzrError.__init__(self, operation=operation, tarball=tarball) - - class UnparseableChangelog(BzrError): _fmt = "There was an error parsing the changelog: %(error)s" diff -Nru breezy-debian-2.8.32ubuntu1/import_dsc.py breezy-debian-2.8.35/import_dsc.py --- breezy-debian-2.8.32ubuntu1/import_dsc.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/import_dsc.py 2020-05-08 01:12:30.000000000 +0000 @@ -28,6 +28,7 @@ from __future__ import absolute_import import calendar +from contextlib import contextmanager import os import shutil import stat @@ -48,11 +49,11 @@ BzrError, AlreadyBranchError, NotBranchError, + NoRoundtrippingSupport, NoWorkingTree, UnrelatedBranches, ) from ...revision import NULL_REVISION -from ...sixish import viewitems from ...trace import warning, mutter from ...transport import ( get_transport, @@ -562,8 +563,7 @@ pristine_upstream_revids = branch.pristine_upstream_source\ .version_as_revisions( package, version, tarballs=upstream_tarballs) - for (component, pristine_upstream_revid) in viewitems( - pristine_upstream_revids): + for (component, pristine_upstream_revid) in pristine_upstream_revids.items(): if not graph.is_ancestor( up_branch.last_revision(), pristine_upstream_revid): return False @@ -667,7 +667,7 @@ assert isinstance(version, str) pull_revisions = pull_branch.pristine_upstream_source.version_as_revisions( package, version) - for (component, pull_revision) in viewitems(pull_revisions): + for (component, pull_revision) in pull_revisions.items(): mutter("Fetching upstream part %s of %s from revision %s", component, version, pull_revision) assert self.pristine_upstream_tree is not None, \ @@ -676,8 +676,7 @@ pull_branch.pristine_upstream_branch, stop_revision=pull_revision) self.pristine_upstream_source.tag_version(version, pull_revision) - self.branch.fetch( - self.pristine_upstream_branch, last_revision=pull_revision) + self.branch.fetch(self.pristine_upstream_branch, pull_revision) self.pristine_upstream_branch.tags.merge_to(self.branch.tags) checkout_upstream_version( self.pristine_upstream_tree, package, version, pull_revisions) @@ -709,7 +708,7 @@ str(version), pull_revision) assert self.tree is not None, "Can't pull branch with no tree" self.tree.pull(pull_branch.branch, stop_revision=pull_revision) - self.tag_version(version, revid=pull_revision) + tag_name = self.tag_version(version, revid=pull_revision) if not native and not self.pristine_upstream_source.has_version( package, version.upstream_version): if pull_branch.pristine_upstream_source.has_version( @@ -733,6 +732,7 @@ else: mutter("Not importing the upstream part as it is already " "present in the upstream branch") + return tag_name def get_parents_with_upstream(self, package, version, versions, tarballs, force_upstream_parent=False): @@ -792,8 +792,7 @@ # since self.tree was locked. self.branch.repository.refresh_data() for (component, tag, revid) in imported_revids: - self.branch.fetch( - self.pristine_upstream_branch, last_revision=revid) + self.branch.fetch(self.pristine_upstream_branch, revid) self.pristine_upstream_branch.tags.merge_to(self.branch.tags) def import_upstream(self, upstream_part, package, version, @@ -840,8 +839,13 @@ if revid is None: # FIXME: This is wrong for component tarballs revid = upstream_branch.last_revision() - self.pristine_upstream_branch.fetch( - upstream_branch, last_revision=revid) + try: + self.pristine_upstream_branch.fetch( + upstream_branch, revid) + except NoRoundtrippingSupport: + fetch_result = self.pristine_upstream_branch.fetch( + upstream_branch, revid, lossy=True) + revid = fetch_result.revidmap[revid] upstream_branch.tags.merge_to( self.pristine_upstream_branch.tags) parents.append(revid) @@ -882,7 +886,8 @@ package, version, self.pristine_upstream_tree, parents, component, md5, tarball, author=author, timestamp=timestamp, exclude=exclude, force_pristine_tar=force_pristine_tar, - committer=committer, files_excluded=files_excluded) + committer=committer, files_excluded=files_excluded, + reuse_existing=True) self.pristine_upstream_branch.generate_revision_history(revid) ret.append((component, tag, revid)) self.branch.fetch(self.pristine_upstream_branch) @@ -905,15 +910,12 @@ :param md5sum: hex digest of the md5sum of the tarball, if known. :return: list with (component, tag, revid) tuples """ - tarball_dir = self._extract_tarballs_to_tempdir(tarballs) - try: + with _extract_tarballs_to_tempdir(tarballs) as tarball_dir: return self.import_upstream( tarball_dir, package, version, parents, tarballs, upstream_branch=upstream_branch, upstream_revisions=upstream_revisions, force_pristine_tar=force_pristine_tar) - finally: - shutil.rmtree(tarball_dir) def _mark_native_config(self, native): poss_native_tree = self.branch.basis_tree() @@ -1020,14 +1022,19 @@ if message is None: message = 'Import packaging changes for version %s' % \ (str(version),) - revprops = {"deb-md5": md5} - if native: + supports_revprops = ( + self.tree.branch.repository._format. + supports_custom_revision_properties) + revprops = {} + if supports_revprops: + revprops["deb-md5"] = md5 + if native and supports_revprops: revprops['deb-native'] = "True" if authors: revprops['authors'] = "\n".join(authors) - if thanks: + if thanks and supports_revprops: revprops['deb-thanks'] = "\n".join(thanks) - if bugs: + if bugs and supports_revprops: revprops['bugs'] = "\n".join(bugs) timezone = None if timestamp is not None: @@ -1036,7 +1043,7 @@ self._mark_native_config(native) revid = self.tree.commit( message, revprops=revprops, timestamp=timestamp, timezone=timezone) - self.tag_version(version, revid=revid) + return self.tag_version(version, revid=revid) def upstream_parents(self, package, versions, version): """Get the parents for importing a new upstream. @@ -1061,8 +1068,7 @@ package, last_contained_version.upstream_version)): revid = self.revid_of_version(last_contained_version) parents.append(revid) - self.pristine_upstream_branch.fetch( - self.branch, last_revision=revid) + self.pristine_upstream_branch.fetch(self.branch, revid) pull_parents = self.get_parents(versions) if ((first_parent == NULL_REVISION and len(pull_parents) > 0) or len(pull_parents) > 1): @@ -1083,7 +1089,7 @@ parents.append(pull_revid) self.pristine_upstream_branch.fetch( pull_branch.pristine_upstream_branch, - last_revision=pull_revid) + pull_revid) pull_branch.pristine_upstream_branch.tags.merge_to( self.pristine_upstream_branch.tags) # FIXME: What about other versions ? @@ -1105,7 +1111,7 @@ def _fetch_from_branch(self, branch, revid): branch.branch.tags.merge_to(self.branch.tags) - self.branch.fetch(branch.branch, last_revision=revid) + self.branch.fetch(branch.branch, revid) if self.pristine_upstream_branch.last_revision() == NULL_REVISION: self.pristine_upstream_tree.pull(branch.pristine_upstream_branch) branch.pristine_upstream_branch.tags.merge_to( @@ -1172,7 +1178,7 @@ package, version, versions, upstream_tarballs, force_upstream_parent=imported_upstream) # Now we have the list of parents we need to import the .diff.gz - self.import_debian( + return self.import_debian( debian_part, version, parents, md5, timestamp=timestamp, file_ids_from=file_ids_from) @@ -1203,11 +1209,11 @@ if pull_debian: pull_branch = self.branch_to_pull_version_from(version, md5) if pull_branch is not None: - self.pull_version_from_branch( + return self.pull_version_from_branch( pull_branch, package, version, native=True) else: parents = self.get_native_parents(version, versions) - self.import_debian( + return self.import_debian( debian_part, version, parents, md5, native=True, timestamp=timestamp, file_ids_from=file_ids_from) @@ -1230,7 +1236,8 @@ :param use_time_from_changelog: whether to use the current time or the one from the last changelog entry. """ - dsc = deb822.Dsc(open(dsc_filename).read()) + with open(dsc_filename) as f: + dsc = deb822.Dsc(f.read()) version = Version(dsc['Version']) with extract(dsc_filename, dsc) as extractor: cl = self.get_changelog_from_source(extractor.extracted_debianised) @@ -1254,7 +1261,7 @@ # should happen if it isn't. if extractor.extracted_upstream is not None: - self._import_normal_package( + return self._import_normal_package( dsc['Source'], version, versions, extractor.extracted_debianised, extractor.unextracted_debian_md5, @@ -1263,7 +1270,7 @@ file_ids_from=file_ids_from, pull_debian=pull_debian, force_pristine_tar=force_pristine_tar) else: - self._import_native_package( + return self._import_native_package( dsc['Source'], version, versions, extractor.extracted_debianised, extractor.unextracted_debian_md5, timestamp=timestamp, @@ -1291,7 +1298,7 @@ self.pristine_upstream_branch.get_config_stack().set( 'branch.fetch_tags', True) - def _create_empty_upstream_tree(self, basedir): + def create_empty_upstream_tree(self, basedir): to_location = os.path.join(basedir, "upstream") to_transport = get_transport(to_location) to_transport.ensure_base() @@ -1323,17 +1330,6 @@ if root_id and self.pristine_upstream_tree.supports_setting_file_ids(): self.pristine_upstream_tree.set_root_id(root_id) - def _extract_tarballs_to_tempdir(self, tarballs): - tempdir = tempfile.mkdtemp() - try: - extract_orig_tarballs( - [(fn, component) for (fn, component, md5) in tarballs], - tempdir, strip_components=1) - return tempdir - except BaseException: - shutil.rmtree(tempdir) - raise - def _export_previous_upstream_tree( self, package, previous_version, tempdir): try: @@ -1355,14 +1351,15 @@ def merge_upstream(self, tarball_filenames, package, version, previous_version, upstream_branch=None, upstream_revisions=None, merge_type=None, force=False, - force_pristine_tar=False, committer=None, files_excluded=None): + force_pristine_tar=False, committer=None, + files_excluded=None): tempdir = tempfile.mkdtemp(dir=os.path.join(self.tree.basedir, '..')) try: if previous_version is not None: self._export_previous_upstream_tree( package, previous_version, tempdir) else: - self._create_empty_upstream_tree(tempdir) + self.create_empty_upstream_tree(tempdir) if self.pristine_upstream_source.has_version(package, version): raise UpstreamAlreadyImported(version) if upstream_branch is not None: @@ -1378,8 +1375,7 @@ (os.path.abspath(fn), component, md5sum_filename(fn)) for (fn, component) in tarball_filenames] - tarball_dir = self._extract_tarballs_to_tempdir(upstream_tarballs) - try: + with _extract_tarballs_to_tempdir(upstream_tarballs) as tarball_dir: # FIXME: should use upstream_parents()? parents = {None: []} if self.pristine_upstream_branch.last_revision() != NULL_REVISION: @@ -1392,12 +1388,11 @@ force_pristine_tar=force_pristine_tar, committer=committer, files_excluded=files_excluded) self._fetch_upstream_to_branch(imported_revids) - finally: - shutil.rmtree(tarball_dir) if self.branch.last_revision() != NULL_REVISION: try: conflicts = self.tree.merge_from_branch( - self.pristine_upstream_branch, merge_type=merge_type) + self.pristine_upstream_branch, + merge_type=merge_type) except UnrelatedBranches: # Bug lp:515367 where the first upstream tarball is # missing a proper history link and a criss-cross merge @@ -1408,8 +1403,8 @@ else: from_revision = parents[None][0] conflicts = self.tree.merge_from_branch( - self.pristine_upstream_branch, merge_type=merge_type, - from_revision=from_revision) + self.pristine_upstream_branch, + merge_type=merge_type, from_revision=from_revision) else: # Pull so that merge-upstream allows you to start a branch # from upstream tarball. @@ -1423,3 +1418,14 @@ finally: shutil.rmtree(tempdir) + +@contextmanager +def _extract_tarballs_to_tempdir(tarballs): + tempdir = tempfile.mkdtemp() + try: + extract_orig_tarballs( + [(fn, component) for (fn, component, md5) in tarballs], + tempdir) + yield tempdir + finally: + shutil.rmtree(tempdir) diff -Nru breezy-debian-2.8.32ubuntu1/__init__.py breezy-debian-2.8.35/__init__.py --- breezy-debian-2.8.32ubuntu1/__init__.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/__init__.py 2020-05-08 01:12:30.000000000 +0000 @@ -30,9 +30,6 @@ import breezy from ...commands import plugin_cmds from ...hooks import install_lazy_named_hook -from ...sixish import ( - viewitems, - ) from ... import trace from .info import ( @@ -58,13 +55,10 @@ "debrelease": [], } -for command, aliases in viewitems(commands): +for command, aliases in commands.items(): plugin_cmds.register_lazy( 'cmd_' + command, aliases, __name__ + ".cmds") -builddeb_dir = '.bzr-builddeb' -default_conf = os.path.join(builddeb_dir, 'default.conf') - def global_conf(): try: @@ -74,10 +68,6 @@ return os.path.join(config_dir(), 'builddeb.conf') -local_conf = os.path.join(builddeb_dir, 'local.conf') -new_local_conf = 'debian/local.conf.local' -new_conf = 'debian/bzr-builddeb.conf' - default_build_dir = '../build-area' default_orig_dir = '..' default_result_dir = '..' @@ -195,10 +185,12 @@ from .util import ( debuild_config, find_changelog, MissingChangelogError) t = branch.repository.revision_tree(revid) - config = debuild_config(t) + subpath = '' + config = debuild_config(t, subpath=subpath) try: (changelog, top_level) = find_changelog( - t, config.build_type == BUILD_TYPE_MERGE) + t, subpath=subpath, + merge=(config.build_type == BUILD_TYPE_MERGE)) except MissingChangelogError: # Not a debian package return None diff -Nru breezy-debian-2.8.32ubuntu1/Makefile breezy-debian-2.8.35/Makefile --- breezy-debian-2.8.32ubuntu1/Makefile 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/Makefile 2020-05-08 01:12:30.000000000 +0000 @@ -1,6 +1,6 @@ BRZ ?= $(shell which brz) BRZ_OPTIONS ?= -Derror -PYTHON ?= $(shell which python) +PYTHON ?= $(shell which python3) SETUP ?= $(PYTHON) ./setup.py TESTS ?= "^breezy.plugins.debian." "^unittest" diff -Nru breezy-debian-2.8.32ubuntu1/merge_package.py breezy-debian-2.8.35/merge_package.py --- breezy-debian-2.8.32ubuntu1/merge_package.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/merge_package.py 2020-05-08 01:12:30.000000000 +0000 @@ -155,9 +155,8 @@ # hence the call to refresh the data in the /target/ repo. tree.branch.repository.refresh_data() - tree.branch.fetch(source, last_revision=us_revid) - tree.branch.fetch( - tmp_target_utree.branch, last_revision=new_revid) + tree.branch.fetch(source, us_revid) + tree.branch.fetch(tmp_target_utree.branch, new_revid) # Merge shared upstream parent into the target merge # branch. This creates revison L in the digram above. diff -Nru breezy-debian-2.8.32ubuntu1/quilt/__init__.py breezy-debian-2.8.35/quilt/__init__.py --- breezy-debian-2.8.32ubuntu1/quilt/__init__.py 2020-02-10 17:02:32.000000000 +0000 +++ breezy-debian-2.8.35/quilt/__init__.py 2020-05-08 01:12:30.000000000 +0000 @@ -25,7 +25,6 @@ """ -from __future__ import absolute_import from ....errors import BzrError from .... import trace diff -Nru breezy-debian-2.8.32ubuntu1/README.rst breezy-debian-2.8.35/README.rst --- breezy-debian-2.8.32ubuntu1/README.rst 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/README.rst 2020-05-08 01:12:30.000000000 +0000 @@ -354,7 +354,7 @@ This file is part of breezy-debian. - bzr-builldeb is free software; you can redistribute it and/or modify + bzr-builddeb is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. diff -Nru breezy-debian-2.8.32ubuntu1/release.py breezy-debian-2.8.35/release.py --- breezy-debian-2.8.32ubuntu1/release.py 2020-02-10 17:02:14.000000000 +0000 +++ breezy-debian-2.8.35/release.py 2020-05-08 01:12:30.000000000 +0000 @@ -18,10 +18,10 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -from __future__ import absolute_import import subprocess from ... import osutils + from .util import ( find_changelog, ) diff -Nru breezy-debian-2.8.32ubuntu1/repack_tarball.py breezy-debian-2.8.35/repack_tarball.py --- breezy-debian-2.8.32ubuntu1/repack_tarball.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/repack_tarball.py 2020-05-08 01:12:30.000000000 +0000 @@ -25,16 +25,8 @@ from io import BytesIO import tarfile import bz2 -try: - import hashlib +import hashlib - def new_sha(*args): - return hashlib.sha1(*args) -except ImportError: - import sha - - def new_sha(*args): - return sha.new(*args) import shutil import time import zipfile @@ -43,9 +35,6 @@ DependencyNotPresent, FileExists, ) -from ...sixish import ( - viewitems, - ) from ...transport import get_transport from .errors import UnsupportedRepackFormat @@ -143,7 +132,7 @@ ".tar": "tar", ".zip": "zip" } - for filetype, name in viewitems(types): + for filetype, name in types.items(): if filename.endswith(filetype): return name @@ -164,9 +153,9 @@ def _error_if_exists(target_transport, new_name, source_name): with open_file(source_name) as source_f: - source_sha = new_sha(source_f.read()).hexdigest() + source_sha = hashlib.sha1(source_f.read()).hexdigest() with open_file_via_transport(new_name, target_transport) as target_f: - target_sha = new_sha(target_f.read()).hexdigest() + target_sha = hashlib.sha1(target_f.read()).hexdigest() if source_sha != target_sha: raise FileExists(new_name) diff -Nru breezy-debian-2.8.32ubuntu1/revspec.py breezy-debian-2.8.35/revspec.py --- breezy-debian-2.8.32ubuntu1/revspec.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/revspec.py 2020-05-08 01:12:30.000000000 +0000 @@ -20,8 +20,12 @@ from __future__ import absolute_import +try: + from ...revisionspec import InvalidRevisionSpec +except ImportError: # breezy < 3.2 + from ...errors import InvalidRevisionSpec + from ...errors import ( - InvalidRevisionSpec, NoSuchTag, ) from ...revisionspec import RevisionSpec, RevisionInfo diff -Nru breezy-debian-2.8.32ubuntu1/setup.py breezy-debian-2.8.35/setup.py --- breezy-debian-2.8.32ubuntu1/setup.py 2020-02-10 17:04:57.000000000 +0000 +++ breezy-debian-2.8.35/setup.py 2020-05-08 01:12:30.000000000 +0000 @@ -38,7 +38,6 @@ url="https://code.breezy-vcs.org/breezy-debian", packages=['breezy.plugins.debian', 'breezy.plugins.debian.quilt', - 'breezy.plugins.debian.quilt.tests', 'breezy.plugins.debian.tests', 'breezy.plugins.debian.tests.blackbox', 'breezy.plugins.debian.upstream'], diff -Nru breezy-debian-2.8.32ubuntu1/source_distiller.py breezy-debian-2.8.35/source_distiller.py --- breezy-debian-2.8.32ubuntu1/source_distiller.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/source_distiller.py 2020-05-08 01:12:30.000000000 +0000 @@ -19,7 +19,6 @@ from __future__ import absolute_import -import glob import os import shutil import tempfile @@ -162,22 +161,9 @@ os.makedirs(parent_dir) if not self.use_existing: tarballs = self.upstream_provider.provide(parent_dir) - # Extract it to the right place - tempdir = tempfile.mkdtemp(prefix='builddeb-merge-') - try: - extract_orig_tarballs(tarballs, tempdir) - files = glob.glob(tempdir+'/*') - # If everything is in a single dir then move everything up one - # level. - if os.path.isdir(target): - shutil.rmtree(target) - if len(files) == 1: - shutil.move(files[0], target) - else: - shutil.move(tempdir, target) - finally: - if os.path.exists(tempdir): - shutil.rmtree(tempdir) + if not os.path.exists(target): + os.mkdir(target) + extract_orig_tarballs(tarballs, target) # Now export the tree to provide the debian dir basetempdir = tempfile.mkdtemp(prefix='builddeb-merge-debian-') try: diff -Nru breezy-debian-2.8.32ubuntu1/tests/blackbox/test_builddeb.py breezy-debian-2.8.35/tests/blackbox/test_builddeb.py --- breezy-debian-2.8.32ubuntu1/tests/blackbox/test_builddeb.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/blackbox/test_builddeb.py 2020-05-08 01:12:30.000000000 +0000 @@ -20,8 +20,6 @@ from __future__ import absolute_import -from breezy.sixish import text_type - import os from .. import BuilddebTestCase @@ -51,14 +49,14 @@ def assertInBuildDir(self, files): build_dir = self.build_dir() - if isinstance(files, (text_type, bytes)): + if not isinstance(files, list): files = [files] for filename in files: self.assertPathExists(os.path.join(build_dir, filename)) def assertNotInBuildDir(self, files): build_dir = self.build_dir() - if isinstance(files, (bytes, text_type)): + if not isinstance(files, list): files = [files] for filename in files: self.assertPathDoesNotExist(os.path.join(build_dir, filename)) diff -Nru breezy-debian-2.8.32ubuntu1/tests/__init__.py breezy-debian-2.8.35/tests/__init__.py --- breezy-debian-2.8.32ubuntu1/tests/__init__.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/__init__.py 2020-05-08 01:12:30.000000000 +0000 @@ -22,13 +22,13 @@ import shutil import subprocess +import sys import tarfile import zipfile import doctest import os -from ....sixish import PY3 from .... import tests from debian.changelog import Version, Changelog @@ -99,10 +99,7 @@ def make_new_upstream_tarball_lzma(source, dest): import lzma - if PY3: - f = lzma.LZMAFile(dest, 'w', format=lzma.FORMAT_ALONE) - else: - f = lzma.LZMAFile(dest, 'w', options={'format': 'alone'}) + f = lzma.LZMAFile(dest, 'w', format=lzma.FORMAT_ALONE) try: tar = tarfile.open(None, 'w', f) try: diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_config.py breezy-debian-2.8.35/tests/test_config.py --- breezy-debian-2.8.32ubuntu1/tests/test_config.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_config.py 2020-05-08 01:12:30.000000000 +0000 @@ -137,11 +137,10 @@ cfg = DebBuildConfig([], tree=branch.basis_tree()) self.assertEquals(False, cfg.merge) - dc = self.get_commit_editor(branch.base) - d = dc.add_dir("debian") - f = d.add_file("debian/svn-layout") - f.modify("origDir = someorigdir\n") - dc.close() + with self.get_commit_editor(branch.base) as dc: + d = dc.add_dir("debian") + f = d.add_file("debian/svn-layout") + f.modify(b"origDir = someorigdir\n") cfg = DebBuildConfig([], tree=branch.basis_tree()) self.assertEquals("someorigdir", cfg.orig_dir) diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_dep3.py breezy-debian-2.8.35/tests/test_dep3.py --- breezy-debian-2.8.32ubuntu1/tests/test_dep3.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_dep3.py 2020-05-08 01:12:30.000000000 +0000 @@ -26,7 +26,7 @@ from ....revision import ( NULL_REVISION, ) -from ....sixish import StringIO +from io import StringIO from ....tests import ( TestCase, diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_merge_changelog.py breezy-debian-2.8.35/tests/test_merge_changelog.py --- breezy-debian-2.8.32ubuntu1/tests/test_merge_changelog.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_merge_changelog.py 2020-05-08 01:12:30.000000000 +0000 @@ -22,6 +22,7 @@ from __future__ import absolute_import import logging +import sys from testtools.content_type import ContentType from testtools.content import Content @@ -30,7 +31,6 @@ merge, tests, ) -from ....sixish import PY3 from ... import debian from .. import merge_changelog from ....tests.features import ExecutableFeature @@ -348,12 +348,8 @@ merger = FakeMerger(tree) params_cls = merge.MergeFileHookParams - if PY3: - from inspect import signature - params_cls_arg_count = len(signature(params_cls).parameters) + 1 - else: - from inspect import getargspec - params_cls_arg_count = len(getargspec(params_cls.__init__)[0]) + from inspect import signature + params_cls_arg_count = len(signature(params_cls).parameters) + 1 # Older versions of Breezy required a file_id to be specified. if params_cls_arg_count == 7: params = params_cls( diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_revspec.py breezy-debian-2.8.35/tests/test_revspec.py --- breezy-debian-2.8.32ubuntu1/tests/test_revspec.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_revspec.py 2020-05-08 01:12:30.000000000 +0000 @@ -22,7 +22,10 @@ import os -from ....errors import InvalidRevisionSpec +try: + from ....revisionspec import InvalidRevisionSpec +except ImportError: # brz < 3.2 + from ....errors import InvalidRevisionSpec from ....revisionspec import RevisionSpec from ....tests.test_revisionspec import TestRevisionSpec diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_upstream.py breezy-debian-2.8.35/tests/test_upstream.py --- breezy-debian-2.8.32ubuntu1/tests/test_upstream.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_upstream.py 2020-05-08 01:12:30.000000000 +0000 @@ -53,7 +53,6 @@ PackageVersionNotPresent, ) -from ....sixish import text_type from . import ( LzmaFeature, XzFeature, @@ -94,7 +93,7 @@ ) -svn_plugin = PluginLoadedFeature('svn') +svn_plugin = ModuleAvailableFeature('breezy.plugins.svn.mapping') dulwich = ModuleAvailableFeature('dulwich') @@ -752,10 +751,18 @@ self.assertEquals("42.0", upstream_tag_to_version(u"bla-42.0", "bla")) def test_unicode(self): - self.assertEquals( - u"42.0\xa9", + self.assertIs( + None, upstream_tag_to_version(u"bla-42.0\xa9", "bla")) + def test_popt(self): + self.assertEquals("1.4", upstream_tag_to_version("popt-1_4", "popt")) + self.assertEquals( + "1.4", upstream_tag_to_version("popt-1_4-release", "popt")) + + def test_perl(self): + self.assertEquals("0.006019", upstream_tag_to_version("v0.006_019")) + class TestUpstreamVersionAddRevision(TestCaseWithTransport): """Test that updating the version string works.""" @@ -1019,30 +1026,26 @@ "upstream-ubuntu-0.3") def test_version(self): - self.assertEquals([ - 'upstream-3.3', - 'upstream-debian-3.3', - 'upstream-ubuntu-3.3', 'upstream/3.3', 'upstream-3.3', - 'upstream_3.3'], - self.source.possible_tag_names("3.3", component=None)) + self.assertEquals( + ['upstream/3.3', 'upstream-3.3', 'upstream_3.3', '3.3', + 'v3.3', 'release-3.3', 'v3.3-release', 'pkg-3.3'], + self.source.possible_tag_names("pkg", "3.3", component=None)) def test_version_with_tilde(self): self.assertEquals([ - 'upstream-3.3~brz232', - 'upstream-debian-3.3~brz232', - 'upstream-ubuntu-3.3~brz232', 'upstream/3.3~brz232', 'upstream-3.3~brz232', 'upstream/3.3_brz232', - 'upstream_3.3~brz232'], - self.source.possible_tag_names("3.3~brz232", component=None)) + 'upstream_3.3~brz232', + '3.3~brz232', + 'v3.3~brz232', + 'pkg-3.3~brz232'], + self.source.possible_tag_names('pkg', "3.3~brz232", component=None)) def test_version_component(self): self.assertEquals([ - 'upstream-3.3/extlib', - 'upstream-debian-3.3/extlib', - 'upstream-ubuntu-3.3/extlib'], - self.source.possible_tag_names("3.3", component="extlib")) + 'upstream-3.3/extlib'], + self.source.possible_tag_names('pkg', "3.3", component="extlib")) def test_version_as_revisions_missing(self): self.assertRaises(PackageVersionNotPresent, @@ -1074,7 +1077,7 @@ revid1 = self.tree.commit("msg") self.tree.branch.tags.set_tag("upstream-2.1", revid1) self.assertRaises(PackageVersionNotPresent, - self.source.version_as_revisions, None, "2.1", [ + self.source.version_as_revisions, 'pkg', "2.1", [ ("upstream_2.1.orig.tar.gz", None, "somemd5sum"), ("upstream_2.1.orig-lib.tar.gz", "lib", "othermd5sum")]) @@ -1120,7 +1123,7 @@ source = TarfileSource(u"foo-1.0.tar.gz") latest_version = source.get_latest_version("foo", u"0.9") self.assertEquals("1.0", latest_version) - self.assertIsInstance(latest_version, text_type) + self.assertIsInstance(latest_version, str) def test_get_latest_version_parses(self): source = TarfileSource("foo-1.0.tar.gz") diff -Nru breezy-debian-2.8.32ubuntu1/tests/test_util.py breezy-debian-2.8.35/tests/test_util.py --- breezy-debian-2.8.32ubuntu1/tests/test_util.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/tests/test_util.py 2020-05-08 01:12:30.000000000 +0000 @@ -78,7 +78,7 @@ ) from .... import errors as bzr_errors -from ....sixish import text_type +from six import text_type from ....tests import ( TestCase, ) @@ -110,6 +110,15 @@ 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')) + class SafeDecodeTests(TestCase): @@ -193,16 +202,19 @@ tree = self.make_branch_and_tree('.') self.write_changelog('changelog') tree.add(['changelog']) - self.assertRaises(MissingChangelogError, find_changelog, tree, merge=False) + 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) + 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) + self.assertRaises( + MissingChangelogError, find_changelog, tree, merge=True) def test_find_changelog_symlink(self): """When there was a symlink debian -> . then the code used to break""" @@ -616,9 +628,8 @@ 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()) + message, authors, thanks, bugs = get_commit_info_from_changelog( + changelog, wt.branch, _lplib=MockLaunchpad()) self.assertEqual(None, message) self.assertEqual([], authors) self.assertEqual([], thanks) @@ -631,24 +642,22 @@ " * Second change, thanks to B. Hacker"] author = "J. Maintainer MERGE tree = self.make_branch_and_tree('.') self.writeVersionFile(tree, "3.0 (quilt)") - self.assertEquals(BUILD_TYPE_MERGE, guess_build_type(tree, None, contains_upstream_source=False)) + self.assertEquals( + BUILD_TYPE_MERGE, + guess_build_type(tree, None, contains_upstream_source=False)) def test_native_source_format(self): # Native source format -> NATIVE tree = self.make_branch_and_tree('.') self.writeVersionFile(tree, "3.0 (native)") - self.assertEquals(BUILD_TYPE_NATIVE, guess_build_type(tree, None, contains_upstream_source=True)) + self.assertEquals( + BUILD_TYPE_NATIVE, + guess_build_type(tree, None, contains_upstream_source=True)) def test_prev_version_native(self): # Native package version -> NATIVE tree = self.make_branch_and_tree('.') - self.assertEquals(BUILD_TYPE_NATIVE, - guess_build_type(tree, Version("1.0"), contains_upstream_source=True)) + self.assertEquals( + BUILD_TYPE_NATIVE, + guess_build_type( + tree, Version("1.0"), contains_upstream_source=True)) def test_empty(self): # Empty tree and a non-native package -> NORMAL tree = self.make_branch_and_tree('.') - self.assertEquals(BUILD_TYPE_NORMAL, - guess_build_type(tree, Version("1.0-1"), contains_upstream_source=None)) + self.assertEquals( + BUILD_TYPE_NORMAL, + guess_build_type( + tree, Version("1.0-1"), contains_upstream_source=None)) def test_no_upstream_source(self): # No upstream source code and a non-native package -> MERGE tree = self.make_branch_and_tree('.') tree.mkdir("debian") - self.assertEquals(BUILD_TYPE_MERGE, - guess_build_type(tree, Version("1.0-1"), contains_upstream_source=False)) + self.assertEquals( + BUILD_TYPE_MERGE, + guess_build_type( + tree, Version("1.0-1"), contains_upstream_source=False)) def test_default(self): # Upstream source code and a non-native package -> NORMAL tree = self.make_branch_and_tree('.') - self.assertEquals(BUILD_TYPE_NORMAL, - guess_build_type(tree, Version("1.0-1"), contains_upstream_source=True)) + self.assertEquals( + BUILD_TYPE_NORMAL, + guess_build_type( + tree, Version("1.0-1"), contains_upstream_source=True)) def test_inconsistent(self): - # If version string and source format disagree on whether the package is native, - # raise an exception. + # If version string and source format disagree on whether the package + # is native, raise an exception. tree = self.make_branch_and_tree('.') self.writeVersionFile(tree, "3.0 (native)") - e = self.assertRaises(InconsistentSourceFormatError, guess_build_type, tree, + e = self.assertRaises( + InconsistentSourceFormatError, guess_build_type, tree, Version("1.0-1"), contains_upstream_source=True) self.assertEquals( - "Inconsistency between source format and version: version is not native, " - "format is native.", str(e)) + "Inconsistency between source format and version: " + "version is not native, format is native.", str(e)) class TestExtractOrigTarballs(TestCaseInTempDir): @@ -889,8 +924,8 @@ import lzma f = lzma.LZMAFile(tar_path, "w") else: - raise AssertionError("Unknown compressin type %r" % - compression) + raise AssertionError( + "Unknown compressin type %r" % compression) try: tf = tarfile.open(None, 'w', f) try: @@ -906,55 +941,67 @@ 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) + extract_orig_tarballs( + [(tar_path, None)], "target", strip_components=1) self.assertEquals(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) + extract_orig_tarballs( + [(tar_path, None)], "target", strip_components=1) self.assertEquals(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) + extract_orig_tarballs( + [(tar_path, None)], "target", strip_components=1) self.assertEquals(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") + 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", + extract_orig_tarballs( + [(base_tar_path, None), (tar_path_extra, "extra")], "target", strip_components=1) - self.assertEquals(sorted(os.listdir("target")), + self.assertEquals( + 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, + 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, + self.assertRaises( + ValueError, component_from_orig_tarball, "foo_0.1.orig.unknown", "foo", "0.1") def test_component(self): - self.assertEquals("comp", - component_from_orig_tarball("foo_0.1.orig-comp.tar.gz", "foo", "0.1")) - self.assertEquals("comp-dash", - component_from_orig_tarball("foo_0.1.orig-comp-dash.tar.gz", "foo", "0.1")) + self.assertEquals( + "comp", + component_from_orig_tarball( + "foo_0.1.orig-comp.tar.gz", "foo", "0.1")) + self.assertEquals( + "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, + self.assertRaises( + ValueError, component_from_orig_tarball, "foo_0.1.orig;.tar.gz", "foo", "0.1") diff -Nru breezy-debian-2.8.32ubuntu1/.travis.yml breezy-debian-2.8.35/.travis.yml --- breezy-debian-2.8.32ubuntu1/.travis.yml 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/.travis.yml 2020-05-08 01:12:30.000000000 +0000 @@ -11,12 +11,17 @@ - 2.7 - 3.5 - 3.6 + - 3.7 + - 3.8 script: - make check install: - sudo apt install python-all-dev subunit python-debian python-apt python-testtools patchutils pristine-tar devscripts python-lzma libalgorithm-merge-perl python-distro-info quilt python-yaml + - pip install cython + - if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then pip install pyliblzma; fi + - pip install git+https://salsa.debian.org/python-debian-team/python-debian - travis_retry pip install -U setuptools - travis_retry pip install -U pip coverage codecov flake8 testtools paramiko fastimport configobj cython testscenarios six docutils python-subunit dulwich bzr+lp:brz pyyaml diff -Nru breezy-debian-2.8.32ubuntu1/upstream/branch.py breezy-debian-2.8.35/upstream/branch.py --- breezy-debian-2.8.32ubuntu1/upstream/branch.py 2020-02-10 17:04:39.000000000 +0000 +++ breezy-debian-2.8.35/upstream/branch.py 2020-05-08 01:12:30.000000000 +0000 @@ -18,8 +18,10 @@ # along with bzr-builddeb; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from __future__ import absolute_import +import os import re +import subprocess +import tempfile from .... import osutils from ....branch import ( @@ -28,18 +30,23 @@ ) from ....bzr import branch as bzr_branch from ....errors import ( + BzrError, GhostRevisionsHaveNoRevno, InvalidRevisionId, - InvalidRevisionSpec, NoSuchRevision, NoSuchTag, + RevisionNotPresent, UnsupportedOperation, ) from ....lock import _RelockDebugMixin, LogicalLockResult from ....revision import NULL_REVISION from ....revisionspec import RevisionSpec -from ....sixish import text_type -from ....trace import note +from ....trace import note, mutter + +try: + from ....revisionspec import InvalidRevisionSpec +except ImportError: # Breezy < 3.2 + from ....errors import InvalidRevisionSpec from ..errors import ( MultipleUpstreamTarballsNotSupported, @@ -54,22 +61,30 @@ def upstream_tag_to_version(tag_name, package=None): """Take a tag name and return the upstream version, or None.""" - assert isinstance(tag_name, text_type) + if tag_name.endswith('-release'): + tag_name = tag_name[:-len('-release')] + if tag_name.startswith("release-"): + tag_name = tag_name[len("release-"):] + if tag_name[0] == "v" and tag_name[1].isdigit(): + tag_name = tag_name[1:] if (package is not None and ( tag_name.startswith("%s-" % package) or tag_name.startswith("%s_" % package))): - return tag_name[len(package)+1:] - if tag_name.startswith("release-"): - return tag_name[len("release-"):] - if tag_name[0] == "v" and tag_name[1].isdigit(): - return tag_name[1:] + tag_name = tag_name[len(package)+1:] + if '_' in tag_name and '.' not in tag_name: + tag_name = tag_name.replace('_', '.') + if tag_name.count('_') == 1 and tag_name.startswith('0.'): + # This is a style commonly used for perl packages. + # Most debian packages seem to just drop the underscore. + tag_name = tag_name.replace('_', '') if all([c.isdigit() or c in (".", "~") for c in tag_name]): return tag_name return None -def _upstream_branch_version(revhistory, upstream_revision, reverse_tag_dict, package, - previous_version, add_rev): +def _upstream_branch_version( + revhistory, upstream_revision, reverse_tag_dict, package, + previous_version, add_rev): """Determine the version string of an upstream branch. The upstream version is determined from the most recent tag @@ -84,7 +99,8 @@ :param reverse_tag_dict: Reverse tag dictionary (revid -> list of tags) :param package: Name of package. :param previous_version: Previous upstream version in debian changelog. - :param add_rev: Function that can add a revision suffix to a version string. + :param add_rev: Function that can add a revision suffix to a version + string. :return: Name of the upstream revision. """ if upstream_revision == NULL_REVISION: @@ -243,7 +259,7 @@ def upstream_branch_version(upstream_branch, upstream_revision, package, - previous_version): + previous_version): """Determine the version string for a revision in an upstream branch. :param upstream_branch: The upstream branch object @@ -254,14 +270,20 @@ """ graph = upstream_branch.repository.get_graph() previous_revision = get_snapshot_revision(previous_version) + stop_revids = None if previous_revision is not None: previous_revspec = RevisionSpec.from_string(previous_revision) - previous_revno, previous_revid = previous_revspec.in_history(upstream_branch) - # Trim revision history - we don't care about any revisions - # before the revision of the previous version - stop_revids = [previous_revid] - else: - stop_revids = None + try: + previous_revno, previous_revid = previous_revspec.in_history( + upstream_branch) + except InvalidRevisionSpec as e: + # Odd - the revision mentioned in the old version doesn't exist. + mutter('Unable to find old upstream version %s (%s): %s', + previous_version, previous_revision, e) + else: + # Trim revision history - we don't care about any revisions + # before the revision of the previous version + stop_revids = [previous_revid] revhistory = graph.iter_lefthand_ancestry(upstream_revision, stop_revids) return _upstream_branch_version( revhistory, upstream_revision, @@ -383,9 +405,10 @@ """ def __init__(self, upstream_branch, upstream_revision_map=None, - config=None, actual_branch=None): + config=None, actual_branch=None, dist_command=None): self.upstream_branch = upstream_branch self._actual_branch = actual_branch or upstream_branch + self.dist_command = dist_command self.config = config if upstream_revision_map is None: self.upstream_revision_map = {} @@ -394,7 +417,7 @@ @classmethod def from_branch(cls, upstream_branch, upstream_revision_map=None, - config=None, local_dir=None): + config=None, local_dir=None, dist_command=None): """Create a new upstream branch source from a branch. This will optionally fetch into a local directory. @@ -417,7 +440,7 @@ return cls( upstream_branch=upstream_branch, upstream_revision_map=upstream_revision_map, config=config, - actual_branch=actual_branch) + actual_branch=actual_branch, dist_command=dist_command) def version_as_revision(self, package, version, tarballs=None): if version in self.upstream_revision_map: @@ -496,16 +519,19 @@ raise PackageVersionNotPresent(package, version, self) target_filename = self._tarball_path( package, version, None, target_dir) - tarball_base = "%s-%s" % (package, version) rev_tree = self.upstream_branch.repository.revision_tree(revid) - try: - export(rev_tree, target_filename, 'tgz', tarball_base) - except UnsupportedOperation as e: - note('Not exporting revision from upstream branch: %s', e) - raise PackageVersionNotPresent(package, version, self) - else: - note("Exporting upstream branch revision %s to create " - "the tarball", revid) + if self.dist_command is None or not run_dist_command( + rev_tree, package, version, target_filename, + self.dist_command): + tarball_base = "%s-%s" % (package, version) + try: + export(rev_tree, target_filename, 'tgz', tarball_base) + except UnsupportedOperation as e: + note('Not exporting revision from upstream branch: %s', e) + raise PackageVersionNotPresent(package, version, self) + else: + note("Exporting upstream branch revision %s to create " + "the tarball", revid) return [target_filename] def __repr__(self): @@ -518,10 +544,11 @@ """ def __init__(self, upstream_branch_url, upstream_revision_map=None, - config=None): + config=None, dist_command=None): self.upstream_branch_url = upstream_branch_url self._upstream_branch = None self.config = config + self.dist_command = dist_command if upstream_revision_map is None: self.upstream_revision_map = {} else: @@ -541,9 +568,10 @@ class LocalUpstreamBranchSource(UpstreamBranchSource): """Upstream branch source in a local branch.""" - def __init__(self, local_branch): + def __init__(self, local_branch, dist_command=None): self.local_branch = local_branch self.upstream_revision_map = {} + self.dist_command = dist_command self.config = None @classmethod @@ -556,3 +584,60 @@ def __repr__(self): return "%s(%r)" % (self.__class__.__name__, self.local_branch) + + +class DistCommandFailed(BzrError): + + _fmt = "Dist command failed to produce a tarball: %(error)s" + + def __init__(self, error): + super(DistCommandFailed, self).__init__(error=error) + + +def run_dist_command(rev_tree, package, version, target_filename, + dist_command): + from ..repack_tarball import get_filetype + with tempfile.TemporaryDirectory() as td: + package_dir = os.path.join(td, package) + export(rev_tree, package_dir, 'dir') + existing_files = os.listdir(package_dir) + env = dict(os.environ.items()) + env['PACKAGE'] = package + env['VERSION'] = version + env['OUTPUT'] = target_filename + note('Running dist command: %s', dist_command) + try: + subprocess.check_call( + dist_command, env=env, cwd=package_dir, shell=True) + except subprocess.CalledProcessError as e: + if e.returncode == 2: + return False + raise DistCommandFailed(str(e)) + if os.path.exists(target_filename): + note('dist command created tarball.') + return True + new_files = os.listdir(package_dir) + diff_files = set(new_files) - set(existing_files) + diff = [n for n in diff_files if get_filetype(n) is not None] + if len(diff) == 1: + note('Found tarball %s in package directory.', diff[0]) + os.rename( + os.path.join(package_dir, diff[0]), + target_filename) + return True + if 'dist' in diff_files: + for entry in os.scandir(os.path.join(package_dir, 'dist')): + if get_filetype(entry.name) is not None: + note('Found tarball %s in dist directory.', entry.name) + os.rename(entry.path, target_filename) + return True + note('No tarballs found in dist directory.') + diff = set(os.listdir(td)) - set([package]) + if len(diff) == 1: + fn = diff.pop(0) + note('Found tarball %s in parent directory.', fn) + os.rename( + os.path.join(td, fn), + target_filename) + return True + raise DistCommandFailed('no tarball created') diff -Nru breezy-debian-2.8.32ubuntu1/upstream/__init__.py breezy-debian-2.8.35/upstream/__init__.py --- breezy-debian-2.8.32ubuntu1/upstream/__init__.py 2020-02-10 17:03:57.000000000 +0000 +++ breezy-debian-2.8.35/upstream/__init__.py 2020-05-08 01:12:30.000000000 +0000 @@ -18,7 +18,6 @@ # along with bzr-builddeb; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from __future__ import absolute_import import os import re import shutil @@ -27,12 +26,9 @@ import tarfile import tempfile -from debian.changelog import Version - -from ....errors import BzrError, NoSuchFile +from ....errors import BzrError, DependencyNotPresent, NoSuchFile from .... import osutils from ....export import export -from ....sixish import PY3 from ....trace import ( note, warning, @@ -128,7 +124,10 @@ def fetch_tarballs(self, package, upstream_version, target_dir, _apt_pkg=None, components=None): if _apt_pkg is None: - import apt_pkg + try: + import apt_pkg + except ImportError as e: + raise DependencyNotPresent('apt_pkg', e) else: apt_pkg = _apt_pkg apt_pkg.init() @@ -218,10 +217,7 @@ if error.startswith('uscan error '): error = error[len('uscan error '):] raise UScanError(error) - if PY3: - sys.stderr.write(stderr.decode()) - else: - sys.stderr.write(stderr) + sys.stderr.write(stderr.decode()) return stdout, p.returncode @staticmethod @@ -233,8 +229,14 @@ @staticmethod def _xml_report_extract_errors(text): from xml.sax.saxutils import unescape - for m in re.finditer(b"(.*)", text): - raise UScanError(unescape(m.group(1).decode())) + lines = [unescape(m.group(1).decode()) + for m in re.finditer(b"(.*)", text)] + for line in lines: + if not line.startswith('uscan warn: '): + raise UScanError(line) + + for line in lines: + raise UScanError(line) @staticmethod def _xml_report_extract_upstream_version(text): @@ -348,6 +350,9 @@ package, version, target_dir, components) except PackageVersionNotPresent: pass + except DependencyNotPresent as e: + warning('not checking %r due to missing dependency: %s', + source, e) else: return paths raise PackageVersionNotPresent(package, version, self) @@ -375,6 +380,9 @@ return source.version_as_revisions(package, version, tarballs) except PackageVersionNotPresent: pass + except DependencyNotPresent as e: + warning('not checking %r due to missing dependency: %s', + source, e) raise PackageVersionNotPresent(package, version, self) def has_version(self, package, version, tarballs=None): @@ -455,8 +463,9 @@ if in_target is not None: note("Upstream tarball already exists in build directory, " "using that") - return [(p, component_from_orig_tarball(p, - self.package, self.version)) for p in in_target] + return [ + (p, component_from_orig_tarball(p, self.package, self.version)) + for p in in_target] if self.already_exists_in_store() is None: if not os.path.exists(self.store_dir): os.makedirs(self.store_dir) @@ -485,8 +494,8 @@ if paths is None: return None for path in paths: - repack_tarball(path, os.path.basename(path), - target_dir=target_dir) + repack_tarball( + path, os.path.basename(path), target_dir=target_dir) return paths @@ -498,7 +507,7 @@ """ basename = os.path.basename(path) for extension in [".tar.gz", ".tgz", ".tar.bz2", ".tar.lzma", ".tar.xz", - ".zip"]: + ".zip"]: if basename.endswith(extension): basename = basename[:-len(extension)] break diff -Nru breezy-debian-2.8.32ubuntu1/upstream/pristinetar.py breezy-debian-2.8.35/upstream/pristinetar.py --- breezy-debian-2.8.32ubuntu1/upstream/pristinetar.py 2020-02-10 17:04:53.000000000 +0000 +++ breezy-debian-2.8.35/upstream/pristinetar.py 2020-05-08 01:12:30.000000000 +0000 @@ -19,7 +19,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from __future__ import absolute_import from base64 import ( standard_b64decode, standard_b64encode, @@ -28,18 +27,16 @@ from debian.copyright import globs_to_re import errno import os -import re -import shutil import subprocess import tempfile +from .... import debug from ..errors import ( PackageVersionNotPresent, ) from ..upstream import UpstreamSource from ....export import export from ..util import ( - debuild_config, subprocess_setup, ) @@ -55,15 +52,23 @@ NoSuchFile, NotBranchError, ) -from ....sixish import ( - viewitems, - ) from ....trace import ( mutter, note, warning, ) +from .tags import ( + GbpTagFormatError, + gbp_expand_tag_name, + mangle_version_for_git, + upstream_tag_name, + is_upstream_tag, + possible_upstream_tag_names, + search_for_upstream_version, + upstream_tag_version, + ) + class PristineTarError(BzrError): _fmt = 'There was an error using pristine-tar: %(error)s.' @@ -80,12 +85,8 @@ _fmt = 'There is not delta present for %(version)s.' -class GbpTagFormatError(BzrError): - _fmt = 'Unknown variable %(variable)s in tag %(tag_name)s.' - - def __init__(self, tag_name, variable): - self.variable = variable - self.tag_name = tag_name +class PristineTarDeltaExists(PristineTarError): + _fmt = 'An existing pristine tar entry exists for %(filename)s' def git_store_pristine_tar(branch, filename, tree_id, delta, force=False): @@ -103,8 +104,7 @@ # Nothing to do. return if not force: - raise PristineTarError( - "An existing pristine tar entry exists for %s" % filename) + raise PristineTarDeltaExists(filename) tree.put_file_bytes_non_atomic(id_filename, tree_id + b'\n') tree.put_file_bytes_non_atomic(delta_filename, delta) tree.add([id_filename, delta_filename], [None, None], ['file', 'file']) @@ -173,8 +173,7 @@ def make_pristine_tar_delta_from_tree( tree, tarball_path, subdir=None, exclude=None): - tmpdir = tempfile.mkdtemp(prefix="builddeb-pristine-") - try: + with tempfile.TemporaryDirectory(prefix="builddeb-pristine-") as tmpdir: dest = os.path.join(tmpdir, "orig") with tree.lock_read(): export(tree, dest, format='dir', subdir=subdir) @@ -183,8 +182,7 @@ except PristineTarDeltaTooLarge: raise except PristineTarError: # I.e. not PristineTarDeltaTooLarge - conf = debuild_config(tree) - if conf.debug_pristine_tar: + if 'pristine-tar' in debug.debug_flags: revno, revid = tree.branch.last_revision_info() preserved = osutils.pathjoin(osutils.dirname(tarball_path), 'orig-%s' % (revno,)) @@ -198,8 +196,6 @@ ' pristine-tar -vdk gendelta %s -' % (preserved, tarball_path)) raise - finally: - shutil.rmtree(tmpdir) def revision_has_pristine_tar_delta(rev): @@ -234,31 +230,6 @@ "Not handled new delta type in pristine_tar_format") -def gbp_expand_tag_name(tag_format, version): - # See gbp/pkg/pkgpolicy.py in gbp-buildpackage - version_mangle_re = ( - r'%\(version' - r'%(?P[^%])' - r'%(?P([^%]|\\%))+' - r'\)s') - - ret = tag_format - m = re.search(version_mangle_re, tag_format) - if m: - ret = re.sub(version_mangle_re, "%(version)s", tag_format) - version = version.replace( - m.group('M'), m.group('R').replace(r'\%', '%')) - - vars = { - 'version': version, - 'hversion': version.replace('.', '-'), - } - try: - return ret % vars - except KeyError as e: - raise GbpTagFormatError(tag_format, e.args[0]) - - class PristineTarSource(UpstreamSource): """Source that uses the pristine-tar revisions in the packaging branch.""" @@ -315,20 +286,8 @@ """ if self.gbp_tag_format is not None: return gbp_expand_tag_name(self.gbp_tag_format, version) - if getattr(self.branch.repository, '_git', None): - # In git, the convention is to use a slash - if distro is None: - name = "upstream/" + version.replace('~', '_') - else: - name = "upstream-%s/%s" % (distro, version.replace('~', '_')) - else: - if distro is None: - name = "upstream-" + version - else: - name = "upstream-%s-%s" % (distro, version) - if component is not None: - name += "/%s" % component - return name + git_style = bool(getattr(self.branch.repository, '_git', None)) + return upstream_tag_name(version, component, distro, git_style) def tag_version(self, version, revid, component=None): """Tags the upstream branch's last revision with an upstream version. @@ -354,7 +313,7 @@ component=None, md5=None, tarball=None, author=None, timestamp=None, subdir=None, exclude=None, force_pristine_tar=False, committer=None, - files_excluded=None): + files_excluded=None, reuse_existing=True): """Import a tarball. :param package: Package name @@ -365,6 +324,8 @@ :param force_pristine_tar: Whether to force creating a pristine-tar branch if one does not exist. :param committer: Committer identity to use + :param reuse_existing: Whether to reuse existing tarballs, or raise + an error """ if exclude is None: exclude = [] @@ -460,9 +421,15 @@ 'since there is no pristine-tar branch.') pristine_tar_branch = None if pristine_tar_branch: - git_store_pristine_tar( - pristine_tar_branch, os.path.basename(tarball), tree_id, - git_delta) + try: + git_store_pristine_tar( + pristine_tar_branch, os.path.basename(tarball), + tree_id, git_delta) + except PristineTarDeltaExists: + if reuse_existing: + note('Reusing existing tarball, since delta exists.') + return tag_name, revid + raise mutter( 'imported %s version %s component %r as revid %s, tagged %s', package, version, component, revid, tag_name) @@ -532,19 +499,28 @@ def version_component_as_revision(self, package, version, component, md5=None): - for tag_name in self.possible_tag_names(version, component=component): + with self.branch.lock_read(): + for tag_name in self.possible_tag_names(package, version, component=component): + try: + revid = self.branch.tags.lookup_tag(tag_name) + except NoSuchTag: + continue + else: + if self._has_revision(revid, md5=md5): + return revid + revid = search_for_upstream_version( + self.branch, package, version, component, md5) + tag_name = self.tag_name(version, component=component) + if revid is not None: + warning( + "Upstream import of %s lacks a tag. Set one by running: " + "brz tag -rrevid:%s %s", version, revid.decode('utf-8'), + tag_name) + return revid try: - revid = self.branch.tags.lookup_tag(tag_name) + return self.branch.tags.lookup_tag(tag_name) except NoSuchTag: - continue - else: - if self._has_revision(revid, md5=md5): - return revid - tag_name = self.tag_name(version, component=component) - try: - return self.branch.tags.lookup_tag(tag_name) - except NoSuchTag: - raise PackageVersionNotPresent(package, version, self) + raise PackageVersionNotPresent(package, version, self) def has_version(self, package, version, tarballs=None): if tarballs is None: @@ -557,7 +533,7 @@ return True def has_version_component(self, package, version, component, md5=None): - for tag_name in self.possible_tag_names(version, component=component): + for tag_name in self.possible_tag_names(package, version, component=component): try: revid = self.branch.tags.lookup_tag(tag_name) except NoSuchTag: @@ -567,19 +543,13 @@ return True return False - def possible_tag_names(self, version, component): - tags = [self.tag_name(version, component=component), - self.tag_name(version, component=component, distro="debian"), - self.tag_name(version, component=component, distro="ubuntu"), - ] - if component is None: - # compatibility with git-buildpackage - tags.append("upstream/%s" % version) - tags.append("upstream-%s" % version) - if "~" in version: - tags.append("upstream/%s" % version.replace("~", "_")) - # compatibility with svn-buildpackage - tags.append("upstream_%s" % version) + def possible_tag_names(self, package, version, component): + tags = [] + if self.gbp_tag_format: + tags.append(gbp_expand_tag_name(self.gbp_tag_format, version)) + + tags.extend(possible_upstream_tag_names(package, version, component)) + return tags def get_pristine_tar_delta(self, package, version, dest_filename, @@ -605,8 +575,7 @@ def reconstruct_pristine_tar(self, revid, package, version, dest_filename): """Reconstruct a pristine-tar tarball from a bzr revision.""" tree = self.branch.repository.revision_tree(revid) - tmpdir = tempfile.mkdtemp(prefix="builddeb-pristine-") - try: + with tempfile.TemporaryDirectory(prefix="bd-pristine-") as tmpdir: dest = os.path.join(tmpdir, "orig") try: delta = self.get_pristine_tar_delta( @@ -615,12 +584,10 @@ reconstruct_pristine_tar(dest, delta, dest_filename) except PristineTarDeltaAbsent: export(tree, dest_filename, per_file_timestamps=True) - finally: - shutil.rmtree(tmpdir) def _components_by_version(self): ret = {} - for tag_name, tag_revid in viewitems(self.branch.tags.get_tag_dict()): + for tag_name, tag_revid in self.branch.tags.get_tag_dict().items(): if not is_upstream_tag(tag_name): continue (component, version) = upstream_tag_version(tag_name) @@ -633,40 +600,7 @@ :return: Iterator over (tag_name, version, revid) tuples """ ret = self._components_by_version() - return viewitems(ret) - + return ret.items() -def is_upstream_tag(tag): - """Return true if tag is an upstream tag. - - :param tag: The string name of the tag. - :return: True if the tag name is one generated by upstream tag operations. - """ - return (tag.startswith('upstream-') or tag.startswith('upstream/') or - tag.startswith('upstream_')) -def upstream_tag_version(tag): - """Return the upstream version portion of an upstream tag name. - - :param tag: The string name of the tag. - :return: tuple with version portion of the tag and component name - """ - assert is_upstream_tag(tag), "Not an upstream tag: %s" % tag - if tag.startswith('upstream/'): - tag = tag[len('upstream/'):] - elif tag.startswith('upstream_'): - tag = tag[len('upstream_'):] - elif tag.startswith('upstream-'): - tag = tag[len('upstream-'):] - if tag.startswith('debian-'): - tag = tag[len('debian-'):] - elif tag.startswith('ubuntu-'): - tag = tag[len('ubuntu-'):] - tag = tag.replace('_', '~') - if '/' not in tag: - return (None, tag) - (version, component) = tag.rsplit('/', 1) - if component == "": - component = None - return (component, version) diff -Nru breezy-debian-2.8.32ubuntu1/upstream/tags.py breezy-debian-2.8.35/upstream/tags.py --- breezy-debian-2.8.32ubuntu1/upstream/tags.py 1970-01-01 00:00:00.000000000 +0000 +++ breezy-debian-2.8.35/upstream/tags.py 2020-05-08 01:12:30.000000000 +0000 @@ -0,0 +1,224 @@ +# tags.py -- Providers of upstream source - tag names +# Copyright (C) 2016-2020 Jelmer Vernooij +# +# This file is part of bzr-builddeb. +# +# bzr-builddeb is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# bzr-builddeb is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with bzr-builddeb; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from itertools import islice +import re + +from ....errors import ( + BzrError, + NotBranchError, + ) +from ....trace import note + + +class GbpTagFormatError(BzrError): + _fmt = 'Unknown variable %(variable)s in tag %(tag_name)s.' + + def __init__(self, tag_name, variable): + self.variable = variable + self.tag_name = tag_name + + +def gbp_expand_tag_name(tag_format, version): + # See gbp/pkg/pkgpolicy.py in gbp-buildpackage + version_mangle_re = ( + r'%\(version' + r'%(?P[^%])' + r'%(?P([^%]|\\%))+' + r'\)s') + + ret = tag_format + m = re.search(version_mangle_re, tag_format) + if m: + ret = re.sub(version_mangle_re, "%(version)s", tag_format) + version = version.replace( + m.group('M'), m.group('R').replace(r'\%', '%')) + + vars = { + 'version': version, + 'hversion': version.replace('.', '-'), + } + try: + return ret % vars + except KeyError as e: + raise GbpTagFormatError(tag_format, e.args[0]) + + +def upstream_tag_name(version, component=None, distro=None, git_style=False): + if git_style: + # In git, the convention is to use a slash + if distro is None: + name = "upstream/" + mangle_version_for_git(version) + else: + name = "upstream-%s/%s" % (distro, version.replace('~', '_')) + else: + if distro is None: + name = "upstream-" + version + else: + name = "upstream-%s-%s" % (distro, version) + if component is not None: + name += "/%s" % component + return name + + +def mangle_version_for_git(version): + # See https://dep-team.pages.debian.net/deps/dep14/ + manipulated = ( + version.replace("~", "_").replace(':', '%').replace('..', '.#.')) + if manipulated.endswith('.'): + manipulated += '#' + if manipulated.endswith('.lock'): + manipulated = manipulated[:-4] + '#lock' + return manipulated + + +def possible_upstream_tag_names(package, version, component=None): + tags = [] + if component is None: + # compatibility with git-buildpackage + tags.append("upstream/%s" % version) + tags.append("upstream-%s" % version) + manipulated = 'upstream/%s' % mangle_version_for_git(version) + if manipulated not in tags: + tags.append(manipulated) + # compatibility with svn-buildpackage + tags.append("upstream_%s" % version) + + # common upstream names + tags.append("%s" % version) + tags.append("v%s" % version) + if '~' not in str(version) and '+' not in str(version): + tags.append("release-%s" % version) + tags.append("v%s-release" % version) + tags.append("%s-%s" % (package, version)) + else: + tags.append(upstream_tag_name(version, component)) + return tags + + +def is_upstream_tag(tag): + """Return true if tag is an upstream tag. + + :param tag: The string name of the tag. + :return: True if the tag name is one generated by upstream tag operations. + """ + return (tag.startswith('upstream-') or tag.startswith('upstream/') or + tag.startswith('upstream_')) + + +def upstream_tag_version(tag): + """Return the upstream version portion of an upstream tag name. + + :param tag: The string name of the tag. + :return: tuple with version portion of the tag and component name + """ + assert is_upstream_tag(tag), "Not an upstream tag: %s" % tag + if tag.startswith('upstream/'): + tag = tag[len('upstream/'):] + elif tag.startswith('upstream_'): + tag = tag[len('upstream_'):] + elif tag.startswith('upstream-'): + tag = tag[len('upstream-'):] + if tag.startswith('debian-'): + tag = tag[len('debian-'):] + elif tag.startswith('ubuntu-'): + tag = tag[len('ubuntu-'):] + tag = tag.replace('_', '~') + if '/' not in tag: + return (None, tag) + (version, component) = tag.rsplit('/', 1) + if component == "": + component = None + return (component, version) + + +def _rev_is_upstream_import(revision, package, version): + possible_messages = [ + 'Import %s_%s' % (package, version), + 'import %s_%s' % (package, version), + 'import %s-%s' % (package.replace('-', '_'), version), + 'Imported upstream version %s' % version, + 'Import upstream version %s' % version, + 'New upstream version %s' % version, + 'New upstream version v%s' % version, + '%s-%s' % (package, version), + ] + for possible_message in possible_messages: + if revision.message.lower().startswith(possible_message.lower()): + return True + return False + + +def _rev_is_upstream_merge(revision, package, version): + if revision.message.lower().startswith( + ("Merge tag 'v%s' into debian/" % version).lower()): + return True + if revision.message.lower().startswith( + ("Merge tag '%s-%s' into " % (package, version)).lower()): + return True + return False + + +def search_for_upstream_version( + branch, package, version, component=None, md5=None, scan_depth=None): + """Find possible upstream revisions that don't have appropriate tags.""" + start_revids = [] + sources = [] + try: + upstream_branch = branch.controldir.open_branch('upstream') + except NotBranchError: + pass + else: + sources.append('branch upstream') + start_revids.append(upstream_branch.last_revision()) + sources.append('main branch') + start_revids.append(branch.last_revision()) + candidate_tag_start = [ + 'debian/%s-' % mangle_version_for_git(version), + 'debian-%s' % version, + 'debian-%s-%s' % (package, version), + # Epochs are sometimes replaced by underscores, rather than by %, + # as DEP-14 suggests. + 'debian/%s-' % mangle_version_for_git(version.replace(':', '_')), + ] + for tag_name, revid in branch.tags.get_tag_dict().items(): + if any([tag_name.startswith(tag_start) + for tag_start in candidate_tag_start]): + sources.append('tag %s' % tag_name) + start_revids.append(revid) + note('Searching for revision importing %s version %s on %s.', + package, version, ', '.join(sources)) + todo = [] + graph = branch.repository.get_graph() + for revid, parents in islice( + graph.iter_ancestry(start_revids), scan_depth): + todo.append(revid) + for revid, rev in branch.repository.iter_revisions(todo): + if rev is None: + continue + if _rev_is_upstream_import(rev, package, version): + return revid + + # Try again, but this time search for merge revisions + for revid, rev in branch.repository.iter_revisions(todo): + if rev is None: + continue + if _rev_is_upstream_merge(rev, package, version): + return rev.parent_ids[1] + return None diff -Nru breezy-debian-2.8.32ubuntu1/util.py breezy-debian-2.8.35/util.py --- breezy-debian-2.8.32ubuntu1/util.py 2019-11-24 02:57:14.000000000 +0000 +++ breezy-debian-2.8.35/util.py 2020-05-08 01:12:30.000000000 +0000 @@ -34,7 +34,7 @@ from debian import deb822 from debian.changelog import Changelog, ChangelogParseError -from debian.copyright import Copyright +from debian.copyright import Copyright, NotMachineReadableError from ... import ( bugtracker, @@ -42,7 +42,6 @@ osutils, urlutils, ) -from ...sixish import text_type from ...trace import ( mutter, warning, @@ -52,11 +51,7 @@ get_transport, ) from . import ( - default_conf, - local_conf, global_conf, - new_conf, - new_local_conf, ) from .config import ( DebBuildConfig, @@ -69,11 +64,17 @@ AddChangelogError, InconsistentSourceFormatError, NoPreviousUpload, - TarFailed, UnableToFindPreviousUpload, UnparseableChangelog, ) +BUILDDEB_DIR = '.bzr-builddeb' + +NEW_LOCAL_CONF = 'debian/local.conf.local' +NEW_CONF = 'debian/bzr-builddeb.conf' +DEFAULT_CONF = os.path.join(BUILDDEB_DIR, 'default.conf') +LOCAL_CONF = os.path.join(BUILDDEB_DIR, 'local.conf') + class MissingChangelogError(BzrError): _fmt = 'Could not find changelog at %(location)s in tree.' @@ -122,7 +123,7 @@ def safe_decode(s): """Decode a string into a Unicode value.""" - if isinstance(s, text_type): # Already unicode + if isinstance(s, str): # Already unicode mutter('safe_decode() called on an already-decoded string: %r' % (s,)) return s try: @@ -153,7 +154,12 @@ os.mkdir(tosubdir) recursive_copy(path, tosubdir) else: - shutil.copy(path, todir) + # Python 3 has a follow_symlinks argument to shutil.copy, but + # Python 2 does not... + if os.path.islink(path): + os.symlink(os.readlink(path), os.path.join(todir, entry)) + else: + shutil.copy(path, todir) def find_changelog(t, subpath='', merge=False, max_blocks=1): @@ -422,7 +428,8 @@ if not os.path.isdir(target_dir): raise errors.NotADirectory(target_dir) path, dsc_t = open_transport(dsc_location) - dsc_contents = open_file_via_transport(path, dsc_t).read() + with open_file_via_transport(path, dsc_t) as f: + dsc_contents = f.read() dsc = cls(dsc_contents) for file_details in dsc['files']: name = file_details['name'] @@ -587,6 +594,13 @@ """ config_files = [] user_config = None + if subpath in ('.', None): + subpath = '' + new_local_conf = osutils.pathjoin(subpath, NEW_LOCAL_CONF) + local_conf = osutils.pathjoin(subpath, LOCAL_CONF) + new_conf = osutils.pathjoin(subpath, NEW_CONF) + default_conf = osutils.pathjoin(subpath, DEFAULT_CONF) + if tree.has_filename(new_local_conf): if not tree.is_versioned(new_local_conf): config_files.append( @@ -771,6 +785,22 @@ tarball_filename) +class TarFailed(BzrError): + _fmt = ("There was an error executing tar to %(operation)s %(tarball)s: " + "%(error)s.") + + def __init__(self, operation, tarball, error): + BzrError.__init__( + self, operation=operation, tarball=tarball, error=error) + + +def needs_strip_components(tf): + top_level_directories = set() + for name in tf.getnames(): + top_level_directories.add(name.split('/')[0]) + return len(top_level_directories) == 1 + + def extract_orig_tarball(tarball_filename, component, target, strip_components=None): """Extract an orig tarball. @@ -778,16 +808,30 @@ :param tarball: Path to the tarball :param component: Component name (or None for top-level) :param target: Target path - :param strip_components: Optional number of components to strip """ + from tarfile import TarFile tar_args = ["tar"] if tarball_filename.endswith(".tar.bz2"): tar_args.append('xjf') + tf = TarFile.bz2open(tarball_filename) elif (tarball_filename.endswith(".tar.lzma") or tarball_filename.endswith(".tar.xz")): tar_args.append('xJf') + tf = TarFile.xzopen(tarball_filename) + elif tarball_filename.endswith(".tar"): + tar_args.append('xf') + tf = TarFile.open(tarball_filename) else: + tf = TarFile.gzopen(tarball_filename) tar_args.append('xzf') + try: + if strip_components is None: + if needs_strip_components(tf): + strip_components = 1 + else: + strip_components = 0 + finally: + tf.close() if component is not None: target_path = os.path.join(target, component) os.mkdir(target_path) @@ -795,11 +839,12 @@ target_path = target tar_args.extend([tarball_filename, "-C", target_path]) if strip_components is not None: - tar_args.extend(["--strip-components", "1"]) - proc = subprocess.Popen(tar_args, preexec_fn=subprocess_setup) - proc.communicate() + tar_args.extend(["--strip-components", str(strip_components)]) + proc = subprocess.Popen(tar_args, preexec_fn=subprocess_setup, + stderr=subprocess.PIPE) + (stdout, stderr) = proc.communicate() if proc.returncode != 0: - raise TarFailed("extract", tarball_filename) + raise TarFailed("extract", tarball_filename, error=stderr) def extract_orig_tarballs(tarballs, target, strip_components=None): @@ -810,8 +855,7 @@ """ for tarball_filename, component in tarballs: extract_orig_tarball( - tarball_filename, component, target, - strip_components=strip_components) + tarball_filename, component, target, strip_components=strip_components) def dput_changes(path): @@ -851,7 +895,10 @@ else: path = os.path.join(subpath, 'debian', 'copyright') with tree.get_file(path) as f: - copyright = Copyright(f) + try: + copyright = Copyright(f, strict=False) + except NotMachineReadableError: + return [] try: return copyright.header["Files-Excluded"].split() except KeyError: