Update tox testing infrastructure.
Change-Id: I18967dde83bca38a1bfa9c85c7b2b21b28b415e3
This commit is contained in:
parent
b8b951060d
commit
029eddc0d8
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@
|
|||||||
local_settings.py
|
local_settings.py
|
||||||
keeper
|
keeper
|
||||||
build/*
|
build/*
|
||||||
|
ChangeLog
|
||||||
build-stamp
|
build-stamp
|
||||||
python_melangeclient.egg-info
|
python_melangeclient.egg-info
|
||||||
.tox
|
.tox
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
|
include ChangeLog
|
||||||
|
include openstack-common.conf
|
||||||
include README.rst
|
include README.rst
|
||||||
|
include tox.ini
|
||||||
include melange/client/views/*.tpl
|
include melange/client/views/*.tpl
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2011 OpenStack LLC.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import gettext
|
|
||||||
|
|
||||||
from melange.client.client import HTTPClient
|
|
||||||
from melange.client.client import AuthorizationClient
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE(jkoelker) should this be melange.client? Are translations going
|
|
||||||
# to be separate?
|
|
||||||
gettext.install('melange', unicode=1)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [HTTPClient,
|
|
||||||
AuthorizationClient]
|
|
0
melange/client/openstack/__init__.py
Normal file
0
melange/client/openstack/__init__.py
Normal file
0
melange/client/openstack/common/__init__.py
Normal file
0
melange/client/openstack/common/__init__.py
Normal file
121
melange/client/openstack/common/setup.py
Normal file
121
melange/client/openstack/common/setup.py
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Utilities with minimum-depends for use in setup.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def parse_mailmap(mailmap='.mailmap'):
|
||||||
|
mapping = {}
|
||||||
|
if os.path.exists(mailmap):
|
||||||
|
fp = open(mailmap, 'r')
|
||||||
|
for l in fp:
|
||||||
|
l = l.strip()
|
||||||
|
if not l.startswith('#') and ' ' in l:
|
||||||
|
canonical_email, alias = l.split(' ')
|
||||||
|
mapping[alias] = canonical_email
|
||||||
|
return mapping
|
||||||
|
|
||||||
|
|
||||||
|
def str_dict_replace(s, mapping):
|
||||||
|
for s1, s2 in mapping.iteritems():
|
||||||
|
s = s.replace(s1, s2)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
# Get requirements from the first file that exists
|
||||||
|
def get_reqs_from_files(requirements_files):
|
||||||
|
reqs_in = []
|
||||||
|
for requirements_file in requirements_files:
|
||||||
|
if os.path.exists(requirements_file):
|
||||||
|
return open(requirements_file, 'r').read().split('\n')
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def parse_requirements(requirements_files=['requirements.txt',
|
||||||
|
'tools/pip-requires']):
|
||||||
|
requirements = []
|
||||||
|
for line in get_reqs_from_files(requirements_files):
|
||||||
|
if re.match(r'\s*-e\s+', line):
|
||||||
|
requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1',
|
||||||
|
line))
|
||||||
|
elif re.match(r'\s*-f\s+', line):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
requirements.append(line)
|
||||||
|
|
||||||
|
return requirements
|
||||||
|
|
||||||
|
|
||||||
|
def parse_dependency_links(requirements_files=['requirements.txt',
|
||||||
|
'tools/pip-requires']):
|
||||||
|
dependency_links = []
|
||||||
|
for line in get_reqs_from_files(requirements_files):
|
||||||
|
if re.match(r'(\s*#)|(\s*$)', line):
|
||||||
|
continue
|
||||||
|
if re.match(r'\s*-[ef]\s+', line):
|
||||||
|
dependency_links.append(re.sub(r'\s*-[ef]\s+', '', line))
|
||||||
|
return dependency_links
|
||||||
|
|
||||||
|
|
||||||
|
def write_requirements():
|
||||||
|
venv = os.environ.get('VIRTUAL_ENV', None)
|
||||||
|
if venv is not None:
|
||||||
|
with open("requirements.txt", "w") as req_file:
|
||||||
|
output = subprocess.Popen(["pip", "-E", venv, "freeze", "-l"],
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
|
requirements = output.communicate()[0].strip()
|
||||||
|
req_file.write(requirements)
|
||||||
|
|
||||||
|
|
||||||
|
def run_git_command(cmd):
|
||||||
|
output = subprocess.Popen(["/bin/sh", "-c", cmd],
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
|
return output.communicate()[0].strip()
|
||||||
|
|
||||||
|
|
||||||
|
def write_vcsversion(location):
|
||||||
|
if os.path.isdir('.git'):
|
||||||
|
branch_nick_cmd = 'git branch | grep -Ei "\* (.*)" | cut -f2 -d" "'
|
||||||
|
branch_nick = run_git_command(branch_nick_cmd)
|
||||||
|
revid_cmd = "git --no-pager log --max-count=1 --pretty=oneline"
|
||||||
|
revid = run_git_command(revid_cmd).split()[0]
|
||||||
|
revno_cmd = "git --no-pager log --oneline | wc -l"
|
||||||
|
revno = run_git_command(revno_cmd)
|
||||||
|
with open(location, 'w') as version_file:
|
||||||
|
version_file.write("""
|
||||||
|
# This file is automatically generated by setup.py, So don't edit it. :)
|
||||||
|
version_info = {
|
||||||
|
'branch_nick': '%s',
|
||||||
|
'revision_id': '%s',
|
||||||
|
'revno': %s
|
||||||
|
}
|
||||||
|
""" % (branch_nick, revid, revno))
|
||||||
|
|
||||||
|
|
||||||
|
def write_git_changelog():
|
||||||
|
if os.path.isdir('.git'):
|
||||||
|
git_log_gnu = 'git log --format="%ai %aN %n%n%x09* %s%d%n"'
|
||||||
|
changelog = run_git_command(git_log_gnu)
|
||||||
|
mailmap = parse_mailmap()
|
||||||
|
with open("ChangeLog", "w") as changelog_file:
|
||||||
|
changelog_file.write(str_dict_replace(changelog, mailmap))
|
7
openstack-common.conf
Normal file
7
openstack-common.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
# The list of modules to copy from openstack-common
|
||||||
|
modules=setup
|
||||||
|
|
||||||
|
# The base module to hold the copy of openstack.common
|
||||||
|
base=melange.client
|
38
pylintrc
Normal file
38
pylintrc
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# The format of this file isn't really documented; just use --generate-rcfile
|
||||||
|
|
||||||
|
[Messages Control]
|
||||||
|
# NOTE(justinsb): We might want to have a 2nd strict pylintrc in future
|
||||||
|
# C0111: Don't require docstrings on every method
|
||||||
|
# W0511: TODOs in code comments are fine.
|
||||||
|
# W0142: *args and **kwargs are fine.
|
||||||
|
# W0622: Redefining id is fine.
|
||||||
|
disable=C0111,W0511,W0142,W0622
|
||||||
|
|
||||||
|
[Basic]
|
||||||
|
# Variable names can be 1 to 31 characters long, with lowercase and underscores
|
||||||
|
variable-rgx=[a-z_][a-z0-9_]{0,30}$
|
||||||
|
|
||||||
|
# Argument names can be 2 to 31 characters long, with lowercase and underscores
|
||||||
|
argument-rgx=[a-z_][a-z0-9_]{1,30}$
|
||||||
|
|
||||||
|
# Method names should be at least 3 characters long
|
||||||
|
# and be lowecased with underscores
|
||||||
|
method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$
|
||||||
|
|
||||||
|
# Module names matching melange-* are ok (files in bin/)
|
||||||
|
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(melange-[a-z0-9_-]+))$
|
||||||
|
|
||||||
|
# Don't require docstrings on tests.
|
||||||
|
no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$
|
||||||
|
|
||||||
|
[Design]
|
||||||
|
max-public-methods=100
|
||||||
|
min-public-methods=0
|
||||||
|
max-args=6
|
||||||
|
|
||||||
|
[Variables]
|
||||||
|
|
||||||
|
# List of additional names supposed to be defined in builtins. Remember that
|
||||||
|
# you should avoid to define new builtins when possible.
|
||||||
|
# _ is used by our localization
|
||||||
|
additional-builtins=_
|
@ -1,13 +1,6 @@
|
|||||||
[nosetests]
|
[nosetests]
|
||||||
verbosity=2
|
verbosity=2
|
||||||
detailed-errors=1
|
detailed-errors=1
|
||||||
with-tissue=1
|
|
||||||
tissue-repeat=1
|
|
||||||
tissue-show-pep8=1
|
|
||||||
tissue-show-source=1
|
|
||||||
tissue-inclusive=1
|
|
||||||
tissue-color=1
|
|
||||||
tissue-package=melange.client
|
|
||||||
with-openstack=1
|
with-openstack=1
|
||||||
openstack-red=0.1
|
openstack-red=0.1
|
||||||
openstack-yellow=0.075
|
openstack-yellow=0.075
|
||||||
|
23
setup.py
23
setup.py
@ -15,10 +15,23 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from melange.client.openstack.common.setup import parse_requirements
|
||||||
|
from melange.client.openstack.common.setup import parse_dependency_links
|
||||||
|
from melange.client.openstack.common.setup import write_requirements
|
||||||
|
from melange.client.openstack.common.setup import write_git_changelog
|
||||||
|
|
||||||
|
from setuptools.command.sdist import sdist
|
||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
version = "0.1"
|
version = "0.1"
|
||||||
install_requires = ["httplib2", "pyyaml"]
|
|
||||||
|
|
||||||
|
class local_sdist(sdist):
|
||||||
|
"""Customized sdist hook - builds the ChangeLog file from VC first"""
|
||||||
|
def run(self):
|
||||||
|
write_git_changelog()
|
||||||
|
sdist.run(self)
|
||||||
|
cmdclass = {'sdist': local_sdist}
|
||||||
|
|
||||||
if sys.version_info < (2, 6):
|
if sys.version_info < (2, 6):
|
||||||
install_requires.append("simplejson")
|
install_requires.append("simplejson")
|
||||||
@ -34,6 +47,8 @@ classifiers = ["Development Status :: 5 - Production/Stable",
|
|||||||
|
|
||||||
console_scripts = ["melange = melange.client.cli:main"]
|
console_scripts = ["melange = melange.client.cli:main"]
|
||||||
|
|
||||||
|
write_requirements()
|
||||||
|
|
||||||
|
|
||||||
def read_file(file_name):
|
def read_file(file_name):
|
||||||
return open(os.path.join(os.path.dirname(__file__),
|
return open(os.path.join(os.path.dirname(__file__),
|
||||||
@ -46,12 +61,14 @@ setuptools.setup(name="python-melangeclient",
|
|||||||
long_description=read_file("README.rst"),
|
long_description=read_file("README.rst"),
|
||||||
license="Apache License, Version 2.0",
|
license="Apache License, Version 2.0",
|
||||||
url="https://github.com/openstack/python-melangeclient",
|
url="https://github.com/openstack/python-melangeclient",
|
||||||
|
cmdclass=cmdclass,
|
||||||
classifiers=classifiers,
|
classifiers=classifiers,
|
||||||
author="Openstack Melange Team",
|
author="Openstack Melange Team",
|
||||||
author_email="openstack@lists.launchpad.net",
|
author_email="openstack@lists.launchpad.net",
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
packages=setuptools.find_packages(exclude=["tests"]),
|
packages=setuptools.find_packages(exclude=["tests"]),
|
||||||
install_requires=install_requires,
|
install_requires=parse_requirements(),
|
||||||
entry_points = {"console_scripts": console_scripts},
|
dependency_links=parse_dependency_links(),
|
||||||
|
entry_points={"console_scripts": console_scripts},
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
||||||
|
2
tools/pip-requires
Normal file
2
tools/pip-requires
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pyyaml
|
||||||
|
httplib2
|
10
tools/test-requires
Normal file
10
tools/test-requires
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Packages needed for dev testing
|
||||||
|
distribute>=0.6.24
|
||||||
|
|
||||||
|
coverage
|
||||||
|
mox
|
||||||
|
nose
|
||||||
|
nosexcover
|
||||||
|
openstack.nose_plugin
|
||||||
|
pep8
|
||||||
|
pylint
|
39
tox.ini
39
tox.ini
@ -1,9 +1,36 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py26,py27
|
envlist = py26,py27,pep8
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps= nose
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
mox
|
deps = -r{toxinidir}/tools/pip-requires
|
||||||
tissue
|
-r{toxinidir}/tools/test-requires
|
||||||
openstack.nose_plugin
|
commands = nosetests --where=melange/client/tests/unit
|
||||||
commands=nosetests []
|
|
||||||
|
[testenv:pep8]
|
||||||
|
deps = pep8
|
||||||
|
commands = pep8 --repeat --show-source melange setup.py
|
||||||
|
|
||||||
|
[testenv:pylint]
|
||||||
|
commands = pylint --rcfile=pylintrc --output-format=parseable melange
|
||||||
|
|
||||||
|
[testenv:cover]
|
||||||
|
commands = nosetests --where=melange/client/tests/unit --with-coverage --cover-html --cover-erase --cover-package=melange
|
||||||
|
|
||||||
|
[testenv:sdist]
|
||||||
|
commands = python setup.py sdist {posargs}
|
||||||
|
|
||||||
|
[testenv:hudson]
|
||||||
|
downloadcache = ~/cache/pip
|
||||||
|
|
||||||
|
[testenv:jenkins26]
|
||||||
|
basepython = python2.6
|
||||||
|
deps = file://{toxinidir}/.cache.bundle
|
||||||
|
|
||||||
|
[testenv:jenkins27]
|
||||||
|
basepython = python2.7
|
||||||
|
deps = file://{toxinidir}/.cache.bundle
|
||||||
|
|
||||||
|
[testenv:jenkinscover]
|
||||||
|
deps = file://{toxinidir}/.cache.bundle
|
||||||
|
commands = nosetests --cover-erase --cover-package=melange --with-xcoverage
|
||||||
|
Loading…
Reference in New Issue
Block a user