2019-09-04 12:51:31 -03:00
|
|
|
#!/usr/bin/python3
|
2010-12-11 14:12:02 -08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# ##################################################################
|
|
|
|
#
|
2011-06-11 05:45:21 -07:00
|
|
|
# Copyright (C) 2010-2011, Evan Broder <evan@ebroder.net>
|
2010-12-18 12:58:11 -08:00
|
|
|
# Copyright (C) 2010, Benjamin Drung <bdrung@ubuntu.com>
|
2010-12-18 12:09:44 -08:00
|
|
|
#
|
2010-12-11 14:12:02 -08:00
|
|
|
# This program 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; version 2.
|
|
|
|
#
|
|
|
|
# This program 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.
|
|
|
|
#
|
|
|
|
# See file /usr/share/common-licenses/GPL-2 for more details.
|
|
|
|
#
|
|
|
|
# ##################################################################
|
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
import argparse
|
2012-05-06 12:32:54 +02:00
|
|
|
import glob
|
2010-12-11 14:12:02 -08:00
|
|
|
import os
|
|
|
|
import shutil
|
2019-09-04 19:17:00 -03:00
|
|
|
import subprocess
|
2010-12-11 14:12:02 -08:00
|
|
|
import sys
|
|
|
|
import tempfile
|
2020-01-21 15:09:29 +00:00
|
|
|
from urllib.parse import quote
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2022-09-28 08:18:52 +02:00
|
|
|
try:
|
|
|
|
import lsb_release
|
|
|
|
except ImportError:
|
|
|
|
lsb_release = None
|
2021-12-05 15:49:31 +01:00
|
|
|
from distro_info import DebianDistroInfo, UbuntuDistroInfo
|
2023-01-30 21:28:47 +01:00
|
|
|
from httplib2 import Http, HttpLib2Error
|
2011-05-23 23:41:00 +02:00
|
|
|
|
2023-01-30 21:28:47 +01:00
|
|
|
from ubuntutools import getLogger
|
|
|
|
from ubuntutools.archive import DebianSourcePackage, DownloadError, UbuntuSourcePackage
|
2010-12-22 23:31:35 +01:00
|
|
|
from ubuntutools.builder import get_builder
|
2023-01-30 21:28:47 +01:00
|
|
|
from ubuntutools.config import UDTConfig, ubu_email
|
2023-01-30 19:45:36 +01:00
|
|
|
from ubuntutools.lp.lpapicache import (
|
|
|
|
Distribution,
|
2023-01-30 21:28:47 +01:00
|
|
|
Launchpad,
|
2023-01-30 19:45:36 +01:00
|
|
|
PackageNotFoundException,
|
2023-01-30 21:28:47 +01:00
|
|
|
SeriesNotFoundException,
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2023-01-30 21:28:47 +01:00
|
|
|
from ubuntutools.misc import codename_to_distribution, system_distribution, vendor_to_distroinfo
|
2010-12-18 19:22:07 +01:00
|
|
|
from ubuntutools.question import YesNoQuestion
|
2010-12-12 19:27:08 -08:00
|
|
|
|
2021-02-01 18:26:13 -05:00
|
|
|
Logger = getLogger()
|
2018-10-12 18:54:07 -04:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2023-01-31 11:13:07 +01:00
|
|
|
def error(msg, *args):
|
|
|
|
Logger.error(msg, *args)
|
2010-12-11 14:12:02 -08:00
|
|
|
sys.exit(1)
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2010-12-12 18:24:28 -08:00
|
|
|
def check_call(cmd, *args, **kwargs):
|
2023-01-30 19:45:36 +01:00
|
|
|
Logger.debug(" ".join(cmd))
|
2010-12-12 18:24:28 -08:00
|
|
|
ret = subprocess.call(cmd, *args, **kwargs)
|
|
|
|
if ret != 0:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("%s returned %d.", cmd[0], ret)
|
2010-12-12 18:24:28 -08:00
|
|
|
|
2012-12-04 16:01:51 +02:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
def parse(argv):
|
|
|
|
usage = "%(prog)s [options] <source package name or .dsc URL/file>"
|
|
|
|
parser = argparse.ArgumentParser(usage=usage)
|
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-d",
|
|
|
|
"--destination",
|
|
|
|
metavar="DEST",
|
|
|
|
dest="dest_releases",
|
|
|
|
default=[],
|
|
|
|
action="append",
|
|
|
|
help="Backport to DEST release (default: current release)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-s",
|
|
|
|
"--source",
|
|
|
|
metavar="SOURCE",
|
|
|
|
dest="source_release",
|
|
|
|
help="Backport from SOURCE release (default: devel release)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-S",
|
|
|
|
"--suffix",
|
|
|
|
metavar="SUFFIX",
|
|
|
|
help="Suffix to append to version number (default: ~ppa1 when uploading to a PPA)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-e",
|
|
|
|
"--message",
|
|
|
|
metavar="MESSAGE",
|
|
|
|
default="No-change",
|
|
|
|
help='Changelog message to use instead of "No-change" '
|
|
|
|
"(default: No-change backport to DEST.)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-b",
|
|
|
|
"--build",
|
|
|
|
default=False,
|
|
|
|
action="store_true",
|
2023-01-31 13:33:18 +01:00
|
|
|
help="Build the package before uploading (default: %(default)s)",
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-B",
|
|
|
|
"--builder",
|
|
|
|
metavar="BUILDER",
|
|
|
|
help="Specify the package builder (default: pbuilder)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-U",
|
|
|
|
"--update",
|
|
|
|
default=False,
|
|
|
|
action="store_true",
|
|
|
|
help="Update the build environment before attempting to build",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument("-u", "--upload", metavar="UPLOAD", help="Specify an upload destination")
|
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-k", "--key", dest="keyid", help="Specify the key ID to be used for signing."
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"--dont-sign", dest="keyid", action="store_false", help="Do not sign the upload."
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-y",
|
|
|
|
"--yes",
|
|
|
|
dest="prompt",
|
|
|
|
default=True,
|
|
|
|
action="store_false",
|
|
|
|
help="Do not prompt before uploading to a PPA",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-v", "--version", metavar="VERSION", help="Package version to backport (or verify)"
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-w",
|
|
|
|
"--workdir",
|
|
|
|
metavar="WORKDIR",
|
|
|
|
help="Specify a working directory (default: temporary dir)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-r",
|
|
|
|
"--release-pocket",
|
|
|
|
default=False,
|
|
|
|
action="store_true",
|
|
|
|
help="Target the release pocket in the .changes file. "
|
|
|
|
"Necessary (and default) for uploads to PPAs",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
|
|
|
"-c", "--close", metavar="BUG", help="Bug to close in the changelog entry."
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-m", "--mirror", metavar="URL", help="Preferred mirror (default: Launchpad)"
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"-l",
|
|
|
|
"--lpinstance",
|
|
|
|
metavar="INSTANCE",
|
|
|
|
help="Launchpad instance to connect to (default: production)",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument(
|
2023-01-30 19:45:36 +01:00
|
|
|
"--no-conf",
|
|
|
|
default=False,
|
|
|
|
action="store_true",
|
|
|
|
help="Don't read config files or environment variables",
|
|
|
|
)
|
2023-01-31 13:33:18 +01:00
|
|
|
parser.add_argument("package_or_dsc", help=argparse.SUPPRESS)
|
|
|
|
|
|
|
|
args = parser.parse_args(argv)
|
|
|
|
config = UDTConfig(args.no_conf)
|
|
|
|
if args.builder is None:
|
|
|
|
args.builder = config.get_value("BUILDER")
|
|
|
|
if not args.update:
|
|
|
|
args.update = config.get_value("UPDATE_BUILDER", boolean=True)
|
|
|
|
if args.workdir is None:
|
|
|
|
args.workdir = config.get_value("WORKDIR")
|
|
|
|
if args.lpinstance is None:
|
|
|
|
args.lpinstance = config.get_value("LPINSTANCE")
|
|
|
|
if args.upload is None:
|
|
|
|
args.upload = config.get_value("UPLOAD")
|
|
|
|
if args.keyid is None:
|
|
|
|
args.keyid = config.get_value("KEYID")
|
|
|
|
if not args.upload and not args.workdir:
|
2023-01-30 19:45:36 +01:00
|
|
|
parser.error("Please specify either a working dir or an upload target!")
|
2023-01-31 13:33:18 +01:00
|
|
|
if args.upload and args.upload.startswith("ppa:"):
|
|
|
|
args.release_pocket = True
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
return args, config
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2011-06-19 14:46:53 -07:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
def find_release_package(mirror, workdir, package, version, source_release, config):
|
2011-06-11 05:45:21 -07:00
|
|
|
srcpkg = None
|
|
|
|
|
|
|
|
if source_release:
|
|
|
|
distribution = codename_to_distribution(source_release)
|
2011-06-19 14:35:50 -07:00
|
|
|
if not distribution:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("Unknown release codename %s", source_release)
|
2012-02-15 16:57:17 +02:00
|
|
|
info = vendor_to_distroinfo(distribution)()
|
|
|
|
source_release = info.codename(source_release, default=source_release)
|
2010-12-12 18:12:28 -08:00
|
|
|
else:
|
2011-06-11 05:45:21 -07:00
|
|
|
distribution = system_distribution()
|
2011-06-23 17:55:14 -07:00
|
|
|
mirrors = [mirror] if mirror else []
|
|
|
|
|
2023-01-31 19:32:58 +01:00
|
|
|
mirrors.append(config.get_value(f"{distribution.upper()}_MIRROR"))
|
2011-06-11 05:45:21 -07:00
|
|
|
|
|
|
|
if not version:
|
2011-11-23 01:45:49 +02:00
|
|
|
archive = Distribution(distribution.lower()).getArchive()
|
|
|
|
try:
|
|
|
|
spph = archive.getSourcePackage(package, source_release)
|
2015-01-25 21:01:03 +03:00
|
|
|
except (SeriesNotFoundException, PackageNotFoundException) as e:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("%s", str(e))
|
2011-11-23 01:45:49 +02:00
|
|
|
version = spph.getVersion()
|
2010-12-12 18:12:28 -08:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
if distribution == "Debian":
|
|
|
|
srcpkg = DebianSourcePackage(package, version, workdir=workdir, mirrors=mirrors)
|
|
|
|
elif distribution == "Ubuntu":
|
|
|
|
srcpkg = UbuntuSourcePackage(package, version, workdir=workdir, mirrors=mirrors)
|
2010-12-12 18:12:28 -08:00
|
|
|
|
|
|
|
return srcpkg
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2011-11-23 01:45:49 +02:00
|
|
|
def find_package(mirror, workdir, package, version, source_release, config):
|
2010-12-30 18:05:55 +02:00
|
|
|
"Returns the SourcePackage"
|
2023-01-30 19:45:36 +01:00
|
|
|
if package.endswith(".dsc"):
|
2021-05-02 19:55:44 +02:00
|
|
|
# Here we are using UbuntuSourcePackage just because we don't have any
|
|
|
|
# "general" class that is safely instantiable (as SourcePackage is an
|
|
|
|
# abstract class). None of the distribution-specific details within
|
|
|
|
# UbuntuSourcePackage is relevant for this use case.
|
2023-01-30 19:45:36 +01:00
|
|
|
return UbuntuSourcePackage(
|
|
|
|
version=version, dscfile=package, workdir=workdir, mirrors=(mirror,)
|
|
|
|
)
|
2010-12-28 00:23:53 +02:00
|
|
|
|
2010-12-15 20:39:50 -08:00
|
|
|
if not source_release and not version:
|
2011-06-11 05:45:21 -07:00
|
|
|
info = vendor_to_distroinfo(system_distribution())
|
|
|
|
source_release = info().devel()
|
2010-12-12 18:12:28 -08:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
srcpkg = find_release_package(mirror, workdir, package, version, source_release, config)
|
2011-06-11 05:45:21 -07:00
|
|
|
if version and srcpkg.version != version:
|
2023-01-30 19:45:36 +01:00
|
|
|
error(
|
2023-01-31 11:13:07 +01:00
|
|
|
"Requested backport of version %s but version of %s in %s is %s",
|
|
|
|
version,
|
|
|
|
package,
|
|
|
|
source_release,
|
|
|
|
srcpkg.version,
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2011-06-11 05:45:21 -07:00
|
|
|
|
|
|
|
return srcpkg
|
2010-12-12 18:12:28 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2010-12-18 12:16:02 -08:00
|
|
|
def get_backport_version(version, suffix, upload, release):
|
2012-05-13 13:49:49 -07:00
|
|
|
distribution = codename_to_distribution(release)
|
|
|
|
if not distribution:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("Unknown release codename %s", release)
|
2023-01-30 19:45:36 +01:00
|
|
|
if distribution == "Debian":
|
2021-12-05 15:42:11 +01:00
|
|
|
debian_distro_info = DebianDistroInfo()
|
|
|
|
debian_codenames = debian_distro_info.supported()
|
|
|
|
if release in debian_codenames:
|
|
|
|
release_version = debian_distro_info.version(release)
|
|
|
|
if not release_version:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("Can't find the release version for %s", release)
|
2023-01-31 19:32:58 +01:00
|
|
|
backport_version = f"{version}~bpo{release_version}+1"
|
2021-12-05 15:42:11 +01:00
|
|
|
else:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("%s is not a supported release (%s)", release, debian_codenames)
|
2023-01-30 19:45:36 +01:00
|
|
|
elif distribution == "Ubuntu":
|
|
|
|
series = Distribution(distribution.lower()).getSeries(name_or_version=release)
|
2012-05-13 13:49:49 -07:00
|
|
|
|
2023-01-31 19:32:58 +01:00
|
|
|
backport_version = f"{version}~bpo{series.version}.1"
|
2021-10-31 16:47:43 +01:00
|
|
|
else:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("Unknown distribution «%s» for release «%s»", distribution, release)
|
2010-12-18 12:33:10 -08:00
|
|
|
if suffix is not None:
|
2010-12-27 15:20:49 +01:00
|
|
|
backport_version += suffix
|
2023-01-30 19:45:36 +01:00
|
|
|
elif upload and upload.startswith("ppa:"):
|
|
|
|
backport_version += "~ppa1"
|
2010-12-27 15:20:49 +01:00
|
|
|
return backport_version
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2012-05-13 14:05:53 -07:00
|
|
|
def get_old_version(source, release):
|
|
|
|
try:
|
|
|
|
distribution = codename_to_distribution(release)
|
|
|
|
archive = Distribution(distribution.lower()).getArchive()
|
2023-01-30 19:45:36 +01:00
|
|
|
pkg = archive.getSourcePackage(
|
|
|
|
source, release, ("Release", "Security", "Updates", "Proposed", "Backports")
|
|
|
|
)
|
2012-05-13 14:05:53 -07:00
|
|
|
return pkg.getVersion()
|
2017-05-01 00:20:03 +02:00
|
|
|
except (SeriesNotFoundException, PackageNotFoundException):
|
2012-05-13 14:05:53 -07:00
|
|
|
pass
|
2023-01-31 16:58:24 +01:00
|
|
|
return None
|
2012-05-13 14:05:53 -07:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2011-12-21 22:49:24 +02:00
|
|
|
def get_backport_dist(release, release_pocket):
|
|
|
|
if release_pocket:
|
2010-12-12 18:48:50 -08:00
|
|
|
return release
|
2023-01-31 19:32:58 +01:00
|
|
|
return f"{release}-backports"
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2010-12-30 18:05:55 +02:00
|
|
|
def do_build(workdir, dsc, release, builder, update):
|
2010-12-22 23:31:35 +01:00
|
|
|
builder = get_builder(builder)
|
2010-12-12 20:11:49 -08:00
|
|
|
if not builder:
|
2023-01-31 16:58:24 +01:00
|
|
|
return None
|
2010-12-12 20:11:49 -08:00
|
|
|
|
2010-12-18 18:17:29 +01:00
|
|
|
if update:
|
2010-12-17 01:36:05 -08:00
|
|
|
if 0 != builder.update(release):
|
2010-12-18 23:08:13 +01:00
|
|
|
sys.exit(1)
|
2010-12-13 04:00:14 -08:00
|
|
|
|
2011-09-10 13:17:11 +02:00
|
|
|
# builder.build is going to chdir to buildresult:
|
|
|
|
workdir = os.path.realpath(workdir)
|
2023-01-30 19:45:36 +01:00
|
|
|
return builder.build(os.path.join(workdir, dsc), release, os.path.join(workdir, "buildresult"))
|
2010-12-12 20:11:49 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2010-12-30 18:05:55 +02:00
|
|
|
def do_upload(workdir, package, bp_version, changes, upload, prompt):
|
2023-01-31 19:32:58 +01:00
|
|
|
print(f"Please check {package} {bp_version} in file://{workdir} carefully!")
|
2023-01-30 19:45:36 +01:00
|
|
|
if prompt or upload == "ubuntu":
|
2023-01-31 19:32:58 +01:00
|
|
|
question = f"Do you want to upload the package to {upload}"
|
2010-12-18 12:29:38 -08:00
|
|
|
answer = YesNoQuestion().ask(question, "yes")
|
2010-12-18 13:11:27 -08:00
|
|
|
if answer == "no":
|
2010-12-18 12:29:38 -08:00
|
|
|
return
|
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
check_call(["dput", upload, changes], cwd=workdir)
|
2010-12-12 20:11:49 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2012-05-06 12:32:54 +02:00
|
|
|
def orig_needed(upload, workdir, pkg):
|
2023-01-30 19:45:36 +01:00
|
|
|
"""Avoid a -sa if possible"""
|
|
|
|
if not upload or not upload.startswith("ppa:"):
|
2012-05-06 12:32:54 +02:00
|
|
|
return True
|
2023-01-30 19:45:36 +01:00
|
|
|
ppa = upload.split(":", 1)[1]
|
|
|
|
user, ppa = ppa.split("/", 1)
|
2012-05-06 12:32:54 +02:00
|
|
|
|
2012-06-02 20:34:20 +01:00
|
|
|
version = pkg.version.upstream_version
|
2012-05-06 12:32:54 +02:00
|
|
|
|
2023-01-30 23:10:31 +01:00
|
|
|
http = Http()
|
2023-01-31 19:32:58 +01:00
|
|
|
for filename in glob.glob(os.path.join(workdir, f"{pkg.source}_{version}.orig*")):
|
|
|
|
url = (
|
|
|
|
f"https://launchpad.net/~{quote(user)}/+archive/{quote(ppa)}/+sourcefiles"
|
|
|
|
f"/{quote(pkg.source)}/{quote(pkg.version.full_version)}"
|
|
|
|
f"/{quote(os.path.basename(filename))}"
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2012-05-06 12:32:54 +02:00
|
|
|
try:
|
2023-01-31 15:51:29 +01:00
|
|
|
headers = http.request(url, "HEAD")[0]
|
2023-01-30 19:45:36 +01:00
|
|
|
if headers.status != 200 or not headers["content-location"].startswith(
|
|
|
|
"https://launchpadlibrarian.net"
|
|
|
|
):
|
2012-05-06 12:32:54 +02:00
|
|
|
return True
|
2015-01-25 21:01:03 +03:00
|
|
|
except HttpLib2Error as e:
|
2018-10-12 18:54:07 -04:00
|
|
|
Logger.debug(e)
|
2012-05-06 12:32:54 +02:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
def do_backport(
|
|
|
|
workdir,
|
|
|
|
pkg,
|
|
|
|
suffix,
|
|
|
|
message,
|
|
|
|
close,
|
|
|
|
release,
|
|
|
|
release_pocket,
|
|
|
|
build,
|
|
|
|
builder,
|
|
|
|
update,
|
|
|
|
upload,
|
|
|
|
keyid,
|
|
|
|
prompt,
|
|
|
|
):
|
2023-01-31 19:32:58 +01:00
|
|
|
dirname = f"{pkg.source}-{release}"
|
2010-12-30 18:05:55 +02:00
|
|
|
srcdir = os.path.join(workdir, dirname)
|
2010-12-12 20:11:49 -08:00
|
|
|
|
2012-03-28 14:47:30 +02:00
|
|
|
if os.path.exists(srcdir):
|
2023-01-31 19:32:58 +01:00
|
|
|
question = f"Working directory {srcdir} already exists. Delete it?"
|
2023-01-30 19:45:36 +01:00
|
|
|
if YesNoQuestion().ask(question, "no") == "no":
|
2012-03-28 14:47:30 +02:00
|
|
|
sys.exit(1)
|
|
|
|
shutil.rmtree(srcdir)
|
|
|
|
|
|
|
|
pkg.unpack(dirname)
|
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
bp_version = get_backport_version(pkg.version.full_version, suffix, upload, release)
|
2012-05-13 14:05:53 -07:00
|
|
|
old_version = get_old_version(pkg.source, release)
|
2011-12-21 22:49:24 +02:00
|
|
|
bp_dist = get_backport_dist(release, release_pocket)
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2023-01-31 19:32:58 +01:00
|
|
|
changelog = f"{message} backport to {release}."
|
2012-05-11 09:56:19 -07:00
|
|
|
if close:
|
2023-01-31 19:32:58 +01:00
|
|
|
changelog += f" (LP: #{close})"
|
2023-01-30 19:45:36 +01:00
|
|
|
check_call(
|
|
|
|
[
|
|
|
|
"dch",
|
|
|
|
"--force-bad-version",
|
|
|
|
"--force-distribution",
|
|
|
|
"--preserve",
|
|
|
|
"--newversion",
|
|
|
|
bp_version,
|
|
|
|
"--distribution",
|
|
|
|
bp_dist,
|
|
|
|
changelog,
|
|
|
|
],
|
|
|
|
cwd=srcdir,
|
|
|
|
)
|
|
|
|
|
|
|
|
cmd = ["debuild", "--no-lintian", "-S", "-nc", "-uc", "-us"]
|
2012-05-06 12:32:54 +02:00
|
|
|
if orig_needed(upload, workdir, pkg):
|
2023-01-30 19:45:36 +01:00
|
|
|
cmd.append("-sa")
|
2012-05-06 12:32:54 +02:00
|
|
|
else:
|
2023-01-30 19:45:36 +01:00
|
|
|
cmd.append("-sd")
|
2012-05-13 14:05:53 -07:00
|
|
|
if old_version:
|
2023-01-31 19:32:58 +01:00
|
|
|
cmd.append(f"-v{old_version}")
|
2012-06-13 23:21:17 +01:00
|
|
|
env = os.environ.copy()
|
2012-06-17 19:54:40 +01:00
|
|
|
# An ubuntu.com e-mail address would make dpkg-buildpackage fail if there
|
|
|
|
# wasn't an Ubuntu maintainer for an ubuntu-versioned package. LP: #1007042
|
2023-01-30 19:45:36 +01:00
|
|
|
env.pop("DEBEMAIL", None)
|
2012-06-13 23:21:17 +01:00
|
|
|
check_call(cmd, cwd=srcdir, env=env)
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
fn_base = pkg.source + "_" + bp_version.split(":", 1)[-1]
|
|
|
|
changes = fn_base + "_source.changes"
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2010-12-15 20:39:50 -08:00
|
|
|
if build:
|
2023-01-30 19:45:36 +01:00
|
|
|
if 0 != do_build(workdir, fn_base + ".dsc", release, builder, update):
|
2010-12-18 23:08:13 +01:00
|
|
|
sys.exit(1)
|
2012-12-03 13:15:27 +02:00
|
|
|
|
|
|
|
# None: sign with the default signature. False: don't sign
|
|
|
|
if keyid is not False:
|
2023-01-30 19:45:36 +01:00
|
|
|
cmd = ["debsign"]
|
2012-05-06 13:09:54 +02:00
|
|
|
if keyid:
|
2023-01-30 19:45:36 +01:00
|
|
|
cmd.append("-k" + keyid)
|
2012-05-06 13:09:54 +02:00
|
|
|
cmd.append(changes)
|
|
|
|
check_call(cmd, cwd=workdir)
|
2010-12-15 20:39:50 -08:00
|
|
|
if upload:
|
2012-05-06 13:09:54 +02:00
|
|
|
do_upload(workdir, pkg.source, bp_version, changes, upload, prompt)
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2010-12-12 20:11:49 -08:00
|
|
|
shutil.rmtree(srcdir)
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
def main(argv):
|
2010-12-20 22:08:12 +02:00
|
|
|
ubu_email()
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
args, config = parse(argv[1:])
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
Launchpad.login_anonymously(service=args.lpinstance)
|
2010-12-12 18:12:28 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
if not args.dest_releases:
|
2022-09-28 08:18:52 +02:00
|
|
|
if lsb_release:
|
|
|
|
distinfo = lsb_release.get_distro_information()
|
|
|
|
try:
|
2023-01-30 19:45:36 +01:00
|
|
|
current_distro = distinfo["ID"]
|
2022-09-28 08:18:52 +02:00
|
|
|
except KeyError:
|
2023-01-30 19:45:36 +01:00
|
|
|
error("No destination release specified and unable to guess yours.")
|
2022-09-28 08:18:52 +02:00
|
|
|
else:
|
2023-01-30 19:45:36 +01:00
|
|
|
err, current_distro = subprocess.getstatusoutput("lsb_release --id --short")
|
2022-09-28 08:18:52 +02:00
|
|
|
if err:
|
2023-01-30 19:45:36 +01:00
|
|
|
error("Could not run lsb_release to retrieve distribution")
|
2022-09-28 08:18:52 +02:00
|
|
|
|
2021-12-05 15:49:31 +01:00
|
|
|
if current_distro == "Ubuntu":
|
2023-01-31 13:33:18 +01:00
|
|
|
args.dest_releases = [UbuntuDistroInfo().lts()]
|
2023-03-29 19:26:55 +01:00
|
|
|
elif current_distro == "Debian":
|
2023-01-31 13:33:18 +01:00
|
|
|
args.dest_releases = [DebianDistroInfo().stable()]
|
2021-12-05 15:49:31 +01:00
|
|
|
else:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("Unknown distribution %s, can't guess target release", current_distro)
|
2010-12-15 20:50:30 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
if args.workdir:
|
|
|
|
workdir = os.path.expanduser(args.workdir)
|
2010-12-16 00:06:57 -08:00
|
|
|
else:
|
2023-01-30 19:45:36 +01:00
|
|
|
workdir = tempfile.mkdtemp(prefix="backportpackage-")
|
2010-12-16 00:06:57 -08:00
|
|
|
|
|
|
|
if not os.path.exists(workdir):
|
|
|
|
os.makedirs(workdir)
|
|
|
|
|
2010-12-11 14:12:02 -08:00
|
|
|
try:
|
2023-01-30 19:45:36 +01:00
|
|
|
pkg = find_package(
|
2023-01-31 13:33:18 +01:00
|
|
|
args.mirror, workdir, args.package_or_dsc, args.version, args.source_release, config
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2010-12-30 18:05:55 +02:00
|
|
|
pkg.pull()
|
2010-12-12 18:48:50 -08:00
|
|
|
|
2023-01-31 13:33:18 +01:00
|
|
|
for release in args.dest_releases:
|
2023-01-30 19:45:36 +01:00
|
|
|
do_backport(
|
|
|
|
workdir,
|
|
|
|
pkg,
|
2023-01-31 13:33:18 +01:00
|
|
|
args.suffix,
|
|
|
|
args.message,
|
|
|
|
args.close,
|
2023-01-30 19:45:36 +01:00
|
|
|
release,
|
2023-01-31 13:33:18 +01:00
|
|
|
args.release_pocket,
|
|
|
|
args.build,
|
|
|
|
args.builder,
|
|
|
|
args.update,
|
|
|
|
args.upload,
|
|
|
|
args.keyid,
|
|
|
|
args.prompt,
|
2023-01-30 19:45:36 +01:00
|
|
|
)
|
2015-01-25 21:01:03 +03:00
|
|
|
except DownloadError as e:
|
2023-01-31 11:13:07 +01:00
|
|
|
error("%s", str(e))
|
2010-12-11 14:12:02 -08:00
|
|
|
finally:
|
2023-01-31 13:33:18 +01:00
|
|
|
if not args.workdir:
|
2010-12-16 00:06:57 -08:00
|
|
|
shutil.rmtree(workdir)
|
2010-12-11 14:12:02 -08:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2023-01-30 19:45:36 +01:00
|
|
|
if __name__ == "__main__":
|
2010-12-11 14:12:02 -08:00
|
|
|
sys.exit(main(sys.argv))
|