1
"""distutils.command.upload
3
Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
6
from distutils.errors import DistutilsOptionError
7
from distutils.spawn import spawn
14
from lpdistutils import LPCommand
17
class lpupload(LPCommand):
19
description = "upload files to Launchpad"
20
user_options = LPCommand.user_options + [
22
'sign files to upload using gpg'),
23
('identity=', 'i', 'GPG identity used to sign files'),
25
boolean_options = LPCommand.boolean_options + ['sign']
27
def initialize_options(self):
28
LPCommand.initialize_options(self)
32
def finalize_options(self):
33
LPCommand.finalize_options(self)
34
if self.identity and not self.sign:
35
raise DistutilsOptionError(
36
"Must use --sign for --identity to have meaning"
40
if not self.distribution.dist_files:
41
raise DistutilsOptionError("No dist file created in earlier command")
42
for command, pyversion, filename in self.distribution.dist_files:
43
self.upload_file(command, pyversion, filename)
45
def create_release(self, project, version):
46
print "Release %s could not be found for project. Create it? (Y/n)" % version
47
answer = sys.stdin.readline().strip().lower()
48
if not answer.startswith('y'):
51
if len(project.series) != 1:
54
for s in project.series:
55
for m in s.all_milestones:
64
print "Select a series to upload to:"
65
for i, series in enumerate(project.series):
66
print "%d: %s" % (i+1, series.name)
67
answer = int(sys.stdin.readline().strip())
68
if answer < 1 or answer > len(series):
70
series = project.series[answer-1]
72
series = project.series[0]
74
release_date = datetime.date.today().strftime('%Y-%m-%d')
76
milestone = series.newMilestone(name=version,
77
date_targeted=release_date)
78
return milestone.createProductRelease(date_released=release_date)
80
def edit_file(self, prefix, description):
81
(fd, f) = tempfile.mkstemp(prefix=prefix+'.')
82
os.write(fd, '\n\n#------\n# Please enter the %s here. Lines which start with "#" are ignored.\n' %
85
subprocess.call(['sensible-editor', f])
92
return content.strip()
94
def upload_file(self, command, pyversion, filename):
97
gpg_args = ["gpg", "--detach-sign", "-a", filename]
99
gpg_args[2:2] = ["--local-user", self.identity]
103
f = open(filename,'rb')
106
basename = os.path.basename(filename)
107
description = command + " (%s)" % str(pyversion)
108
if command=='bdist_egg' and self.distribution.has_ext_modules():
109
description += " (built on %s)" % platform.platform(terse=1)
110
if command == 'bdist_rpm':
111
dist, version, id = platform.dist()
113
description += ' (built for %s %s)' % (dist, version)
114
elif command == 'bdist_dumb':
115
description += ' (built for %s)' % platform.platform(terse=1)
117
lpinfo = self.get_lpinfo()
118
name = lpinfo.get_name()
120
name = self.distribution.get_name()
121
version = self.distribution.metadata.version
125
project = lp.projects[name]
127
raise KeyError("Project %s not found." % name)
130
for rel in project.releases:
131
if rel.version == version:
135
release = self.create_release(project, version)
138
sig_filename = filename + ".asc"
140
kwargs["signature_filename"] = os.path.basename(sig_filename)
141
kwargs["signature_content"] = open(sig_filename).read()
143
release.add_file(filename=basename, description=description,
144
file_content=content, file_type="Code Release Tarball",
145
content_type='application/x-gzip', **kwargs)
147
changelog = self.edit_file('changelog', 'changelog')
149
release.changelog = changelog
150
release_notes = self.edit_file('releasenotes', 'release notes')
152
release.release_notes = release_notes