backportpackage: Accept a URL or path to a .dsc file as an alternative to a source package name

This commit is contained in:
Evan Broder 2010-12-16 01:05:29 -08:00
parent 2585452cbb
commit b50fbb7750
2 changed files with 58 additions and 28 deletions

View File

@ -41,7 +41,7 @@ def check_call(cmd, *args, **kwargs):
error('%s returned %d' % (cmd, ret)) error('%s returned %d' % (cmd, ret))
def parse(args): def parse(args):
usage = 'Usage: %prog [options] <source package>' usage = 'Usage: %prog [options] <source package name or .dsc URL/file>'
p = optparse.OptionParser(usage) p = optparse.OptionParser(usage)
p.add_option('-d', '--destination', p.add_option('-d', '--destination',
dest='dest_releases', dest='dest_releases',
@ -86,7 +86,7 @@ def parse(args):
opts, args = p.parse_args(args) opts, args = p.parse_args(args)
if len(args) != 1: if len(args) != 1:
p.error('You must specify a source package') p.error('You must specify a single source package or a .dsc URL/path')
if not opts.upload and not opts.build: if not opts.upload and not opts.build:
p.error('Nothing to do') p.error('Nothing to do')
@ -129,9 +129,7 @@ def find_version_package(lp, package, version):
error('Version %s of package %s was never published in Ubuntu' % error('Version %s of package %s was never published in Ubuntu' %
(version, package)) (version, package))
def fetch_package(lp, workdir, package, version, source_release): def dscurl_from_package(lp, workdir, package, version, source_release):
# Returns the path to the .dsc file that was fetched
if not source_release and not version: if not source_release and not version:
source_release = lp.distributions['ubuntu'].current_series.name source_release = lp.distributions['ubuntu'].current_series.name
@ -144,14 +142,33 @@ def fetch_package(lp, workdir, package, version, source_release):
for f in srcpkg.sourceFileUrls(): for f in srcpkg.sourceFileUrls():
if f.endswith('.dsc'): if f.endswith('.dsc'):
return urllib.unquote(f)
else:
error('Package %s contains no .dsc file' % package)
def dscurl_from_dsc(package):
path = os.path.abspath(os.path.expanduser(package))
if os.path.exists(path):
return 'file://%s' % path
else:
# Can't resolve it as a local path? Let's just hope it's good
# as-is
return package
def fetch_package(lp, workdir, package, version, source_release):
# Returns the path to the .dsc file that was fetched
if package.endswith('.dsc'):
dsc = dscurl_from_dsc(package)
else:
dsc = dscurl_from_package(lp, workdir, package, version, source_release)
check_call(['dget', check_call(['dget',
'--download-only', '--download-only',
'--allow-unauthenticated', '--allow-unauthenticated',
urllib.unquote(f)], dsc],
cwd=workdir) cwd=workdir)
return os.path.join(workdir, os.path.basename(f)) return os.path.join(workdir, os.path.basename(dsc))
else:
error('Package %s contains no .dsc file' % package)
def get_backport_version(version, upload, release): def get_backport_version(version, upload, release):
v = version + ('~%s1' % release) v = version + ('~%s1' % release)
@ -191,10 +208,7 @@ def do_upload(workdir, package, bp_version, upload):
cwd=workdir) cwd=workdir)
def do_backport(workdir, package, dscfile, release, build, builder, upload): def do_backport(workdir, package, dscfile, version, release, build, builder, upload):
dsc = Dsc(open(os.path.join(workdir, dscfile)))
v = dsc['Version']
check_call(['dpkg-source', check_call(['dpkg-source',
'-x', '-x',
dscfile, dscfile,
@ -202,7 +216,7 @@ def do_backport(workdir, package, dscfile, release, build, builder, upload):
cwd=workdir) cwd=workdir)
srcdir = os.path.join(workdir, package) srcdir = os.path.join(workdir, package)
bp_version = get_backport_version(v, upload, release) bp_version = get_backport_version(version, upload, release)
bp_dist = get_backport_dist(upload, release) bp_dist = get_backport_dist(upload, release)
check_call(['dch', check_call(['dch',
@ -230,7 +244,7 @@ def do_backport(workdir, package, dscfile, release, build, builder, upload):
def main(args): def main(args):
os.environ['DEB_VENDOR'] = 'Ubuntu' os.environ['DEB_VENDOR'] = 'Ubuntu'
opts, (package,) = parse(args[1:]) opts, (package_or_dsc,) = parse(args[1:])
script_name = os.path.basename(sys.argv[0]) script_name = os.path.basename(sys.argv[0])
lp = launchpadlib.launchpad.Launchpad.login_anonymously(script_name, lp = launchpadlib.launchpad.Launchpad.login_anonymously(script_name,
@ -254,14 +268,19 @@ def main(args):
try: try:
dscfile = fetch_package(lp, dscfile = fetch_package(lp,
workdir, workdir,
package, package_or_dsc,
opts.version, opts.version,
opts.source_release) opts.source_release)
dsc = Dsc(open(os.path.join(workdir, dscfile)))
package = dsc['Source']
version = dsc['Version']
for release in opts.dest_releases: for release in opts.dest_releases:
do_backport(workdir, do_backport(workdir,
package, package,
dscfile, dscfile,
version,
release, release,
opts.build, opts.build,
opts.builder, opts.builder,

View File

@ -6,7 +6,7 @@ backportpackage \- helper to test package backports
.B backportpackage \fR[\fIadditional options\fR] .B backportpackage \fR[\fIadditional options\fR]
\-\-upload <\fIupload target\fR> \-\-upload <\fIupload target\fR>
.br .br
<\fIsource package\fR> <\fIsource package name or .dsc URL/file\fR>
.PP .PP
.B backportpackage \-h .B backportpackage \-h
.SH OPTIONS .SH OPTIONS
@ -42,7 +42,8 @@ If the \fB\-\-source\fR option is specified, then
package\fR in \fISOURCE\fR is the same as \fIVERSION\fR. Otherwise, package\fR in \fISOURCE\fR is the same as \fIVERSION\fR. Otherwise,
\fBbackportpackage\fR finds version \fIVERSION\fR of \fIsource \fBbackportpackage\fR finds version \fIVERSION\fR of \fIsource
package\fR, regardless of the release in which it was published (or if package\fR, regardless of the release in which it was published (or if
that version is still current). that version is still current). This option is ignored if a .dsc URL
or path is passed in instead of a source package name.
.TP .TP
.B \-w \fIWORKDIR\fR, \-\-workdir=\fIWORKDIR\fR .B \-w \fIWORKDIR\fR, \-\-workdir=\fIWORKDIR\fR
If \fIWORKDIR\fR is specified, then all files are downloaded, If \fIWORKDIR\fR is specified, then all files are downloaded,
@ -54,13 +55,14 @@ deleted before \fIbackportpackage\fR exits.
Use the specified instance of Launchpad (e.g. "staging"), instead of Use the specified instance of Launchpad (e.g. "staging"), instead of
the default of "production". the default of "production".
.SH DESCRIPTION .SH DESCRIPTION
\fBbackportpackage\fR fetches a package from one Ubuntu release and \fBbackportpackage\fR fetches a package from one Ubuntu release or
creates a no-change backport of that package to a previous release, from a specified .dsc path or URL and creates a no-change backport of
optionally doing a test build of the package and/or uploading the that package to a previous release, optionally doing a test build of
resulting backport for testing. the package and/or uploading the resulting backport for testing.
.PP .PP
The backported package is fetched and built in a temporary directory Unless a working directory is specified, the backported package is
in \fB/tmp\fR, which is removed once the script finishes running. fetched and built in a temporary directory in \fB/tmp\fR, which is
removed once the script finishes running.
.PP .PP
\fBbackportpackage\fR is only recommended for testing backports in a \fBbackportpackage\fR is only recommended for testing backports in a
PPA, not uploading backports to the Ubuntu archive. PPA, not uploading backports to the Ubuntu archive.
@ -68,7 +70,7 @@ PPA, not uploading backports to the Ubuntu archive.
.TP .TP
.B UBUNTUTOOLS_BUILDER .B UBUNTUTOOLS_BUILDER
The default builder for Ubuntu development tools that support it The default builder for Ubuntu development tools that support it
(including \fBbackportpackage\fR. Supported are \fBpbuilder\fR(8) and (including \fBbackportpackage\fR). Supported are \fBpbuilder\fR(8) and
\fBsbuild\fR(1). If unset and not provided on the command line, \fBsbuild\fR(1). If unset and not provided on the command line,
\fBpbuilder\fR(8) is used. \fBpbuilder\fR(8) is used.
.SH EXAMPLES .SH EXAMPLES
@ -85,7 +87,16 @@ test-build both locally, leaving all build products in the current
working directory: working directory:
.IP .IP
.nf .nf
.B backportpackage -b -s maverick -d karmic -d lucid -w . squashfs-tools .B backportpackage -b -s maverick -d karmic -d lucid -w . \\\\
.B " "squashfs-tools
.fi
.PP
Fetch a package from a PPA, backport it to Hardy, then upload it back
to the same PPA:
.IP
.nf
.B backportpackage -d hardy -u ppa:\fIuser\fR/\fIppa\fR \\\\
.B " "https://launchpad.net/\fIsome/file.dsc\fR
.fi .fi
.SH AUTHOR .SH AUTHOR
\fBbackportpackage\fR and this manpage were written by Evan Broder \fBbackportpackage\fR and this manpage were written by Evan Broder