93
118
def _run_shell_command(cmd):
94
119
output = subprocess.Popen(["/bin/sh", "-c", cmd],
95
120
stdout=subprocess.PIPE)
96
return output.communicate()[0].strip()
99
def write_vcsversion(location):
100
"""Produce a vcsversion dict that mimics the old one produced by bzr.
102
if os.path.isdir('.git'):
103
branch_nick_cmd = 'git branch | grep -Ei "\* (.*)" | cut -f2 -d" "'
104
branch_nick = _run_shell_command(branch_nick_cmd)
105
revid_cmd = "git rev-parse HEAD"
106
revid = _run_shell_command(revid_cmd).split()[0]
107
revno_cmd = "git log --oneline | wc -l"
108
revno = _run_shell_command(revno_cmd)
109
with open(location, 'w') as version_file:
110
version_file.write("""
111
# This file is automatically generated by setup.py, So don't edit it. :)
117
""" % (branch_nick, revid, revno))
121
out = output.communicate()
124
if len(out[0].strip()) == 0:
126
return out[0].strip()
129
def _get_git_next_version_suffix(branch_name):
130
datestamp = datetime.datetime.now().strftime('%Y%m%d')
131
if branch_name == 'milestone-proposed':
135
_run_shell_command("git fetch origin +refs/meta/*:refs/remotes/meta/*")
136
milestone_cmd = "git show meta/openstack/release:%s" % branch_name
137
milestonever = _run_shell_command(milestone_cmd)
140
post_version = _get_git_post_version()
141
# post version should look like:
143
# where the bit after the last . is the short sha, and the bit between
144
# the last and second to last is the revno count
145
(revno, sha) = post_version.split(".")[-2:]
146
first_half = "%s~%s" % (milestonever, datestamp)
147
second_half = "%s%s.%s" % (revno_prefix, revno, sha)
148
return ".".join((first_half, second_half))
151
def _get_git_current_tag():
152
return _run_shell_command("git tag --contains HEAD")
155
def _get_git_tag_info():
156
return _run_shell_command("git describe --tags")
159
def _get_git_post_version():
160
current_tag = _get_git_current_tag()
161
if current_tag is not None:
164
tag_info = _get_git_tag_info()
167
cmd = "git --no-pager log --oneline"
168
out = _run_shell_command(cmd)
169
revno = len(out.split("\n"))
170
sha = _run_shell_command("git describe --always")
172
tag_infos = tag_info.split("-")
173
base_version = "-".join(tag_infos[:-2])
174
(revno, sha) = tag_infos[-2:]
175
return "%s.%s.%s" % (base_version, revno, sha)
120
178
def write_git_changelog():
121
179
"""Write a changelog based on the git changelog."""
122
if os.path.isdir('.git'):
123
git_log_cmd = 'git log --stat'
124
changelog = _run_shell_command(git_log_cmd)
125
mailmap = parse_mailmap()
126
with open("ChangeLog", "w") as changelog_file:
127
changelog_file.write(canonicalize_emails(changelog, mailmap))
180
new_changelog = 'ChangeLog'
181
if not os.getenv('SKIP_WRITE_GIT_CHANGELOG'):
182
if os.path.isdir('.git'):
183
git_log_cmd = 'git log --stat'
184
changelog = _run_shell_command(git_log_cmd)
185
mailmap = parse_mailmap()
186
with open(new_changelog, "w") as changelog_file:
187
changelog_file.write(canonicalize_emails(changelog, mailmap))
189
open(new_changelog, 'w').close()
130
192
def generate_authors():
132
194
jenkins_email = 'jenkins@review.openstack.org'
133
195
old_authors = 'AUTHORS.in'
134
196
new_authors = 'AUTHORS'
135
if os.path.isdir('.git'):
136
# don't include jenkins email address in AUTHORS file
137
git_log_cmd = "git log --format='%aN <%aE>' | sort -u | " \
138
"grep -v " + jenkins_email
139
changelog = _run_shell_command(git_log_cmd)
140
mailmap = parse_mailmap()
141
with open(new_authors, 'w') as new_authors_fh:
142
new_authors_fh.write(canonicalize_emails(changelog, mailmap))
143
if os.path.exists(old_authors):
144
with open(old_authors, "r") as old_authors_fh:
145
new_authors_fh.write('\n' + old_authors_fh.read())
197
if not os.getenv('SKIP_GENERATE_AUTHORS'):
198
if os.path.isdir('.git'):
199
# don't include jenkins email address in AUTHORS file
200
git_log_cmd = ("git log --format='%aN <%aE>' | sort -u | "
201
"grep -v " + jenkins_email)
202
changelog = _run_shell_command(git_log_cmd)
203
mailmap = parse_mailmap()
204
with open(new_authors, 'w') as new_authors_fh:
205
new_authors_fh.write(canonicalize_emails(changelog, mailmap))
206
if os.path.exists(old_authors):
207
with open(old_authors, "r") as old_authors_fh:
208
new_authors_fh.write('\n' + old_authors_fh.read())
210
open(new_authors, 'w').close()
213
_rst_template = """%(heading)s
216
.. automodule:: %(module)s
223
def read_versioninfo(project):
224
"""Read the versioninfo file. If it doesn't exist, we're in a github
225
zipball, and there's really no way to know what version we really
226
are, but that should be ok, because the utility of that should be
227
just about nil if this code path is in use in the first place."""
228
versioninfo_path = os.path.join(project, 'versioninfo')
229
if os.path.exists(versioninfo_path):
230
with open(versioninfo_path, 'r') as vinfo:
231
version = vinfo.read().strip()
237
def write_versioninfo(project, version):
238
"""Write a simple file containing the version of the package."""
239
open(os.path.join(project, 'versioninfo'), 'w').write("%s\n" % version)
243
"""Return dict of commands to run from setup.py."""
247
def _find_modules(arg, dirname, files):
248
for filename in files:
249
if filename.endswith('.py') and filename != '__init__.py':
250
arg["%s.%s" % (dirname.replace('/', '.'),
251
filename[:-3])] = True
253
class LocalSDist(sdist.sdist):
254
"""Builds the ChangeLog and Authors files from VC first."""
257
write_git_changelog()
259
# sdist.sdist is an old style class, can't use super()
260
sdist.sdist.run(self)
262
cmdclass['sdist'] = LocalSDist
264
# If Sphinx is installed on the box running setup.py,
265
# enable setup.py to build the documentation, otherwise,
268
from sphinx.setup_command import BuildDoc
270
class LocalBuildDoc(BuildDoc):
271
def generate_autoindex(self):
272
print "**Autodocumenting from %s" % os.path.abspath(os.curdir)
274
option_dict = self.distribution.get_option_dict('build_sphinx')
275
source_dir = os.path.join(option_dict['source_dir'][1], 'api')
276
if not os.path.exists(source_dir):
277
os.makedirs(source_dir)
278
for pkg in self.distribution.packages:
280
os.path.walk(pkg, _find_modules, modules)
281
module_list = modules.keys()
283
autoindex_filename = os.path.join(source_dir, 'autoindex.rst')
284
with open(autoindex_filename, 'w') as autoindex:
285
autoindex.write(""".. toctree::
289
for module in module_list:
290
output_filename = os.path.join(source_dir,
292
heading = "The :mod:`%s` Module" % module
293
underline = "=" * len(heading)
294
values = dict(module=module, heading=heading,
297
print "Generating %s" % output_filename
298
with open(output_filename, 'w') as output_file:
299
output_file.write(_rst_template % values)
300
autoindex.write(" %s.rst\n" % module)
303
if not os.getenv('SPHINX_DEBUG'):
304
self.generate_autoindex()
306
for builder in ['html', 'man']:
307
self.builder = builder
308
self.finalize_options()
309
self.project = self.distribution.get_name()
310
self.version = self.distribution.get_version()
311
self.release = self.distribution.get_version()
313
cmdclass['build_sphinx'] = LocalBuildDoc
320
def get_git_branchname():
321
for branch in _run_shell_command("git branch --color=never").split("\n"):
322
if branch.startswith('*'):
323
_branch_name = branch.split()[1].strip()
324
if _branch_name == "(no":
325
_branch_name = "no-branch"
329
def get_pre_version(projectname, base_version):
330
"""Return a version which is leading up to a version that will
331
be released in the future."""
332
if os.path.isdir('.git'):
333
current_tag = _get_git_current_tag()
334
if current_tag is not None:
335
version = current_tag
337
branch_name = os.getenv('BRANCHNAME',
338
os.getenv('GERRIT_REFNAME',
339
get_git_branchname()))
340
version_suffix = _get_git_next_version_suffix(branch_name)
341
version = "%s~%s" % (base_version, version_suffix)
342
write_versioninfo(projectname, version)
345
version = read_versioninfo(projectname)
349
def get_post_version(projectname):
350
"""Return a version which is equal to the tag that's on the current
351
revision if there is one, or tag plus number of additional revisions
352
if the current revision has no tag."""
354
if os.path.isdir('.git'):
355
version = _get_git_post_version()
356
write_versioninfo(projectname, version)
358
return read_versioninfo(projectname)