From 7c097b19bad1efff794982ed20cf488e33dc46af Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 6 Nov 2019 17:07:42 -0500 Subject: [PATCH] ubuntutools: add --status param to pull-pkg Allow specifying what package statuses should be searched for. By default search only for Pending and Published, unless a specific version number is being searched for. --- ubuntutools/archive.py | 4 ++++ ubuntutools/lp/lpapicache.py | 41 ++++++++++++++++++++++++++++++++---- ubuntutools/misc.py | 3 +++ ubuntutools/pullpkg.py | 13 ++++++++++-- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/ubuntutools/archive.py b/ubuntutools/archive.py index 9e857e6..375f308 100644 --- a/ubuntutools/archive.py +++ b/ubuntutools/archive.py @@ -142,6 +142,7 @@ class SourcePackage(object): quiet = kwargs.get('quiet', False) series = kwargs.get('series') pocket = kwargs.get('pocket') + status = kwargs.get('status') verify_signature = kwargs.get('verify_signature', False) assert (package is not None or dscfile is not None) @@ -154,6 +155,7 @@ class SourcePackage(object): self.quiet = quiet self._series = series self._pocket = pocket + self._status = status self._dsc_source = dscfile self._verify_signature = verify_signature @@ -201,6 +203,8 @@ class SourcePackage(object): # We always want to search all series, if not specified params['search_all_series'] = True + params['status'] = self._status + try: self._spph = archive.getSourcePackage(self.source, wrapper=self.spph_class, diff --git a/ubuntutools/lp/lpapicache.py b/ubuntutools/lp/lpapicache.py index 5063c7e..a821ebc 100644 --- a/ubuntutools/lp/lpapicache.py +++ b/ubuntutools/lp/lpapicache.py @@ -38,7 +38,8 @@ from lazr.restfulclient.resource import Entry from ubuntutools.version import Version from ubuntutools.lp import (service, api_version) from ubuntutools.misc import (host_architecture, - DEFAULT_POCKETS, POCKETS) + DEFAULT_POCKETS, POCKETS, + DEFAULT_STATUSES, STATUSES) from ubuntutools.lp.udtexceptions import (AlreadyLoggedInError, ArchiveNotFoundException, ArchSeriesNotFoundException, @@ -373,6 +374,11 @@ class Archive(BaseWrapper): specific version, it defaults to all pockets. Pocket strings must be capitalized. + status may be a string or a list. If no version is provided, it + defaults to only 'Pending' and 'Published'; if searching for a + specific version, it defaults to all statuses. Status strings must + be capitalized. + wrapper is the class to return an instance of; defaults to SourcePackagePublishingHistory. @@ -380,7 +386,6 @@ class Archive(BaseWrapper): search only the latest devel series, and if True all series will be searched, in reverse order, starting with the latest devel series. Defaults to False. - status is optional, to restrict search to a given status only. If the requested source package doesn't exist a PackageNotFoundException is raised. @@ -413,6 +418,11 @@ class Archive(BaseWrapper): specific version, it defaults to all pockets. Pocket strings must be capitalized. + status may be a string or a list. If no version is provided, it + defaults to only 'Pending' and 'Published'; if searching for a + specific version, it defaults to all statuses. Status strings must + be capitalized. + wrapper is the class to return an instance of; defaults to BinaryPackagePublishingHistory. @@ -420,7 +430,6 @@ class Archive(BaseWrapper): search only the latest devel series, and if True all series will be searched, in reverse order, starting with the latest devel series. Defaults to False. - status is optional, to restrict search to a given status only. If the requested binary package doesn't exist a PackageNotFoundException is raised. @@ -460,6 +469,21 @@ class Archive(BaseWrapper): if p not in POCKETS: raise PocketDoesNotExistError("Pocket '%s' does not exist." % p) + if not status: + if version: + # check ALL statuses if specific version + statuses = STATUSES + else: + # otherwise, only check 'Pending' and 'Published' + statuses = DEFAULT_STATUSES + elif isinstance(status, str): + statuses = (status,) + else: + statuses = tuple(status) + + for s in statuses: + if s not in STATUSES: + raise ValueError("Status '%s' is not valid." % s) dist = Distribution(self.distribution_link) @@ -499,7 +523,7 @@ class Archive(BaseWrapper): if archtag is None: archtag = host_architecture() - index = (name, getattr(series, 'name', None), archtag, pockets, status, version) + index = (name, getattr(series, 'name', None), archtag, pockets, statuses, version) if index in cache: return cache[index] @@ -517,6 +541,8 @@ class Archive(BaseWrapper): if len(pockets) == 1: params['pocket'] = pockets[0] + if len(statuses) == 1: + params['status'] = statuses[0] if version: params['version'] = version @@ -540,6 +566,9 @@ class Archive(BaseWrapper): err_msg = 'pocket %s not in (%s)' % (record.pocket, ','.join(pockets)) Logger.debug(skipmsg + err_msg) continue + if record.status not in statuses: + err_msg = 'status %s not in (%s)' % (record.status, ','.join(statuses)) + Logger.debug(skipmsg + err_msg) continue r = wrapper(record) if binary and archtag and archtag != r.arch: @@ -587,6 +616,10 @@ class Archive(BaseWrapper): msg += "-%s" % pockets[0] elif len(pockets) != len(POCKETS): msg += " for pockets " + ', '.join(pockets) + if len(statuses) == 1: + msg += " with status %s" % statuses[0] + elif len(statuses) != len(STATUSES): + msg += " with status in " + ', '.join(statuses) if version_with_epoch: msg += " (did you forget the epoch? try %s)" % version_with_epoch raise PackageNotFoundException(msg) diff --git a/ubuntutools/misc.py b/ubuntutools/misc.py index e322422..1a285fd 100644 --- a/ubuntutools/misc.py +++ b/ubuntutools/misc.py @@ -35,6 +35,9 @@ from ubuntutools.lp.udtexceptions import PocketDoesNotExistError DEFAULT_POCKETS = ('Release', 'Security', 'Updates', 'Proposed') POCKETS = DEFAULT_POCKETS + ('Backports',) +DEFAULT_STATUSES = ('Pending', 'Published') +STATUSES = DEFAULT_STATUSES + ('Superseded', 'Deleted', 'Obsolete') + _system_distribution_chain = [] diff --git a/ubuntutools/pullpkg.py b/ubuntutools/pullpkg.py index e7064a5..11f1bd8 100644 --- a/ubuntutools/pullpkg.py +++ b/ubuntutools/pullpkg.py @@ -40,7 +40,7 @@ from ubuntutools.lp.udtexceptions import (SeriesNotFoundException, PocketDoesNotExistError, InvalidDistroValueError) from ubuntutools.logger import Logger -from ubuntutools.misc import (split_release_pocket, host_architecture) +from ubuntutools.misc import (split_release_pocket, host_architecture, STATUSES) PULL_SOURCE = 'source' PULL_DEBS = 'debs' @@ -114,7 +114,11 @@ class PullPkg(object): help_default_arch = ("Get binary packages for arch") help_default_arch += ("(default: %s)" % self._default_arch) - parser = ArgumentParser() + epilog = ("Note on --status: if a version is provided, all status types " + "will be searched; if no version is provided, by default only " + "'Pending' and 'Published' status will be searched.") + + parser = ArgumentParser(epilog=epilog) parser.add_argument('-v', '--verbose', action='store_true', help="Print verbose/debug messages") parser.add_argument('-d', '--download-only', action='store_true', @@ -125,6 +129,8 @@ class PullPkg(object): help="Don't read config files or environment variables") parser.add_argument('--no-verify-signature', action='store_true', help="Don't fail if dsc signature can't be verified") + parser.add_argument('-s', '--status', action='append', default=[], + help="Search for packages with specific status(es)") parser.add_argument('-a', '--arch', default=self._default_arch, help=help_default_arch) parser.add_argument('-p', '--pull', default=self._default_pull, @@ -265,6 +271,7 @@ class PullPkg(object): assert 'download_only' in options assert 'no_conf' in options assert 'no_verify_signature' in options + assert 'status' in options # type string assert 'pull' in options assert 'distro' in options @@ -316,6 +323,8 @@ class PullPkg(object): params['verify_signature'] = not options['no_verify_signature'] + params['status'] = STATUSES if 'all' in options['status'] else options['status'] + return (pull, distro, params) def pull(self, args=None):