/usr/bin/submittodebian is in ubuntu-dev-tools 0.153.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | #! /usr/bin/python
# -*- coding: utf-8 -*-
#
# submittodebian - tool to submit patches to Debian's BTS
# Copyright (C) 2007, 2009 Canonical Ltd.
# Author: Soren Hansen <soren@ubuntu.com>,
# Steve Langasek <slangasek@canonical.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; either version 2
# of the License, or (at your option) any later version.
#
# 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 for more details.
#
# ##################################################################
import optparse
import os
import re
import shutil
import sys
from tempfile import mkdtemp
from distro_info import UbuntuDistroInfo, DistroDataOutdated
from ubuntutools.config import ubu_email
from ubuntutools.question import YesNoQuestion, EditFile
from ubuntutools.subprocess import call, check_call, Popen, PIPE
from ubuntutools.update_maintainer import update_maintainer, restore_maintainer
try:
from debian.changelog import Changelog
except ImportError:
print (u"This utility requires modules from the «python-debian» package, "
u"which isn't currently installed.")
sys.exit(1)
def get_most_recent_debian_version(changelog):
for block in changelog:
version = block.version.full_version
if not re.search('(ubuntu|build)', version):
return version
def get_bug_body(changelog):
entry = next(iter(changelog))
msg = """
In Ubuntu, the attached patch was applied to achieve the following:
## ---------------- REPLACE THIS WITH ACTUAL INFORMATION ---------------------
## Please add all necessary information about why the change needed to go in
## Ubuntu, quote policy, spec or any other background material and why it can
## and should be used in Debian too. If the patch is composed of multiple
## independent pieces, please send them as separate bug reports.
## ---------------- REPLACE THIS WITH ACTUAL INFORMATION ---------------------
%s
Thanks for considering the patch.
""" % ("\n".join([a for a in entry.changes()]))
return msg
def build_source_package():
if os.path.isdir('.bzr'):
cmd = ['bzr', 'bd', '--builder=dpkg-buildpackage', '-S',
'--', '-uc', '-us', '-nc']
else:
cmd = ['dpkg-buildpackage', '-S', '-uc', '-us', '-nc']
env = os.environ.copy()
# Unset DEBEMAIL in case there's an @ubuntu.com e-mail address
env.pop('DEBEMAIL', None)
check_call(cmd, env=env)
def gen_debdiff(tmpdir, changelog):
pkg = changelog.package
changelog_it = iter(changelog)
newver = next(changelog_it).version
oldver = next(changelog_it).version
debdiff = os.path.join(tmpdir, '%s_%s.debdiff' % (pkg, newver))
devnull = open('/dev/null', 'w')
diff_cmd = ['bzr', 'diff', '-r', 'tag:' + str(oldver)]
if call(diff_cmd, stdout=devnull, stderr=devnull) == 1:
print "Extracting bzr diff between %s and %s" % (oldver, newver)
else:
if oldver.epoch is not None:
oldver = str(oldver)[str(oldver).index(":") + 1:]
if newver.epoch is not None:
newver = str(newver)[str(newver).index(":") + 1:]
olddsc = '../%s_%s.dsc' % (pkg, oldver)
newdsc = '../%s_%s.dsc' % (pkg, newver)
check_file(olddsc)
check_file(newdsc)
print "Generating debdiff between %s and %s" % (oldver, newver)
diff_cmd = ['debdiff', olddsc, newdsc]
diff = Popen(diff_cmd, stdout=PIPE)
debdiff_f = open(debdiff, 'w')
filterdiff = Popen(['filterdiff', '-x', '*changelog*'],
stdin=diff.stdout, stdout=debdiff_f)
diff.stdout.close()
filterdiff.wait()
debdiff_f.close()
devnull.close()
return debdiff
def check_file(fname, critical=True):
if os.path.exists(fname):
return fname
else:
if not critical:
return False
print u"Couldn't find «%s».\n" % fname
sys.exit(1)
def submit_bugreport(body, debdiff, deb_version, changelog):
try:
devel = UbuntuDistroInfo().devel()
except DistroDataOutdated, e:
print str(e)
devel = ''
if os.path.dirname(sys.argv[0]).startswith('/usr/bin'):
editor_path = '/usr/share/ubuntu-dev-tools'
else:
editor_path = os.path.dirname(sys.argv[0])
env = dict(os.environ.items())
if 'EDITOR' in env:
env['UDT_EDIT_WRAPPER_EDITOR'] = env['EDITOR']
if 'VISUAL' in env:
env['UDT_EDIT_WRAPPER_VISUAL'] = env['VISUAL']
env['EDITOR'] = os.path.join(editor_path, 'enforced-editing-wrapper')
env['VISUAL'] = os.path.join(editor_path, 'enforced-editing-wrapper')
env['UDT_EDIT_WRAPPER_TEMPLATE_RE'] = (
'.*REPLACE THIS WITH ACTUAL INFORMATION.*')
env['UDT_EDIT_WRAPPER_FILE_DESCRIPTION'] = 'bug report'
# In external mua mode, attachments are lost (Reportbug bug: #679907)
internal_mua = True
for cfgfile in ('/etc/reportbug.conf', '~/.reportbugrc'):
cfgfile = os.path.expanduser(cfgfile)
if not os.path.exists(cfgfile):
continue
with open(cfgfile, 'r') as f:
for line in f:
line = line.strip()
if line in ('gnus', 'mutt', 'nmh') or line.startswith('mua '):
internal_mua = False
break
cmd = ('reportbug',
'--no-check-available',
'--no-check-installed',
'--pseudo-header', 'User: ubuntu-devel@lists.ubuntu.com',
'--pseudo-header', 'Usertags: origin-ubuntu %s ubuntu-patch'
% devel,
'--tag', 'patch',
'--bts', 'debian',
'--include', body,
'--attach' if internal_mua else '--include', debdiff,
'--package-version', deb_version,
changelog.package)
check_call(cmd, env=env)
def check_reportbug_config():
fn = os.path.expanduser('~/.reportbugrc')
if os.path.exists(fn):
return
email = ubu_email()[1]
reportbugrc = """# Reportbug configuration generated by submittodebian(1)
# See reportbug.conf(5) for the configuration file format.
# Use Debian's reportbug SMTP Server:
# Note: it's limited to 5 connections per hour, and cannot CC you at submission
# time. See /usr/share/doc/reportbug/README.Users.gz for more details.
smtphost reportbug.debian.org:587
header "X-Debbugs-CC: %s"
no-cc
# Use GMail's SMTP Server:
#smtphost smtp.googlemail.com:587
#smtpuser "<your address>@gmail.com"
#smtptls
""" % email
with file(fn, 'w') as f:
f.write(reportbugrc)
print """\
You have not configured reportbug. Assuming this is the first time you have
used it. Writing a ~/.reportbugrc that will use Debian's mail server, and CC
the bug to you at <%s>
--- Generated ~/.reportbugrc ---
%s
--- End of ~/.reportbugrc ---
If this is not correct, please exit now and edit ~/.reportbugrc or run
reportbug --configure for its configuration wizard.
""" % (email, reportbugrc.strip())
if YesNoQuestion().ask("Continue submitting this bug", "yes") == "no":
sys.exit(1)
def main():
description = 'Submit the Ubuntu changes in a package to Debian. ' + \
'Run inside an unpacked Ubuntu source package.'
parser = optparse.OptionParser(description=description)
parser.parse_args()
if not os.path.exists('/usr/bin/reportbug'):
print(u"This utility requires the «reportbug» package, which isn't "
u"currently installed.")
sys.exit(1)
check_reportbug_config()
changelog_file = (check_file('debian/changelog', critical=False) or
check_file('../debian/changelog'))
changelog = Changelog(file(changelog_file).read())
deb_version = get_most_recent_debian_version(changelog)
bug_body = get_bug_body(changelog)
tmpdir = mkdtemp()
body = os.path.join(tmpdir, 'bug_body')
fp = open(body, 'w')
fp.write(bug_body.encode('utf-8'))
fp.close()
restore_maintainer('debian')
build_source_package()
update_maintainer('debian')
debdiff = gen_debdiff(tmpdir, changelog)
# Build again as the user probably doesn't expect the Maintainer to be
# reverted in the most recent build
build_source_package()
EditFile(debdiff, 'debdiff').edit(optional=True)
submit_bugreport(body, debdiff, deb_version, changelog)
os.unlink(body)
os.unlink(debdiff)
shutil.rmtree(tmpdir)
if __name__ == '__main__':
main()
|