Rev 5910: Create a helper tool for uploading packages to Launchpad. in http://bazaar.launchpad.net/~jameinel/bzr/integration
John Arbash Meinel
john at arbash-meinel.com
Mon May 23 15:00:32 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/integration
------------------------------------------------------------
revno: 5910
revision-id: john at arbash-meinel.com-20110523150018-1r1e2ldhnc06ooi4
parent: pqm at pqm.ubuntu.com-20110522135417-n76kmfgwmhygrj7g
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: integration
timestamp: Mon 2011-05-23 17:00:18 +0200
message:
Create a helper tool for uploading packages to Launchpad.
-------------- next part --------------
=== added file 'tools/upload_to_launchpad.py'
--- a/tools/upload_to_launchpad.py 1970-01-01 00:00:00 +0000
+++ b/tools/upload_to_launchpad.py 2011-05-23 15:00:18 +0000
@@ -0,0 +1,178 @@
+# Copyright (C) 2005-2011 Canonical Ltd
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""A tool for uploading tarballs and installers of bzr to Launchpad."""
+
+import os
+import pprint
+import re
+import subprocess
+import sys
+
+_bzr_version_re = re.compile(
+ r'bzr-(?P<major>\d)\.(?P<minor>\d)'
+ r'((?P<micro>(\.|b)\d))?'
+ r'(-(?P<build>\d))?'
+ r'(\.win32-py(?P<py_version>2\.\d))?')
+
+
+def determine_bzr_version(name):
+ """Extra the version information from the string."""
+ m = _bzr_version_re.match(name)
+ if not m:
+ return None
+ return m.groupdict()
+
+
+def add_build_num(name, version_dict, build):
+ """There isn't a build number, add it."""
+ version_bits = '%s.%s' % (version_dict['major'], version_dict['minor'])
+ if version_dict['micro'] is not None:
+ # 'micro' is 'b1' or '.3' etc.
+ version_bits += version_dict['micro']
+ return name.replace(version_bits, '%s-%d' % (version_bits, build))
+
+
+def find_sig_name(name):
+ """See if a signature exists for this entry."""
+ for ext in ('.asc', '.sig'):
+ sig_name = name + ext
+ if os.path.isfile(sig_name):
+ return sig_name
+ return None
+
+
+def get_sig_name(name):
+ """Find a signature file for this entry, or create one."""
+ sig_name = find_sig_name(name)
+ if sig_name is not None:
+ return sig_name
+ # If we got here, there is no signature yet
+ ret = subprocess.call(['gpg', '--detach-sig', '--armor', name])
+ if ret == 0:
+ return name + '.asc'
+ raise RuntimeError("failed to sign %s" % (name,))
+
+
+def get_description(version_dict):
+ """Get the description of this version."""
+ py_version = version_dict['py_version']
+ if py_version is None:
+ return "Windows Standalone Installer"
+ else:
+ return "Windows Python %s Installer" % (py_version,)
+
+
+def get_upload_url(opts, version_info):
+ """Get the URL we are posting to."""
+ var = dict(version_info)
+ if version_info['micro'] is None:
+ var['micro'] = ''
+ base = ('https://launchpad.net/bzr'
+ '/%(major)s.%(minor)s'
+ '/%(major)s.%(minor)s%(micro)s'
+ '/+adddownloadfile')
+ return base % var
+
+
+def get_curl_command(opts, filename, sig_filename, version_info):
+ """Populate the CURL command to upload this content."""
+ description = get_description(version_info)
+ # We may also do field.contenttype=CODETARBALL
+ url = get_upload_url(opts, version_info),
+ command = ['curl',
+ '--form-string', 'field.description=%s' % (description,),
+ '--form-string', 'field.filecontent.used=1',
+ '--form', 'field.filecontent=@%s' % (filename,),
+ '--form-string', 'field.signature.used=1',
+ '--form', 'field.signature=@%s' % (sig_filename,),
+ '--form-string', 'field.contenttype=INSTALLER',
+ '--form-string', 'field.actions.add=Upload',
+ '--referer', url,
+ url,
+ ]
+ if opts.user:
+ command.insert(1, '--user')
+ command.insert(2, opts.user)
+ if opts.ignore_ssl:
+ command.insert(-1, '--insecure')
+ return command
+
+
+def main(args):
+ import optparse
+ p = optparse.OptionParser(usage='%prog [options]')
+ p.add_option('--verbose', '-v', action='store_true', help='Be chatty')
+ p.add_option('--build', default=None, type=int,
+ help='Files that are missing a build id will be renamed'
+ ' to match this build num')
+ p.add_option('--user', default=None, type=str,
+ help='Set the Launchpad username you are uploading as.')
+ p.add_option('--ignore-ssl', default=False, action='store_true',
+ help='Ignore SSL certificates')
+ p.add_option('--dry-run', default=False, action='store_true',
+ help='Don\'t actually run curl')
+
+ (opts, args) = p.parse_args(args)
+ files_to_upload = []
+ for arg in args:
+ if arg.endswith('.asc') or arg.endswith('.sig'):
+ sys.stderr.write('Ignoring signature file: %s\n' % (arg,))
+ continue
+ version = determine_bzr_version(arg)
+ if version is None:
+ sys.stderr.write('Unknown bzr version for %s\n' % (arg,))
+ continue
+ if version['build'] is None and opts.build is not None:
+ build_name = add_build_num(arg, version, opts.build)
+ os.rename(arg, build_name)
+ sig_name = find_sig_name(arg)
+ if sig_name is not None:
+ build_sig_name = add_build_num(sig_name, version, opts.build)
+ os.rename(sig_name, build_sig_name)
+ arg = build_name
+ sig_name = get_sig_name(arg)
+ files_to_upload.append((arg, sig_name, version))
+ # Now sort them
+ def sort_key(info):
+ version = info[-1]
+ py_version = version['py_version']
+ if py_version is None:
+ # We want these to sort last
+ py_version = '\xff\xff\xff\xff\xff\xff'
+ return (version['major'], version['minor'], version['micro'],
+ py_version)
+ files_to_upload.sort(key=sort_key)
+ for f_name, sig_name, version in files_to_upload:
+ curl = get_curl_command(opts, f_name, sig_name, version)
+ if opts.verbose:
+ pprint.pprint(curl)
+ else:
+ sys.stderr.write('Uploading %s' % (f_name,))
+ # We have curl write to a PIPE so that we get progress output, and then
+ # we turn around and write the actual content back out again for the
+ # user to see errors. On success, stdout is empty.
+ if not opts.dry_run:
+ p = subprocess.Popen(curl, stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ sys.stdout.write(stdout)
+ if p.returncode != 0:
+ sys.stderr.write('failed to upload for %s:\n' % (f_name,))
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
+
More information about the bazaar-commits
mailing list