From 47030d4fd7754abf3eeed4b6d163c085c7ae6c1e Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Sat, 13 Feb 2010 19:45:21 +0100 Subject: [PATCH] Add fakesync script. --- fakesync | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100755 fakesync diff --git a/fakesync b/fakesync new file mode 100755 index 0000000..ed87f43 --- /dev/null +++ b/fakesync @@ -0,0 +1,213 @@ +#!/usr/bin/python +# +# Copyright (C) 2007, Canonical Ltd. +# Copyright (C) 2010, Benjamin Drung +# +# fakesync is based on ack-sync, which was initial written by Daniel Holbach. +# +# 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. +# +# 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-3 for more details. + +import getopt +import os +import re +import subprocess +import sys + +from ubuntutools.lp.libsupport import get_launchpad +from ubuntutools.requestsync.common import raw_input_exit_on_ctrlc + +COMMAND_LINE_SYNTAX_ERROR = 1 +VERSION_DETECTION_FAILED = 2 + +def get_version(title): + m = re.search("[() ][0-9][0-9a-zA-Z.:+-]*", title) + if m is None: + print >> sys.stderr, "Version could not be detected. Please specify it with -V." + sys.exit(VERSION_DETECTION_FAILED) + return m.group(0).strip("() ") + +def strip_epoch(version): + parts = version.split(':') + if len(parts) > 1: + del parts[0] + version = ':'.join(parts) + return version + +def extract_upstream_version(debian_version): + # remove last part separated by a dash (1.0-2 -> 1.0) + parts = debian_version.split('-') + if len(parts) > 1: + del parts[-1] + upstream_version = '-'.join(parts) + + # remove epoch + parts = upstream_version.split(':') + if len(parts) > 1: + del parts[0] + upstream_version = ':'.join(parts) + + return upstream_version + +def get_source(package, version, section, bug_number): + assert section in ("main", "contrib", "non-free") + + # TODO: use release-info (once available) + dist = "lucid" + + workdir = "/tmp/fakesync" + if not os.path.isdir(workdir): + os.makedirs(workdir) + os.chdir(workdir) + + if package.startswith("lib"): + group = package[0:4] + else: + group = package[0] + + dsc_file = package + "_" + strip_epoch(version) + ".dsc" + location = os.path.join("http://ftp.debian.org/debian/pool", section, group, package, dsc_file) + #print "location:", location + subprocess.check_call(["dget", "-u", location]) + + # remove the Debian tarball + tarball_name = package + "_" + extract_upstream_version(version) + ".orig.tar.gz" + os.remove(tarball_name) + + # get Ubuntu tarball + subprocess.check_call(["wget", "https://launchpad.net/ubuntu/+archive/primary/+files/" + tarball_name]) + + # Update changelog + os.chdir(package + "-" + extract_upstream_version(version)) + new_version = version + "fakesync1" + subprocess.check_call(["dch", "-v", new_version, "-D", dist, "--force-distribution", "Fake sync due to mismatching .orig.tar.gz (LP: #%i)." % (bug_number)]) + # TODO: do we have to run update-maintainer + subprocess.check_call(["update-maintainer"]) + subprocess.check_call(["debuild", "-S"]) + os.chdir("..") + + # Create Debian -> Ubuntu debdiff + new_dsc_file = package + "_" + strip_epoch(new_version) + ".dsc" + patch_file = package + "_" + strip_epoch(new_version) + ".patch" + output = subprocess.Popen(["debdiff", dsc_file, new_dsc_file], stdout=subprocess.PIPE).communicate()[0] + f = open(patch_file, "w") + f.write(output) + f.close() + + return new_dsc_file + +def build_source(dsc_file): + # TODO: use release-info (once available) + dist = "lucid" + try: + subprocess.check_call(["sudo", "env", "DIST=" + dist, "pbuilder", "build", dsc_file]) + except subprocess.CalledProcessError: + print >> sys.stderr, "E: %s failed to build." % (dsc_file) + sys.exit(1) + +def main(bug_number, package, version, update, verbose=False, silent=False): + launchpad = get_launchpad("ubuntu-dev-tools") + + bug = launchpad.bugs[bug_number] + + task = list(bug.bug_tasks)[0] + + if package is None: + package = task.bug_target_name.split(" ")[0] + if version is None: + version = get_version(bug.title) + print "package:", package + print "version:", version + dsc_file = get_source(package, version, "main", bug_number) + + # update pbuilder + if update: + subprocess.call(["sudo", "env", "DIST=lucid", "pbuilder", "update"]) + + build_source(dsc_file) + + print bug.title + print task.assignee + print task.status + raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') + + people = launchpad.people + uus = people['ubuntu-universe-sponsors'] + bug.unsubscribe(person=uus) + print "uus unsubscribed" + task.transitionToAssignee(assignee=None) + print "unassigned me" + task.transitionToStatus (status="Fix Committed") + print "status set to Fix Committed" +# bug.newMessage(content="package builds, sync request ACK'd") +# print "Ack comment added" + bug.subscribe(person=launchpad.me) + print "subscribed me" + + # Upload package + changes_file = dsc_file[:-4] + "_source.changes" + subprocess.check_call(["dput", changes_file]) + +def usage(): + print """ack-sync + + -h, --help displays this help + -p, --package= set the package + -s, --silent be more silent + -u, --update updates pbuilder before building + -v, --verbose be more verbosive + -V, --version= set the version""" + +if __name__ == '__main__': + try: + long_opts = ["help", "package", "silent", "update", "verbose", "version"] + opts, args = getopt.gnu_getopt(sys.argv[1:], "hp:suvV:", long_opts) + except getopt.GetoptError, e: + # print help information and exit: + print >> sys.stderr, str(e) # will print something like "option -a not recognized" + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + + package = None + silent = False + update = False + verbose = False + version = None + + for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + elif o in ("-p", "--package"): + package = a + elif o in ("-s", "--silent"): + silent = True + elif o in ("-u", "--update"): + update = True + elif o in ("-v", "--verbose"): + verbose = True + elif o in ("-V", "--version"): + version = a + else: + assert False, "unhandled option" + + if len(args) != 1: + if not silent: + print >> sys.stderr, "E: You must specify bug number." + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + + try: + bug_number = int(args[0]) + except: + if not silent: + print >> sys.stderr, "E: '%s' is not a valid bug number." % args[0] + sys.exit(COMMAND_LINE_SYNTAX_ERROR) + main(bug_number, package, version, update, verbose, silent) +