Skip to content

Commit 7df0123

Browse files
committed
Add openstack project infrastructure.
1 parent a42892c commit 7df0123

13 files changed

+281
-30
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
AUTHORS
2+
ChangeLog
3+
dist/
4+
.tox
15
*.egg-info
26
*.py[co]
37
.DS_Store

.gitreview

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[gerrit]
2+
host=review.openstack.org
3+
port=29418
4+
project=openstack/python-swiftclient.git

AUTHORS

-19
This file was deleted.

CHANGELOG

-4
This file was deleted.

MANIFEST.in

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
include README.rst
1+
include AUTHORS
2+
include ChangeLog
23
include LICENSE
4+
include README.rst
35
recursive-include tests *

openstack-common.conf

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[DEFAULT]
2+
3+
# The list of modules to copy from openstack-common
4+
modules=setup
5+
6+
# The base module to hold the copy of openstack.common
7+
base=swiftclient

setup.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,51 @@
1+
#!/usr/bin/python
12
# -*- encoding: utf-8 -*-
3+
# Copyright (c) 2010 OpenStack, LLC.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14+
# implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
218
import os
319
import setuptools
420
import sys
521

6-
# TODO: Figuring out how we are going to do the versionning (and if
22+
from swiftclient.openstack.common import setup
23+
24+
# TODO: Figuring out how we are going to do the versioning (and if
725
# any).
826
version = '1.0'
927
name = 'python-swiftclient'
10-
requires = []
28+
29+
requires = setup.parse_requirements()
30+
depend_links = setup.parse_dependency_links()
1131

1232

1333
def read(fname):
1434
return open(os.path.join(os.path.dirname(__file__), fname)).read()
1535

16-
if sys.version_info < (2, 6):
17-
requires.append('simplejson')
18-
1936
setuptools.setup(
2037
name=name,
2138
version=version,
2239
description='Client Library for OpenStack Object Storage API',
2340
long_description=read('README.rst'),
24-
url='https://github.com/chmouel/python-swiftclient',
41+
url='https://github.com/openstack/python-swiftclient',
2542
license='Apache License (2.0)',
2643
author='OpenStack, LLC.',
2744
author_email='[email protected]',
2845
packages=setuptools.find_packages(exclude=['tests', 'tests.*']),
46+
cmdclass=setup.get_cmdclass(),
2947
install_requires=requires,
48+
dependency_links=depend_links,
3049
classifiers=[
3150
'Development Status :: 4 - Beta',
3251
'Environment :: Console',

swiftclient/openstack/__init__.py

Whitespace-only changes.

swiftclient/openstack/common/__init__.py

Whitespace-only changes.

swiftclient/openstack/common/setup.py

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2+
3+
# Copyright 2011 OpenStack LLC.
4+
# All Rights Reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7+
# not use this file except in compliance with the License. You may obtain
8+
# a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
# License for the specific language governing permissions and limitations
16+
# under the License.
17+
18+
"""
19+
Utilities with minimum-depends for use in setup.py
20+
"""
21+
22+
import os
23+
import re
24+
import subprocess
25+
26+
from setuptools.command import sdist
27+
28+
29+
def parse_mailmap(mailmap='.mailmap'):
30+
mapping = {}
31+
if os.path.exists(mailmap):
32+
fp = open(mailmap, 'r')
33+
for l in fp:
34+
l = l.strip()
35+
if not l.startswith('#') and ' ' in l:
36+
canonical_email, alias = [x for x in l.split(' ') \
37+
if x.startswith('<')]
38+
mapping[alias] = canonical_email
39+
return mapping
40+
41+
42+
def canonicalize_emails(changelog, mapping):
43+
"""Takes in a string and an email alias mapping and replaces all
44+
instances of the aliases in the string with their real email.
45+
"""
46+
for alias, email in mapping.iteritems():
47+
changelog = changelog.replace(alias, email)
48+
return changelog
49+
50+
51+
# Get requirements from the first file that exists
52+
def get_reqs_from_files(requirements_files):
53+
reqs_in = []
54+
for requirements_file in requirements_files:
55+
if os.path.exists(requirements_file):
56+
return open(requirements_file, 'r').read().split('\n')
57+
return []
58+
59+
60+
def parse_requirements(requirements_files=['requirements.txt',
61+
'tools/pip-requires']):
62+
requirements = []
63+
for line in get_reqs_from_files(requirements_files):
64+
if re.match(r'\s*-e\s+', line):
65+
requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1',
66+
line))
67+
elif re.match(r'\s*-f\s+', line):
68+
pass
69+
else:
70+
requirements.append(line)
71+
72+
return requirements
73+
74+
75+
def parse_dependency_links(requirements_files=['requirements.txt',
76+
'tools/pip-requires']):
77+
dependency_links = []
78+
for line in get_reqs_from_files(requirements_files):
79+
if re.match(r'(\s*#)|(\s*$)', line):
80+
continue
81+
if re.match(r'\s*-[ef]\s+', line):
82+
dependency_links.append(re.sub(r'\s*-[ef]\s+', '', line))
83+
return dependency_links
84+
85+
86+
def write_requirements():
87+
venv = os.environ.get('VIRTUAL_ENV', None)
88+
if venv is not None:
89+
with open("requirements.txt", "w") as req_file:
90+
output = subprocess.Popen(["pip", "-E", venv, "freeze", "-l"],
91+
stdout=subprocess.PIPE)
92+
requirements = output.communicate()[0].strip()
93+
req_file.write(requirements)
94+
95+
96+
def _run_shell_command(cmd):
97+
output = subprocess.Popen(["/bin/sh", "-c", cmd],
98+
stdout=subprocess.PIPE)
99+
return output.communicate()[0].strip()
100+
101+
102+
def write_vcsversion(location):
103+
"""Produce a vcsversion dict that mimics the old one produced by bzr.
104+
"""
105+
if os.path.isdir('.git'):
106+
branch_nick_cmd = 'git branch | grep -Ei "\* (.*)" | cut -f2 -d" "'
107+
branch_nick = _run_shell_command(branch_nick_cmd)
108+
revid_cmd = "git rev-parse HEAD"
109+
revid = _run_shell_command(revid_cmd).split()[0]
110+
revno_cmd = "git log --oneline | wc -l"
111+
revno = _run_shell_command(revno_cmd)
112+
with open(location, 'w') as version_file:
113+
version_file.write("""
114+
# This file is automatically generated by setup.py, So don't edit it. :)
115+
version_info = {
116+
'branch_nick': '%s',
117+
'revision_id': '%s',
118+
'revno': %s
119+
}
120+
""" % (branch_nick, revid, revno))
121+
122+
123+
def write_git_changelog():
124+
"""Write a changelog based on the git changelog."""
125+
if os.path.isdir('.git'):
126+
git_log_cmd = 'git log --stat'
127+
changelog = _run_shell_command(git_log_cmd)
128+
mailmap = parse_mailmap()
129+
with open("ChangeLog", "w") as changelog_file:
130+
changelog_file.write(canonicalize_emails(changelog, mailmap))
131+
132+
133+
def generate_authors():
134+
"""Create AUTHORS file using git commits."""
135+
jenkins_email = '[email protected]'
136+
old_authors = 'AUTHORS.in'
137+
new_authors = 'AUTHORS'
138+
if os.path.isdir('.git'):
139+
# don't include jenkins email address in AUTHORS file
140+
git_log_cmd = "git log --format='%aN <%aE>' | sort -u | " \
141+
"grep -v " + jenkins_email
142+
changelog = _run_shell_command(git_log_cmd)
143+
mailmap = parse_mailmap()
144+
with open(new_authors, 'w') as new_authors_fh:
145+
new_authors_fh.write(canonicalize_emails(changelog, mailmap))
146+
if os.path.exists(old_authors):
147+
with open(old_authors, "r") as old_authors_fh:
148+
new_authors_fh.write('\n' + old_authors_fh.read())
149+
150+
151+
def get_cmdclass():
152+
"""Return dict of commands to run from setup.py."""
153+
154+
cmdclass = dict()
155+
156+
class LocalSDist(sdist.sdist):
157+
"""Builds the ChangeLog and Authors files from VC first."""
158+
159+
def run(self):
160+
write_git_changelog()
161+
generate_authors()
162+
# sdist.sdist is an old style class, can't use super()
163+
sdist.sdist.run(self)
164+
165+
cmdclass['sdist'] = LocalSDist
166+
167+
# If Sphinx is installed on the box running setup.py,
168+
# enable setup.py to build the documentation, otherwise,
169+
# just ignore it
170+
try:
171+
from sphinx.setup_command import BuildDoc
172+
173+
class LocalBuildDoc(BuildDoc):
174+
def run(self):
175+
for builder in ['html', 'man']:
176+
self.builder = builder
177+
self.finalize_options()
178+
BuildDoc.run(self)
179+
cmdclass['build_sphinx'] = LocalBuildDoc
180+
except ImportError:
181+
pass
182+
183+
return cmdclass

tools/pip-requires

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
simplejson

tools/test-requires

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
distribute>=0.6.24
2+
3+
nose
4+
nose-exclude
5+
nosexcover
6+
openstack.nose_plugin
7+
pep8>=1.0
8+
sphinx>=1.1.2

tox.ini

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[tox]
2+
envlist = py26,py27,pep8
3+
4+
[testenv]
5+
setenv = VIRTUAL_ENV={envdir}
6+
NOSE_WITH_OPENSTACK=1
7+
NOSE_OPENSTACK_COLOR=1
8+
NOSE_OPENSTACK_RED=0.05
9+
NOSE_OPENSTACK_YELLOW=0.025
10+
NOSE_OPENSTACK_SHOW_ELAPSED=1
11+
deps = -r{toxinidir}/tools/pip-requires
12+
-r{toxinidir}/tools/test-requires
13+
commands = nosetests
14+
15+
[testenv:pep8]
16+
deps = pep8
17+
commands = pep8 --repeat --show-source swiftclient setup.py
18+
19+
[testenv:venv]
20+
commands = {posargs}
21+
22+
[testenv:cover]
23+
commands = nosetests --cover-erase --cover-package=swiftclient --with-xcoverage
24+
25+
[tox:jenkins]
26+
downloadcache = ~/cache/pip
27+
28+
[testenv:jenkins26]
29+
basepython = python2.6
30+
setenv = NOSE_WITH_XUNIT=1
31+
deps = file://{toxinidir}/.cache.bundle
32+
33+
[testenv:jenkins27]
34+
basepython = python2.7
35+
setenv = NOSE_WITH_XUNIT=1
36+
deps = file://{toxinidir}/.cache.bundle
37+
38+
[testenv:jenkinscover]
39+
deps = file://{toxinidir}/.cache.bundle
40+
setenv = NOSE_WITH_XUNIT=1
41+
commands = nosetests --cover-erase --cover-package=swiftclient --with-xcoverage
42+
43+
[testenv:jenkinsvenv]
44+
deps = file://{toxinidir}/.cache.bundle
45+
setenv = NOSE_WITH_XUNIT=1
46+
commands = {posargs}

0 commit comments

Comments
 (0)