|
|
|
#! /usr/bin/python3
|
|
|
|
|
|
|
|
# Copyright (C) 2009, 2010, 2011, 2012 Canonical Ltd.
|
|
|
|
# Authors:
|
|
|
|
# Martin Pitt <martin.pitt@ubuntu.com>
|
|
|
|
# Colin Watson <cjwatson@ubuntu.com>
|
|
|
|
|
|
|
|
# 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 3 of the License.
|
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
"""Process binary NEW entries from Debian.
|
|
|
|
|
|
|
|
Find and accept all binary NEW entries built by source packages synced
|
|
|
|
directly from Debian. These do not typically need significant review.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
import atexit
|
|
|
|
from optparse import OptionParser
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
from launchpadlib.launchpad import Launchpad
|
|
|
|
from six.moves.urllib.parse import unquote, urlsplit
|
|
|
|
from six.moves.urllib.request import urlopen, urlretrieve
|
|
|
|
from ubuntutools.question import YesNoQuestion
|
|
|
|
|
|
|
|
import lputils
|
|
|
|
|
|
|
|
|
|
|
|
CONSUMER_KEY = "new-binary-debian-universe"
|
|
|
|
|
|
|
|
|
|
|
|
temp_dir = None
|
|
|
|
|
|
|
|
|
|
|
|
def ensure_temp_dir():
|
|
|
|
global temp_dir
|
|
|
|
if temp_dir is None:
|
|
|
|
temp_dir = tempfile.mkdtemp()
|
|
|
|
atexit.register(shutil.rmtree, temp_dir)
|
|
|
|
|
|
|
|
|
|
|
|
def find_matching_uploads(options, explicit_suite):
|
|
|
|
kwargs = {}
|
|
|
|
if explicit_suite:
|
|
|
|
kwargs["pocket"] = options.pocket
|
|
|
|
uploads = options.series.getPackageUploads(
|
|
|
|
archive=options.archive, status="New", **kwargs)
|
|
|
|
for upload in uploads:
|
|
|
|
if upload.contains_build:
|
|
|
|
if upload.changes_file_url is None:
|
|
|
|
continue
|
|
|
|
# display_name is inaccurate for the theoretical case of an
|
|
|
|
# upload containing multiple builds, but in practice it's close
|
|
|
|
# enough.
|
|
|
|
source = upload.display_name.split(",")[0]
|
|
|
|
if source == "linux":
|
|
|
|
continue
|
|
|
|
binaries = upload.getBinaryProperties()
|
|
|
|
binaries = [b for b in binaries if "customformat" not in b]
|
|
|
|
if [b for b in binaries if "ubuntu" in b["version"]]:
|
|
|
|
continue
|
|
|
|
changes_file = urlopen(upload.changes_file_url)
|
|
|
|
try:
|
|
|
|
changes = changes_file.read().decode("UTF-8", errors="replace")
|
|
|
|
finally:
|
|
|
|
changes_file.close()
|
|
|
|
if (" unstable; urgency=" not in changes and
|
|
|
|
" experimental; urgency=" not in changes):
|
|
|
|
continue
|
|
|
|
|
|
|
|
if options.lintian:
|
|
|
|
ensure_temp_dir()
|
|
|
|
for url in upload.binaryFileUrls():
|
|
|
|
if (not url.endswith("_all.deb") and
|
|
|
|
not url.endswith("_i386.deb")):
|
|
|
|
continue
|
|
|
|
filename = unquote(urlsplit(url)[2].split("/")[-1])
|
|
|
|
print("Fetching %s ..." % filename)
|
|
|
|
path = os.path.join(temp_dir, filename)
|
|
|
|
urlretrieve(url, path)
|
|
|
|
lintian = subprocess.Popen(
|
|
|
|
["lintian", path], stdout=subprocess.PIPE,
|
|
|
|
universal_newlines=True)
|
|
|
|
out = lintian.communicate()[0]
|
|
|
|
if lintian.returncode != 0:
|
|
|
|
print("\n=== %s ===\n%s" % (filename, out),
|
|
|
|
file=sys.stderr)
|
|
|
|
|
|
|
|
yield upload, binaries
|
|
|
|
|
|
|
|
|
|
|
|
def find_and_accept(options, explicit_suite):
|
|
|
|
for upload, binaries in list(
|
|
|
|
find_matching_uploads(options, explicit_suite)):
|
|
|
|
if options.source and upload.package_name not in options.source:
|
|
|
|
continue
|
|
|
|
display = "%s/%s (%s)" % (
|
|
|
|
upload.display_name, upload.display_version, upload.display_arches)
|
|
|
|
if options.dry_run:
|
|
|
|
print("Would accept %s" % display)
|
|
|
|
else:
|
|
|
|
for binary in binaries:
|
|
|
|
if "customformat" not in binary:
|
|
|
|
print("%s | %s Component: %s Section: %s Priority: %s" % (
|
|
|
|
"N" if binary["is_new"] else "*", binary["name"],
|
|
|
|
binary["component"], binary["section"],
|
|
|
|
binary["priority"]))
|
|
|
|
if not options.confirm_all:
|
|
|
|
if YesNoQuestion().ask("Accept %s" % display, "no") == "no":
|
|
|
|
continue
|
|
|
|
print("Accepting %s" % display)
|
|
|
|
upload.acceptFromQueue()
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
parser = OptionParser(usage="usage: %prog [options]")
|
|
|
|
parser.add_option(
|
|
|
|
"-l", "--launchpad", dest="launchpad_instance", default="production")
|
|
|
|
parser.add_option(
|
|
|
|
"-d", "--distribution", metavar="DISTRO", default="ubuntu",
|
|
|
|
help="look in distribution DISTRO")
|
|
|
|
parser.add_option(
|
|
|
|
"-s", "--suite", metavar="SUITE", help="look in suite SUITE")
|
|
|
|
parser.add_option(
|
|
|
|
"-n", "--dry-run", default=False, action="store_true",
|
|
|
|
help="don't make any modifications")
|
|
|
|
parser.add_option(
|
|
|
|
"-y", "--confirm-all", default=False, action="store_true",
|
|
|
|
help="do not ask for confirmation")
|
|
|
|
parser.add_option(
|
|
|
|
"--lintian", default=False, action="store_true",
|
|
|
|
help="run packages through Lintian")
|
|
|
|
parser.add_option(
|
|
|
|
"--source", action="append", metavar="NAME",
|
|
|
|
help="only consider source package NAME")
|
|
|
|
options, _ = parser.parse_args()
|
|
|
|
|
|
|
|
options.launchpad = Launchpad.login_with(
|
|
|
|
CONSUMER_KEY, options.launchpad_instance, version="devel")
|
|
|
|
explicit_suite = options.suite is not None
|
|
|
|
lputils.setup_location(options)
|
|
|
|
|
|
|
|
find_and_accept(options, explicit_suite)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|