Merge lp:~jelmer/lptools/migrate-project-upload into lp:lptools

Proposed by Jelmer Vernooij
Status: Merged
Merged at revision: 19
Proposed branch: lp:~jelmer/lptools/migrate-project-upload
Merge into: lp:lptools
Diff against target: 179 lines (+175/-0)
1 file modified
bin/lp-project-upload (+175/-0)
To merge this branch: bzr merge lp:~jelmer/lptools/migrate-project-upload
Reviewer Review Type Date Requested Status
lptools Hackers Pending
Review via email: mp+71582@code.launchpad.net

Description of the change

Migrate lp-project-upload from ubuntu-dev-tools to lptools.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'bin/lp-project-upload'
2--- bin/lp-project-upload 1970-01-01 00:00:00 +0000
3+++ bin/lp-project-upload 2011-08-15 16:43:24 +0000
4@@ -0,0 +1,175 @@
5+#!/usr/bin/python
6+
7+# Copyright (c) 2009 Canonical Ltd.
8+#
9+# This program is free software; you can redistribute it and/or modify it
10+# under the terms of the GNU General Public License as published by the
11+# Free Software Foundation; either version 2, or (at your option) any
12+# later version.
13+#
14+# lp-project-upload is distributed in the hope that it will be useful, but
15+# WITHOUT ANY WARRANTY; without even the implied warranty of
16+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+# General Public License for more details.
18+
19+# Authors:
20+# Martin Pitt <martin.pitt@ubuntu.com>, based on
21+# http://blog.launchpad.net/api/recipe-for-uploading-files-via-the-api
22+# Dustin Kirkland <kirkland@ubuntu.com>
23+# - support files for changelog and release notes
24+
25+'''Upload a release tarball to a Launchpad project.'''
26+
27+import datetime
28+import os
29+import sys
30+import tempfile
31+
32+from launchpadlib.errors import HTTPError
33+
34+import subprocess
35+
36+from lptools import config
37+
38+def create_release(project, version):
39+ '''Create new release and milestone for LP project.'''
40+
41+ print 'Release %s could not be found for project. Create it? (Y/n)' % \
42+ version
43+ answer = sys.stdin.readline().strip()
44+ if answer.startswith('n'):
45+ sys.exit(0)
46+
47+ n_series = len(project.series)
48+ if n_series == 1:
49+ series = project.series[0]
50+ elif n_series > 1:
51+ msg = 'More than one series exist. Which one would you like to ' \
52+ 'upload to? Possible series are (listed as index, name):'
53+ print msg
54+ for idx, serie in enumerate(project.series):
55+ print '\t%i - %s' % (idx, serie.name)
56+ print 'Enter series index: '
57+ answer = sys.stdin.readline().strip()
58+ try:
59+ series = project.series[int(answer)]
60+ except (ValueError, IndexError):
61+ print >> sys.stderr, 'The series index is invalid (%s).' % answer
62+ sys.exit(3)
63+ else:
64+ print "Using series named '%s'" % series.name
65+ else:
66+ print >> sys.stderr, ('Does not support creating releases if no '
67+ 'series exists.')
68+ sys.exit(3)
69+
70+ release_date = datetime.date.today().strftime('%Y-%m-%d')
71+ milestone = series.newMilestone(name=version,
72+ date_targeted=release_date)
73+ return milestone.createProductRelease(date_released=release_date)
74+
75+def edit_file(prefix, description):
76+ (fd, f) = tempfile.mkstemp(prefix=prefix+'.')
77+ os.write(fd, '\n\n#------\n# Please enter the %s here. '
78+ 'Lines which start with "#" are ignored.\n' % description)
79+ os.close(fd)
80+ subprocess.call(['sensible-editor', f])
81+ return cat_file(f)
82+
83+def cat_file(f):
84+ content = ''
85+ for line in open(f):
86+ if line.startswith('#'):
87+ continue
88+ content += line
89+ return content.strip()
90+
91+def main():
92+ if len(sys.argv) < 4 or len(sys.argv) > 7:
93+ print >> sys.stderr, '''Upload a release tarball to a Launchpad project.
94+
95+ Usage: %s <project name> <version> <tarball> [new milestone] [changelog file] [releasenotes file]''' % sys.argv[0]
96+ sys.exit(1)
97+
98+ new_milestone = None
99+ changelog_file = None
100+ releasenotes_file = None
101+ if len(sys.argv) == 4:
102+ (project, version, tarball) = sys.argv[1:]
103+ elif len(sys.argv) == 5:
104+ (project, version, tarball, new_milestone) = sys.argv[1:]
105+ elif len(sys.argv) == 6:
106+ (project, version, tarball, new_milestone, changelog_file) = sys.argv[1:]
107+ elif len(sys.argv) == 7:
108+ (project, version, tarball, new_milestone, changelog_file, releasenotes_file) = sys.argv[1:]
109+
110+ launchpad = config.get_launchpd("project-upload")
111+
112+ try:
113+ # Look up the project using the Launchpad instance.
114+ proj = launchpad.projects[project]
115+ # Find the release in the project's releases collection.
116+ release = None
117+ for rel in proj.releases:
118+ if rel.version == version:
119+ release = rel
120+ break
121+ if not release:
122+ for milestone in proj.all_milestones:
123+ if milestone.name == version:
124+ today = datetime.date.today().strftime('%Y-%m-%d')
125+ release = milestone.createProductRelease(date_released=today)
126+ if not release:
127+ release = create_release(proj, version)
128+
129+ # Get the file contents.
130+ file_content = open(tarball, 'r').read()
131+ # Get the signature, if available.
132+ signature = tarball + '.asc'
133+ if not os.path.exists(signature):
134+ print 'Calling GPG to create tarball signature...'
135+ cmd = ['gpg', '--armor', '--sign', '--detach-sig', tarball]
136+ if subprocess.call(cmd) != 0:
137+ print >> sys.stderr, 'gpg failed, aborting'
138+
139+ if os.path.exists(signature):
140+ signature_content = open(signature, 'r').read()
141+ else:
142+ signature_content = None
143+
144+ # Create a new product release file.
145+ filename = os.path.basename(tarball)
146+ release.add_file(filename=filename, description='release tarball',
147+ file_content=file_content, content_type='appplication/x-gzip',
148+ file_type='Code Release Tarball', signature_filename=signature,
149+ signature_content=signature_content)
150+
151+ if changelog_file is not None:
152+ changelog = cat_file(changelog_file)
153+ else:
154+ changelog = edit_file('changelog', 'changelog')
155+ if changelog:
156+ release.changelog = changelog
157+
158+ if releasenotes_file is not None:
159+ release_notes = cat_file(releasenotes_file)
160+ else:
161+ release_notes = edit_file('releasenotes', 'release notes')
162+ if release_notes:
163+ release.release_notes = release_notes
164+
165+ release.lp_save()
166+
167+ # Create a new milestone if requested
168+ if new_milestone is not None:
169+ mil = release.milestone
170+ for series in proj.series:
171+ if mil.name in [milestone.name for milestone in series.all_milestones]:
172+ series.newMilestone(name=new_milestone)
173+
174+ except HTTPError, error:
175+ print 'An error happened in the upload:', error.content
176+ sys.exit(1)
177+
178+if __name__ == '__main__':
179+ main()

Subscribers

People subscribed via source and target branches