Skip to content

Commit def0f8a

Browse files
committed
Sync latest openstack-common updates.
Change-Id: I09adc9b5c01aa97ffba58dff8a696172e8654e3e
1 parent 8d64cc2 commit def0f8a

2 files changed

Lines changed: 88 additions & 127 deletions

File tree

‎openstackclient/openstack/common/setup.py‎

Lines changed: 84 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# vim: tabstop=4 shiftwidth=4 softtabstop=4
22

33
# Copyright 2011 OpenStack LLC.
4+
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
45
# All Rights Reserved.
56
#
67
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -19,7 +20,7 @@
1920
Utilities with minimum-depends for use in setup.py
2021
"""
2122

22-
import datetime
23+
import email
2324
import os
2425
import re
2526
import subprocess
@@ -33,20 +34,21 @@ def parse_mailmap(mailmap='.mailmap'):
3334
if os.path.exists(mailmap):
3435
with open(mailmap, 'r') as fp:
3536
for l in fp:
36-
l = l.strip()
37-
if not l.startswith('#') and ' ' in l:
38-
canonical_email, alias = [x for x in l.split(' ')
39-
if x.startswith('<')]
40-
mapping[alias] = canonical_email
37+
try:
38+
canonical_email, alias = re.match(
39+
r'[^#]*?(<.+>).*(<.+>).*', l).groups()
40+
except AttributeError:
41+
continue
42+
mapping[alias] = canonical_email
4143
return mapping
4244

4345

4446
def canonicalize_emails(changelog, mapping):
4547
"""Takes in a string and an email alias mapping and replaces all
4648
instances of the aliases in the string with their real email.
4749
"""
48-
for alias, email in mapping.iteritems():
49-
changelog = changelog.replace(alias, email)
50+
for alias, email_address in mapping.iteritems():
51+
changelog = changelog.replace(alias, email_address)
5052
return changelog
5153

5254

@@ -78,6 +80,10 @@ def parse_requirements(requirements_files=['requirements.txt',
7880
# -f lines are for index locations, and don't get used here
7981
elif re.match(r'\s*-f\s+', line):
8082
pass
83+
# argparse is part of the standard library starting with 2.7
84+
# adding it to the requirements list screws distro installs
85+
elif line == 'argparse' and sys.version_info >= (2, 7):
86+
pass
8187
else:
8288
requirements.append(line)
8389

@@ -102,23 +108,17 @@ def parse_dependency_links(requirements_files=['requirements.txt',
102108
return dependency_links
103109

104110

105-
def write_requirements():
106-
venv = os.environ.get('VIRTUAL_ENV', None)
107-
if venv is not None:
108-
with open("requirements.txt", "w") as req_file:
109-
output = subprocess.Popen(["pip", "-E", venv, "freeze", "-l"],
110-
stdout=subprocess.PIPE)
111-
requirements = output.communicate()[0].strip()
112-
req_file.write(requirements)
113-
114-
115-
def _run_shell_command(cmd):
111+
def _run_shell_command(cmd, throw_on_error=False):
116112
if os.name == 'nt':
117113
output = subprocess.Popen(["cmd.exe", "/C", cmd],
118-
stdout=subprocess.PIPE)
114+
stdout=subprocess.PIPE,
115+
stderr=subprocess.PIPE)
119116
else:
120117
output = subprocess.Popen(["/bin/sh", "-c", cmd],
121-
stdout=subprocess.PIPE)
118+
stdout=subprocess.PIPE,
119+
stderr=subprocess.PIPE)
120+
if output.returncode and throw_on_error:
121+
raise Exception("%s returned %d" % cmd, output.returncode)
122122
out = output.communicate()
123123
if len(out) == 0:
124124
return None
@@ -127,57 +127,6 @@ def _run_shell_command(cmd):
127127
return out[0].strip()
128128

129129

130-
def _get_git_next_version_suffix(branch_name):
131-
datestamp = datetime.datetime.now().strftime('%Y%m%d')
132-
if branch_name == 'milestone-proposed':
133-
revno_prefix = "r"
134-
else:
135-
revno_prefix = ""
136-
_run_shell_command("git fetch origin +refs/meta/*:refs/remotes/meta/*")
137-
milestone_cmd = "git show meta/openstack/release:%s" % branch_name
138-
milestonever = _run_shell_command(milestone_cmd)
139-
if milestonever:
140-
first_half = "%s~%s" % (milestonever, datestamp)
141-
else:
142-
first_half = datestamp
143-
144-
post_version = _get_git_post_version()
145-
# post version should look like:
146-
# 0.1.1.4.gcc9e28a
147-
# where the bit after the last . is the short sha, and the bit between
148-
# the last and second to last is the revno count
149-
(revno, sha) = post_version.split(".")[-2:]
150-
second_half = "%s%s.%s" % (revno_prefix, revno, sha)
151-
return ".".join((first_half, second_half))
152-
153-
154-
def _get_git_current_tag():
155-
return _run_shell_command("git tag --contains HEAD")
156-
157-
158-
def _get_git_tag_info():
159-
return _run_shell_command("git describe --tags")
160-
161-
162-
def _get_git_post_version():
163-
current_tag = _get_git_current_tag()
164-
if current_tag is not None:
165-
return current_tag
166-
else:
167-
tag_info = _get_git_tag_info()
168-
if tag_info is None:
169-
base_version = "0.0"
170-
cmd = "git --no-pager log --oneline"
171-
out = _run_shell_command(cmd)
172-
revno = len(out.split("\n"))
173-
sha = _run_shell_command("git describe --always")
174-
else:
175-
tag_infos = tag_info.split("-")
176-
base_version = "-".join(tag_infos[:-2])
177-
(revno, sha) = tag_infos[-2:]
178-
return "%s.%s.%s" % (base_version, revno, sha)
179-
180-
181130
def write_git_changelog():
182131
"""Write a changelog based on the git changelog."""
183132
new_changelog = 'ChangeLog'
@@ -223,26 +172,6 @@ def generate_authors():
223172
"""
224173

225174

226-
def read_versioninfo(project):
227-
"""Read the versioninfo file. If it doesn't exist, we're in a github
228-
zipball, and there's really no way to know what version we really
229-
are, but that should be ok, because the utility of that should be
230-
just about nil if this code path is in use in the first place."""
231-
versioninfo_path = os.path.join(project, 'versioninfo')
232-
if os.path.exists(versioninfo_path):
233-
with open(versioninfo_path, 'r') as vinfo:
234-
version = vinfo.read().strip()
235-
else:
236-
version = "0.0.0"
237-
return version
238-
239-
240-
def write_versioninfo(project, version):
241-
"""Write a simple file containing the version of the package."""
242-
with open(os.path.join(project, 'versioninfo'), 'w') as fil:
243-
fil.write("%s\n" % version)
244-
245-
246175
def get_cmdclass():
247176
"""Return dict of commands to run from setup.py."""
248177

@@ -272,6 +201,9 @@ def run(self):
272201
from sphinx.setup_command import BuildDoc
273202

274203
class LocalBuildDoc(BuildDoc):
204+
205+
builders = ['html', 'man']
206+
275207
def generate_autoindex(self):
276208
print "**Autodocumenting from %s" % os.path.abspath(os.curdir)
277209
modules = {}
@@ -307,56 +239,83 @@ def run(self):
307239
if not os.getenv('SPHINX_DEBUG'):
308240
self.generate_autoindex()
309241

310-
for builder in ['html', 'man']:
242+
for builder in self.builders:
311243
self.builder = builder
312244
self.finalize_options()
313245
self.project = self.distribution.get_name()
314246
self.version = self.distribution.get_version()
315247
self.release = self.distribution.get_version()
316248
BuildDoc.run(self)
249+
250+
class LocalBuildLatex(LocalBuildDoc):
251+
builders = ['latex']
252+
317253
cmdclass['build_sphinx'] = LocalBuildDoc
254+
cmdclass['build_sphinx_latex'] = LocalBuildLatex
318255
except ImportError:
319256
pass
320257

321258
return cmdclass
322259

323260

324-
def get_git_branchname():
325-
for branch in _run_shell_command("git branch --color=never").split("\n"):
326-
if branch.startswith('*'):
327-
_branch_name = branch.split()[1].strip()
328-
if _branch_name == "(no":
329-
_branch_name = "no-branch"
330-
return _branch_name
331-
261+
def get_version_from_git(pre_version):
262+
"""Return a version which is equal to the tag that's on the current
263+
revision if there is one, or tag plus number of additional revisions
264+
if the current revision has no tag."""
332265

333-
def get_pre_version(projectname, base_version):
334-
"""Return a version which is leading up to a version that will
335-
be released in the future."""
336266
if os.path.isdir('.git'):
337-
current_tag = _get_git_current_tag()
338-
if current_tag is not None:
339-
version = current_tag
267+
if pre_version:
268+
try:
269+
return _run_shell_command(
270+
"git describe --exact-match",
271+
throw_on_error=True).replace('-', '.')
272+
except Exception:
273+
sha = _run_shell_command("git log -n1 --pretty=format:%h")
274+
describe = _run_shell_command("git describe --always")
275+
revno = describe.rsplit("-", 2)[-2]
276+
return "%s.a%s.g%s" % (pre_version, revno, sha)
340277
else:
341-
branch_name = os.getenv('BRANCHNAME',
342-
os.getenv('GERRIT_REFNAME',
343-
get_git_branchname()))
344-
version_suffix = _get_git_next_version_suffix(branch_name)
345-
version = "%s~%s" % (base_version, version_suffix)
346-
write_versioninfo(projectname, version)
347-
return version
348-
else:
349-
version = read_versioninfo(projectname)
350-
return version
278+
return _run_shell_command(
279+
"git describe --always").replace('-', '.')
280+
return None
351281

352282

353-
def get_post_version(projectname):
354-
"""Return a version which is equal to the tag that's on the current
355-
revision if there is one, or tag plus number of additional revisions
356-
if the current revision has no tag."""
283+
def get_version_from_pkg_info(package_name):
284+
"""Get the version from PKG-INFO file if we can."""
285+
try:
286+
pkg_info_file = open('PKG-INFO', 'r')
287+
except (IOError, OSError):
288+
return None
289+
try:
290+
pkg_info = email.message_from_file(pkg_info_file)
291+
except email.MessageError:
292+
return None
293+
# Check to make sure we're in our own dir
294+
if pkg_info.get('Name', None) != package_name:
295+
return None
296+
return pkg_info.get('Version', None)
357297

358-
if os.path.isdir('.git'):
359-
version = _get_git_post_version()
360-
write_versioninfo(projectname, version)
298+
299+
def get_version(package_name, pre_version=None):
300+
"""Get the version of the project. First, try getting it from PKG-INFO, if
301+
it exists. If it does, that means we're in a distribution tarball or that
302+
install has happened. Otherwise, if there is no PKG-INFO file, pull the
303+
version from git.
304+
305+
We do not support setup.py version sanity in git archive tarballs, nor do
306+
we support packagers directly sucking our git repo into theirs. We expect
307+
that a source tarball be made from our git repo - or that if someone wants
308+
to make a source tarball from a fork of our repo with additional tags in it
309+
that they understand and desire the results of doing that.
310+
"""
311+
version = os.environ.get("OSLO_PACKAGE_VERSION", None)
312+
if version:
313+
return version
314+
version = get_version_from_pkg_info(package_name)
315+
if version:
316+
return version
317+
version = get_version_from_git(pre_version)
318+
if version:
361319
return version
362-
return read_versioninfo(projectname)
320+
raise Exception("Versioning for this project requires either an sdist"
321+
" tarball, or access to an upstream git repository.")

‎setup.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,18 @@
2222
from openstackclient.openstack.common import setup
2323

2424

25+
project = "python-openstackclient"
2526
requires = setup.parse_requirements()
2627
dependency_links = setup.parse_dependency_links()
2728

2829

2930
def read(fname):
3031
return open(os.path.join(os.path.dirname(__file__), fname)).read()
3132

33+
3234
setuptools.setup(
33-
name="python-openstackclient",
34-
version=setup.get_post_version('openstackclient'),
35+
name=project,
36+
version=setup.get_version(project),
3537
description="OpenStack command-line client",
3638
long_description=read('README.rst'),
3739
url='https://github.com/openstack/python-openstackclient',

0 commit comments

Comments
 (0)