pull-lp-source, requestbackport: Take the latest version from any

non-backports pocket. Implemented by making lpapicache's getSourcePackage
smarter.
This commit is contained in:
Stefano Rivera 2011-11-23 01:45:49 +02:00
parent 7dfb6c3ed7
commit 9ba1790863
7 changed files with 82 additions and 64 deletions

View File

@ -24,7 +24,6 @@ import shutil
import sys
import tempfile
from launchpadlib.launchpad import Launchpad
import lsb_release
from debian.debian_support import Version
@ -35,6 +34,9 @@ from ubuntutools.archive import (SourcePackage, DebianSourcePackage,
UbuntuSourcePackage, DownloadError, rmadison)
from ubuntutools.config import UDTConfig, ubu_email
from ubuntutools.builder import get_builder
from ubuntutools.lp.lpapicache import (Launchpad, Distribution,
SeriesNotFoundException,
PackageNotFoundException)
from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
codename_to_distribution)
from ubuntutools.question import YesNoQuestion
@ -144,29 +146,9 @@ def parse(args):
return opts, args, config
def get_current_version(package, distribution, source_release):
info = vendor_to_distroinfo(distribution)
source_release = info().codename(source_release, default=source_release)
latest_version = None
releases = [source_release]
if distribution.lower() == "ubuntu":
releases += [source_release + "-updates", source_release + "-security"]
for release in releases:
for record in rmadison(distribution.lower(), package, suite=release):
if 'source' not in record:
continue
if (not latest_version or
Version(latest_version) < Version(record['version'])):
latest_version = record['version']
return latest_version
def find_release_package(launchpad, mirror, workdir, package, version,
source_release, config):
def find_release_package(mirror, workdir, package, version, source_release,
config):
srcpkg = None
if source_release:
@ -181,40 +163,37 @@ def find_release_package(launchpad, mirror, workdir, package, version,
mirrors.append(config.get_value('%s_MIRROR' % distribution.upper()))
if not version:
version = get_current_version(package, distribution, source_release)
if not version:
error('Unable to find package %s in release %s.' %
(package, source_release))
archive = Distribution(distribution.lower()).getArchive()
try:
spph = archive.getSourcePackage(package, source_release)
except (SeriesNotFoundException, PackageNotFoundException), e:
error(str(e))
version = spph.getVersion()
if distribution == 'Debian':
srcpkg = DebianSourcePackage(package,
version,
workdir=workdir,
lp=launchpad,
mirrors=mirrors)
elif distribution == 'Ubuntu':
srcpkg = UbuntuSourcePackage(package,
version,
workdir=workdir,
lp=launchpad,
mirrors=mirrors)
return srcpkg
def find_package(launchpad, mirror, workdir, package, version, source_release,
config):
def find_package(mirror, workdir, package, version, source_release, config):
"Returns the SourcePackage"
if package.endswith('.dsc'):
return SourcePackage(version=version, dscfile=package,
workdir=workdir, lp=launchpad,
mirrors=(mirror,))
workdir=workdir, mirrors=(mirror,))
if not source_release and not version:
info = vendor_to_distroinfo(system_distribution())
source_release = info().devel()
srcpkg = find_release_package(launchpad, mirror, workdir, package, version,
srcpkg = find_release_package(mirror, workdir, package, version,
source_release, config)
if version and srcpkg.version != version:
error('Requested backport of version %s but version of %s in %s is %s'
@ -298,8 +277,7 @@ def main(args):
opts, (package_or_dsc,), config = parse(args[1:])
script_name = os.path.basename(sys.argv[0])
launchpad = Launchpad.login_anonymously(script_name, opts.lpinstance)
Launchpad.login_anonymously(service=opts.lpinstance)
if not opts.dest_releases:
distinfo = lsb_release.get_distro_information()
@ -317,8 +295,7 @@ def main(args):
os.makedirs(workdir)
try:
pkg = find_package(launchpad,
opts.mirror,
pkg = find_package(opts.mirror,
workdir,
package_or_dsc,
opts.version,

3
debian/changelog vendored
View File

@ -5,6 +5,9 @@ ubuntu-dev-tools (0.136ubuntu1) UNRELEASED; urgency=low
* Use httplib2 everywhere that we do https. The python stdlib doesn't do
certificate verification.
* requestbackport: Check for existing backport bugs first.
* pull-lp-source, requestbackport: Take the latest version from any
non-backports pocket. Implemented by making lpapicache's getSourcePackage
smarter.
-- Stefano Rivera <stefanor@debian.org> Mon, 21 Nov 2011 09:47:00 +0200

View File

@ -11,6 +11,9 @@ pull\-lp\-source \- download a source package from Launchpad
\fBpull\-lp\-source\fR downloads and extracts the specified
\fIversion\fR of <\fBsource package\fR> from Launchpad, or the latest
version of the specified \fIrelease\fR.
To request a version from a particular pocket say
\fIrelease\fB\-\fIpocket\fR (with a magic \fB\-release\fR for only the
release pocket).
If no \fIversion\fR or \fIrelease\fR is specified, the latest version in
the development release will be downloaded.

View File

@ -76,10 +76,10 @@ def main():
release = None
pocket = None
try:
(release, pocket) = split_release_pocket(version)
(release, pocket) = split_release_pocket(version, default=None)
except PocketDoesNotExistError, e:
pass
if release in ubuntu_info.all and pocket is not None:
if release in ubuntu_info.all:
try:
spph = Distribution('ubuntu').getArchive().getSourcePackage(package,
release,

View File

@ -193,7 +193,7 @@ def request_backport(package_spph, source, destinations):
'package': package_spph.getPackageName(),
'version': package_spph.getVersion(),
'component': package_spph.getComponent(),
'source': source,
'source': package_spph.getSeriesAndPocket(),
'destinations': ', '.join(destinations),
}
subject = ("Please backport %(package)s %(version)s (%(component)s) "

View File

@ -281,7 +281,7 @@ class Archive(BaseWrapper):
if '_srcpkgs' not in self.__dict__:
self._srcpkgs = dict()
def getSourcePackage(self, name, series=None, pocket='Release'):
def getSourcePackage(self, name, series=None, pocket=None):
'''
Returns a SourcePackagePublishingHistory object for the most
recent source package in the distribution 'dist', series and
@ -289,13 +289,23 @@ class Archive(BaseWrapper):
series defaults to the current development series if not specified.
pocket may be a list, if so, the highest version will be returned.
It defaults to all pockets except backports.
If the requested source package doesn't exist a
PackageNotFoundException is raised.
'''
# Check if pocket has a valid value
if pocket not in _POCKETS:
raise PocketDoesNotExistError("Pocket '%s' does not exist." %
pocket)
if pocket is None:
pockets = frozenset(('Proposed', 'Updates', 'Security', 'Release'))
elif isinstance(pocket, basestring):
pockets = frozenset((pocket,))
else:
pockets = frozenset(pocket)
for pocket in pockets:
if pocket not in _POCKETS:
raise PocketDoesNotExistError("Pocket '%s' does not exist." %
pocket)
dist = Distribution(self.distribution_link)
# Check if series is already a DistoSeries object or not
@ -305,25 +315,40 @@ class Archive(BaseWrapper):
else:
series = dist.getDevelopmentSeries()
if (name, series.name, pocket) not in self._srcpkgs:
try:
srcpkg = self.getPublishedSources(source_name=name,
distro_series=series(),
pocket=pocket,
status='Published',
exact_match=True)[0]
index = (name, series.name, pocket)
self._srcpkgs[index] = SourcePackagePublishingHistory(srcpkg)
except IndexError:
index = (name, series.name, pockets)
if index not in self._srcpkgs:
params = {
'source_name': name,
'distro_series': series(),
'status': 'Published',
'exact_match': True,
}
if len(pockets) == 1:
params['pocket'] = list(pockets)[0]
records = self.getPublishedSources(**params)
latest = None
for record in records:
if record.pocket not in pockets:
continue
if latest is None or (Version(latest.source_package_version)
< Version(record.source_package_version)):
latest = record
if latest is None:
msg = "The package '%s' does not exist in the %s %s archive" % \
(name, dist.display_name, self.name)
if pocket == 'Release':
msg += " in '%s'" % series.name
else:
msg += " in '%s-%s'" % (series.name, pocket.lower())
pockets = [series.name if pocket == 'Release'
else '%s-%s' % (series.name, pocket.lower())
for pocket in pockets]
if len(pockets) > 1:
pockets[-2:] = [' or '.join(pockets[-2:])]
msg += " in " + ', '.join(pockets)
raise PackageNotFoundException(msg)
return self._srcpkgs[(name, series.name, pocket)]
self._srcpkgs[index] = SourcePackagePublishingHistory(latest)
return self._srcpkgs[index]
def copyPackage(self, source_name, version, from_archive, to_pocket,
to_series=None, include_binaries=False):
@ -377,6 +402,16 @@ class SourcePackagePublishingHistory(BaseWrapper):
'''
return self._lpobject.component_name
def getSeriesAndPocket(self):
'''
Returns a human-readable release-pocket
'''
series = DistroSeries(self._lpobject.distro_series_link)
release = series.name
if self._lpobject.pocket != 'Release':
release += '-' + self._lpobject.pocket.lower()
return release
def getChangelog(self, since_version=None):
'''
Return the changelog, optionally since a particular version

View File

@ -122,7 +122,7 @@ def readlist(filename, uniq=True):
return items
def split_release_pocket(release):
def split_release_pocket(release, default='Release'):
'''Splits the release and pocket name.
If the argument doesn't contain a pocket name then the 'Release' pocket
@ -130,7 +130,7 @@ def split_release_pocket(release):
Returns the release and pocket name.
'''
pocket = 'Release'
pocket = default
if release is None:
raise ValueError('No release name specified')