mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-03-25 01:41:08 +00:00
pull-pkg: change pullpkg into class PullPkg
instead of pullpkg.py containing a simple method to call, change it into a normal class PullPkg that callers can create and use.
This commit is contained in:
parent
fb750e38bb
commit
3491b0cff9
@ -128,8 +128,7 @@ class SourcePackage(object):
|
|||||||
spph_class = SourcePackagePublishingHistory
|
spph_class = SourcePackagePublishingHistory
|
||||||
|
|
||||||
def __init__(self, package=None, version=None, component=None,
|
def __init__(self, package=None, version=None, component=None,
|
||||||
dscfile=None, lp=None, mirrors=(), workdir='.', quiet=False,
|
*args, **kwargs):
|
||||||
series=None, pocket=None, verify_signature=False):
|
|
||||||
"""Can be initialised using either package or dscfile.
|
"""Can be initialised using either package or dscfile.
|
||||||
If package is specified, either the version or series can also be
|
If package is specified, either the version or series can also be
|
||||||
specified; using version will get the specific package version,
|
specified; using version will get the specific package version,
|
||||||
@ -137,6 +136,15 @@ class SourcePackage(object):
|
|||||||
Specifying only the package with no version or series will get the
|
Specifying only the package with no version or series will get the
|
||||||
latest version from the development series.
|
latest version from the development series.
|
||||||
"""
|
"""
|
||||||
|
dscfile = kwargs.get('dscfile')
|
||||||
|
lp = kwargs.get('lp')
|
||||||
|
mirrors = kwargs.get('mirrors', ())
|
||||||
|
workdir = kwargs.get('workdir', '.')
|
||||||
|
quiet = kwargs.get('quiet', False)
|
||||||
|
series = kwargs.get('series')
|
||||||
|
pocket = kwargs.get('pocket')
|
||||||
|
verify_signature = kwargs.get('verify_signature', False)
|
||||||
|
|
||||||
assert (package is not None or dscfile is not None)
|
assert (package is not None or dscfile is not None)
|
||||||
|
|
||||||
self.source = package
|
self.source = package
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import errno
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
from distro_info import DebianDistroInfo
|
from distro_info import DebianDistroInfo
|
||||||
@ -63,16 +65,49 @@ class InvalidPullValueError(ValueError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_argparser(default_pull=None, default_distro=None, default_arch=None):
|
class PullPkg(object):
|
||||||
|
"""Class used to pull file(s) associated with a specific package"""
|
||||||
|
@classmethod
|
||||||
|
def main(cls, *args, **kwargs):
|
||||||
|
"""For use by stand-alone cmdline scripts.
|
||||||
|
|
||||||
|
This will handle catching certain exceptions or kbd interrupts,
|
||||||
|
and printing out (via Logger) the error message, instead of
|
||||||
|
allowing the exception to flow up to the script. This does
|
||||||
|
not catch unexpected exceptions, such as internal errors.
|
||||||
|
On (expected) error, this will call sys.exit(error);
|
||||||
|
unexpected errors will flow up to the caller.
|
||||||
|
On success, this simply returns.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cls(*args, **kwargs).pull()
|
||||||
|
return
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
Logger.normal('User abort.')
|
||||||
|
except (PackageNotFoundException, SeriesNotFoundException,
|
||||||
|
PocketDoesNotExistError, InvalidDistroValueError) as e:
|
||||||
|
Logger.error(str(e))
|
||||||
|
sys.exit(errno.ENOENT)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self._default_pull = kwargs.get('pull')
|
||||||
|
self._default_distro = kwargs.get('distro')
|
||||||
|
self._default_arch = kwargs.get('arch', host_architecture())
|
||||||
|
self._parser = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def argparser(self):
|
||||||
|
if self._parser:
|
||||||
|
return self._parser
|
||||||
|
|
||||||
help_default_pull = "What to pull: " + ", ".join(VALID_PULLS)
|
help_default_pull = "What to pull: " + ", ".join(VALID_PULLS)
|
||||||
if default_pull:
|
if self._default_pull:
|
||||||
help_default_pull += (" (default: %s)" % default_pull)
|
help_default_pull += (" (default: %s)" % self._default_pull)
|
||||||
help_default_distro = "Pull from: " + ", ".join(VALID_DISTROS)
|
help_default_distro = "Pull from: " + ", ".join(VALID_DISTROS)
|
||||||
if default_distro:
|
if self._default_distro:
|
||||||
help_default_distro += (" (default: %s)" % default_distro)
|
help_default_distro += (" (default: %s)" % self._default_distro)
|
||||||
if not default_arch:
|
help_default_arch = ("Get binary packages for arch")
|
||||||
default_arch = host_architecture()
|
help_default_arch += ("(default: %s)" % self._default_arch)
|
||||||
help_default_arch = ("Get binary packages for arch (default: %s)" % default_arch)
|
|
||||||
|
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument('-v', '--verbose', action='store_true',
|
parser.add_argument('-v', '--verbose', action='store_true',
|
||||||
@ -85,19 +120,19 @@ def create_argparser(default_pull=None, default_distro=None, default_arch=None):
|
|||||||
help="Don't read config files or environment variables")
|
help="Don't read config files or environment variables")
|
||||||
parser.add_argument('--no-verify-signature', action='store_true',
|
parser.add_argument('--no-verify-signature', action='store_true',
|
||||||
help="Don't fail if dsc signature can't be verified")
|
help="Don't fail if dsc signature can't be verified")
|
||||||
parser.add_argument('-a', '--arch', default=default_arch,
|
parser.add_argument('-a', '--arch', default=self._default_arch,
|
||||||
help=help_default_arch)
|
help=help_default_arch)
|
||||||
parser.add_argument('-p', '--pull', default=default_pull,
|
parser.add_argument('-p', '--pull', default=self._default_pull,
|
||||||
help=help_default_pull)
|
help=help_default_pull)
|
||||||
parser.add_argument('-D', '--distro', default=default_distro,
|
parser.add_argument('-D', '--distro', default=self._default_distro,
|
||||||
help=help_default_distro)
|
help=help_default_distro)
|
||||||
parser.add_argument('package', help="Package name to pull")
|
parser.add_argument('package', help="Package name to pull")
|
||||||
parser.add_argument('release', nargs='?', help="Release to pull from")
|
parser.add_argument('release', nargs='?', help="Release to pull from")
|
||||||
parser.add_argument('version', nargs='?', help="Package version to pull")
|
parser.add_argument('version', nargs='?', help="Package version to pull")
|
||||||
return parser
|
self._parser = parser
|
||||||
|
return self._parser
|
||||||
|
|
||||||
|
def parse_pull(self, pull):
|
||||||
def parse_pull(pull):
|
|
||||||
if not pull:
|
if not pull:
|
||||||
raise InvalidPullValueError("Must specify --pull")
|
raise InvalidPullValueError("Must specify --pull")
|
||||||
|
|
||||||
@ -115,8 +150,7 @@ def parse_pull(pull):
|
|||||||
|
|
||||||
return pull
|
return pull
|
||||||
|
|
||||||
|
def parse_distro(self, distro):
|
||||||
def parse_distro(distro):
|
|
||||||
if not distro:
|
if not distro:
|
||||||
raise InvalidDistroValueError("Must specify --distro")
|
raise InvalidDistroValueError("Must specify --distro")
|
||||||
|
|
||||||
@ -136,8 +170,7 @@ def parse_distro(distro):
|
|||||||
|
|
||||||
return distro
|
return distro
|
||||||
|
|
||||||
|
def parse_release(self, distro, release):
|
||||||
def parse_release(release, distro):
|
|
||||||
if distro == DISTRO_UCA:
|
if distro == DISTRO_UCA:
|
||||||
# UCA is special; it is specified UBUNTURELEASE-UCARELEASE or just
|
# UCA is special; it is specified UBUNTURELEASE-UCARELEASE or just
|
||||||
# UCARELEASE. The user could also specify UCARELEASE-POCKET. But UCA
|
# UCARELEASE. The user could also specify UCARELEASE-POCKET. But UCA
|
||||||
@ -170,79 +203,92 @@ def parse_release(release, distro):
|
|||||||
distro, release, pocket)
|
distro, release, pocket)
|
||||||
return (release, pocket)
|
return (release, pocket)
|
||||||
|
|
||||||
|
def parse_release_and_version(self, distro, release, version, try_swap=True):
|
||||||
|
# Verify specified release is valid, and params in correct order
|
||||||
|
pocket = None
|
||||||
|
try:
|
||||||
|
(release, pocket) = self.parse_release(distro, release)
|
||||||
|
except (SeriesNotFoundException, PocketDoesNotExistError):
|
||||||
|
if try_swap:
|
||||||
|
Logger.debug("Param '%s' not valid series, must be version", release)
|
||||||
|
release, version = version, release
|
||||||
|
if release:
|
||||||
|
return self.parse_release_and_version(distro, release, version, False)
|
||||||
|
else:
|
||||||
|
Logger.error("Can't find series for '%s' or '%s'", release, version)
|
||||||
|
raise
|
||||||
|
return (release, version, pocket)
|
||||||
|
|
||||||
def pull(options):
|
def parse_options(self, options):
|
||||||
# required options asserted below
|
# if any of these fail, there is a problem with the parser
|
||||||
# 'release' and 'version' are optional strings
|
# they should all be provided, though the optional ones may be None
|
||||||
# 'mirror' is optional list of strings
|
|
||||||
# these are type bool
|
|
||||||
assert hasattr(options, 'verbose')
|
|
||||||
assert hasattr(options, 'download_only')
|
|
||||||
assert hasattr(options, 'no_conf')
|
|
||||||
assert hasattr(options, 'no_verify_signature')
|
|
||||||
# these are type string
|
|
||||||
assert hasattr(options, 'arch')
|
|
||||||
assert hasattr(options, 'pull')
|
|
||||||
assert hasattr(options, 'distro')
|
|
||||||
assert hasattr(options, 'package')
|
|
||||||
|
|
||||||
Logger.set_verbosity(options.verbose)
|
# type bool
|
||||||
|
assert 'download_only' in options
|
||||||
|
assert 'no_conf' in options
|
||||||
|
assert 'no_verify_signature' in options
|
||||||
|
# type string
|
||||||
|
assert 'pull' in options
|
||||||
|
assert 'distro' in options
|
||||||
|
assert 'arch' in options
|
||||||
|
assert 'package' in options
|
||||||
|
# type string, optional
|
||||||
|
assert 'release' in options
|
||||||
|
assert 'version' in options
|
||||||
|
# type list of strings, optional
|
||||||
|
assert 'mirror' in options
|
||||||
|
|
||||||
|
pull = self.parse_pull(options['pull'])
|
||||||
|
distro = self.parse_distro(options['distro'])
|
||||||
|
|
||||||
|
params = {}
|
||||||
|
params['package'] = options['package']
|
||||||
|
|
||||||
|
if options['release']:
|
||||||
|
(r, v, p) = self.parse_release_and_version(distro, options['release'],
|
||||||
|
options['version'])
|
||||||
|
params['series'] = r
|
||||||
|
params['version'] = v
|
||||||
|
params['pocket'] = p
|
||||||
|
|
||||||
|
if (params['package'].endswith('.dsc') and not params['series'] and not params['version']):
|
||||||
|
params['dscfile'] = params['package']
|
||||||
|
params.pop('package')
|
||||||
|
|
||||||
|
mirrors = []
|
||||||
|
if options['mirror']:
|
||||||
|
mirrors.append(options['mirror'])
|
||||||
|
if pull == PULL_DDEBS:
|
||||||
|
config = UDTConfig(options['no_conf'])
|
||||||
|
ddebs_mirror = config.get_value(distro.upper() + '_DDEBS_MIRROR')
|
||||||
|
if ddebs_mirror:
|
||||||
|
mirrors.append(ddebs_mirror)
|
||||||
|
if mirrors:
|
||||||
|
Logger.debug("using mirrors %s", ", ".join(mirrors))
|
||||||
|
params['mirrors'] = mirrors
|
||||||
|
|
||||||
|
params['verify_signature'] = not options['no_verify_signature']
|
||||||
|
|
||||||
|
return (pull, distro, params)
|
||||||
|
|
||||||
|
def pull(self, args=None):
|
||||||
|
"""Pull (download) specified package file(s)"""
|
||||||
|
options = vars(self.argparser.parse_args(args))
|
||||||
|
|
||||||
|
assert 'verbose' in options
|
||||||
|
if options['verbose'] is not None:
|
||||||
|
Logger.set_verbosity(options['verbose'])
|
||||||
|
|
||||||
Logger.debug("pullpkg options: %s", options)
|
Logger.debug("pullpkg options: %s", options)
|
||||||
|
|
||||||
# Login anonymously to LP
|
# Login anonymously to LP
|
||||||
Launchpad.login_anonymously()
|
Launchpad.login_anonymously()
|
||||||
|
|
||||||
pull = parse_pull(options.pull)
|
(pull, distro, params) = self.parse_options(options)
|
||||||
|
|
||||||
distro = parse_distro(options.distro)
|
# call implementation, and allow exceptions to flow up to caller
|
||||||
|
srcpkg = DISTRO_PKG_CLASS[distro](**params)
|
||||||
config = UDTConfig(options.no_conf)
|
|
||||||
|
|
||||||
mirrors = []
|
|
||||||
if hasattr(options, 'mirror') and options.mirror:
|
|
||||||
mirrors += options.mirror
|
|
||||||
if pull == PULL_DDEBS:
|
|
||||||
ddebs_mirror = config.get_value(distro.upper() + '_DDEBS_MIRROR')
|
|
||||||
if ddebs_mirror:
|
|
||||||
mirrors.append(ddebs_mirror)
|
|
||||||
if mirrors:
|
|
||||||
Logger.debug("using mirrors %s", ", ".join(mirrors))
|
|
||||||
|
|
||||||
package = options.package
|
|
||||||
release = getattr(options, 'release', None)
|
|
||||||
version = getattr(options, 'version', None)
|
|
||||||
pocket = None
|
|
||||||
dscfile = None
|
|
||||||
|
|
||||||
if package.endswith('.dsc') and not release and not version:
|
|
||||||
dscfile = package
|
|
||||||
package = None
|
|
||||||
|
|
||||||
if release:
|
|
||||||
try:
|
|
||||||
(release, pocket) = parse_release(release, distro)
|
|
||||||
except (SeriesNotFoundException, PocketDoesNotExistError):
|
|
||||||
Logger.debug("Param '%s' not valid series, must be version", release)
|
|
||||||
release, version = version, release
|
|
||||||
if release:
|
|
||||||
try:
|
|
||||||
(release, pocket) = parse_release(release, distro)
|
|
||||||
except (SeriesNotFoundException, PocketDoesNotExistError):
|
|
||||||
Logger.error("Can't find series for '%s' or '%s'",
|
|
||||||
release, version)
|
|
||||||
raise
|
|
||||||
|
|
||||||
try:
|
|
||||||
pkgcls = DISTRO_PKG_CLASS[distro]
|
|
||||||
srcpkg = pkgcls(package=package, version=version,
|
|
||||||
series=release, pocket=pocket,
|
|
||||||
mirrors=mirrors, dscfile=dscfile,
|
|
||||||
verify_signature=(not options.no_verify_signature))
|
|
||||||
spph = srcpkg.lp_spph
|
spph = srcpkg.lp_spph
|
||||||
except PackageNotFoundException as e:
|
|
||||||
Logger.error(str(e))
|
|
||||||
raise
|
|
||||||
|
|
||||||
Logger.normal('Found %s', spph.display_name)
|
Logger.normal('Found %s', spph.display_name)
|
||||||
|
|
||||||
@ -251,24 +297,22 @@ def pull(options):
|
|||||||
for f in srcpkg.dsc['Files']:
|
for f in srcpkg.dsc['Files']:
|
||||||
Logger.normal(" %s", f['name'])
|
Logger.normal(" %s", f['name'])
|
||||||
Logger.normal("Binary files:")
|
Logger.normal("Binary files:")
|
||||||
for f in spph.getBinaries(options.arch):
|
for f in spph.getBinaries(options['arch']):
|
||||||
Logger.normal(" %s", f.getFileName())
|
Logger.normal(" %s", f.getFileName())
|
||||||
return
|
elif pull == PULL_SOURCE:
|
||||||
|
|
||||||
# allow DownloadError to flow up to caller
|
# allow DownloadError to flow up to caller
|
||||||
if pull == PULL_SOURCE:
|
|
||||||
srcpkg.pull()
|
srcpkg.pull()
|
||||||
if options.download_only:
|
if options['download_only']:
|
||||||
Logger.debug("--download-only specified, not extracting")
|
Logger.debug("--download-only specified, not extracting")
|
||||||
else:
|
else:
|
||||||
srcpkg.unpack()
|
srcpkg.unpack()
|
||||||
else:
|
else:
|
||||||
name = '.*'
|
name = '.*'
|
||||||
if package != spph.getPackageName():
|
if params['package'] != spph.getPackageName():
|
||||||
Logger.normal("Pulling only binary package '%s'", package)
|
Logger.normal("Pulling only binary package '%s'", params['package'])
|
||||||
Logger.normal("Use package name '%s' to pull all binary packages",
|
Logger.normal("Use package name '%s' to pull all binary packages",
|
||||||
spph.getPackageName())
|
spph.getPackageName())
|
||||||
name = package
|
name = params['package']
|
||||||
if pull == PULL_DEBS:
|
if pull == PULL_DEBS:
|
||||||
name = r'{}(?<!-di)(?<!-dbgsym)$'.format(name)
|
name = r'{}(?<!-di)(?<!-dbgsym)$'.format(name)
|
||||||
elif pull == PULL_DDEBS:
|
elif pull == PULL_DDEBS:
|
||||||
@ -277,7 +321,9 @@ def pull(options):
|
|||||||
name += '-di$'
|
name += '-di$'
|
||||||
else:
|
else:
|
||||||
raise InvalidPullValueError("Invalid pull value %s" % pull)
|
raise InvalidPullValueError("Invalid pull value %s" % pull)
|
||||||
total = srcpkg.pull_binaries(name=name, arch=options.arch)
|
|
||||||
|
# allow DownloadError to flow up to caller
|
||||||
|
total = srcpkg.pull_binaries(name=name, arch=options['arch'])
|
||||||
if total < 1:
|
if total < 1:
|
||||||
Logger.error("No %s found for %s %s", pull,
|
Logger.error("No %s found for %s %s", pull,
|
||||||
package, spph.getVersion())
|
params['package'], spph.getVersion())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user