mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-03-14 08:31:13 +00:00
231 lines
6.8 KiB
Python
Executable File
231 lines
6.8 KiB
Python
Executable File
#!/usr/bin/python
|
|
#
|
|
# Copyright (C) 2007, Canonical Ltd.
|
|
# Copyright (C) 2010, Benjamin Drung <bdrung@ubuntu.com>
|
|
#
|
|
# 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 lazr.restfulclient
|
|
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 tarball (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. ')
|
|
|
|
succeeded_unsubscribe = True
|
|
ums = launchpad.people['ubuntu-main-sponsors']
|
|
uus = launchpad.people['ubuntu-universe-sponsors']
|
|
try:
|
|
bug.unsubscribe(person=ums)
|
|
except lazr.restfulclient.errors.HTTPError, http_error:
|
|
print "failed to unsubscribe ubuntu-main-sponsors: " + http_error.content
|
|
succeeded_unsubscribe = False
|
|
try:
|
|
bug.unsubscribe(person=uus)
|
|
except lazr.restfulclient.errors.HTTPError, http_error:
|
|
print "failed to unsubscribe ubuntu-universe-sponsors: " + http_error.content
|
|
succeeded_unsubscribe = False
|
|
if succeeded_unsubscribe:
|
|
print "ubuntu-{main,universe}-sponsors unsubscribed (for backward compatibility)"
|
|
|
|
us = launchpad.people['ubuntu-sponsors']
|
|
bug.unsubscribe(person=us)
|
|
print "ubuntu-sponsors unsubscribed"
|
|
task.assignee = None
|
|
print "unassigned me"
|
|
task.status = "Fix Committed"
|
|
print "status set to Fix Committed"
|
|
task.lp_save()
|
|
# 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 <bug numbers>
|
|
|
|
-h, --help displays this help
|
|
-p, --package=<package> set the package
|
|
-s, --silent be more silent
|
|
-u, --update updates pbuilder before building
|
|
-v, --verbose be more verbosive
|
|
-V, --version=<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)
|
|
|