diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000..1357730488 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,6 @@ +[run] +branch = True +omit = /usr*,setup.py,*egg*,.venv/*,.tox/*,quantum/tests/* + +[report] +ignore-errors = True diff --git a/quantum/openstack/common/setup.py b/quantum/openstack/common/setup.py index 16e53b98bf..79b5a62bca 100644 --- a/quantum/openstack/common/setup.py +++ b/quantum/openstack/common/setup.py @@ -23,6 +23,8 @@ import os import re import subprocess +from setuptools.command import sdist + def parse_mailmap(mailmap='.mailmap'): mapping = {} @@ -59,9 +61,19 @@ def parse_requirements(requirements_files=['requirements.txt', 'tools/pip-requires']): requirements = [] for line in get_reqs_from_files(requirements_files): + # For the requirements list, we need to inject only the portion + # after egg= so that distutils knows the package it's looking for + # such as: + # -e git://github.com/openstack/nova/master#egg=nova if re.match(r'\s*-e\s+', line): requirements.append(re.sub(r'\s*-e\s+.*#egg=(.*)$', r'\1', line)) + # such as: + # http://github.com/openstack/nova/zipball/master#egg=nova + elif re.match(r'\s*https?:', line): + requirements.append(re.sub(r'\s*https?:.*#egg=(.*)$', r'\1', + line)) + # -f lines are for index locations, and don't get used here elif re.match(r'\s*-f\s+', line): pass else: @@ -73,11 +85,18 @@ def parse_requirements(requirements_files=['requirements.txt', def parse_dependency_links(requirements_files=['requirements.txt', 'tools/pip-requires']): dependency_links = [] + # dependency_links inject alternate locations to find packages listed + # in requirements for line in get_reqs_from_files(requirements_files): + # skip comments and blank lines if re.match(r'(\s*#)|(\s*$)', line): continue + # lines with -e or -f need the whole line, minus the flag if re.match(r'\s*-[ef]\s+', line): dependency_links.append(re.sub(r'\s*-[ef]\s+', '', line)) + # lines that are only urls can go in unmolested + elif re.match(r'\s*https?:', line): + dependency_links.append(line) return dependency_links @@ -135,8 +154,8 @@ def generate_authors(): new_authors = 'AUTHORS' if os.path.isdir('.git'): # don't include jenkins email address in AUTHORS file - git_log_cmd = "git log --format='%aN <%aE>' | sort -u | " \ - "grep -v " + jenkins_email + git_log_cmd = ("git log --format='%aN <%aE>' | sort -u | " + "grep -v " + jenkins_email) changelog = _run_shell_command(git_log_cmd) mailmap = parse_mailmap() with open(new_authors, 'w') as new_authors_fh: @@ -144,3 +163,38 @@ def generate_authors(): if os.path.exists(old_authors): with open(old_authors, "r") as old_authors_fh: new_authors_fh.write('\n' + old_authors_fh.read()) + + +def get_cmdclass(): + """Return dict of commands to run from setup.py.""" + + cmdclass = dict() + + class LocalSDist(sdist.sdist): + """Builds the ChangeLog and Authors files from VC first.""" + + def run(self): + write_git_changelog() + generate_authors() + # sdist.sdist is an old style class, can't use super() + sdist.sdist.run(self) + + cmdclass['sdist'] = LocalSDist + + # If Sphinx is installed on the box running setup.py, + # enable setup.py to build the documentation, otherwise, + # just ignore it + try: + from sphinx.setup_command import BuildDoc + + class LocalBuildDoc(BuildDoc): + def run(self): + for builder in ['html', 'man']: + self.builder = builder + self.finalize_options() + BuildDoc.run(self) + cmdclass['build_sphinx'] = LocalBuildDoc + except ImportError: + pass + + return cmdclass diff --git a/setup.cfg b/setup.cfg index dbb13fb067..c74b7b12c3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,9 +5,7 @@ # openstack-nose https://github.com/jkoelker/openstack-nose verbosity=2 detailed-errors=1 -with-openstack=1 -openstack-red=0.05 -openstack-yellow=0.025 -openstack-show-elapsed=1 -openstack-color=1 - +cover-package = quantum +cover-html = true +cover-erase = true +where=quantum/tests/unit diff --git a/setup.py b/setup.py index e46e710593..fe4f5fafdf 100644 --- a/setup.py +++ b/setup.py @@ -12,25 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -from setuptools import setup, find_packages +import setuptools -from quantum.openstack.common.setup import generate_authors -from quantum.openstack.common.setup import parse_requirements -from quantum.openstack.common.setup import parse_dependency_links -from quantum.openstack.common.setup import write_requirements -from quantum.openstack.common.setup import write_git_changelog -from quantum.openstack.common.setup import write_vcsversion +from quantum.openstack.common import setup - -requires = parse_requirements() -depend_links = parse_dependency_links() -write_requirements() -write_git_changelog() -write_vcsversion('quantum/vcsversion.py') -generate_authors() +setup.write_vcsversion('quantum/vcsversion.py') from quantum import version +requires = setup.parse_requirements() +depend_links = setup.parse_dependency_links() + Name = 'quantum' Url = "https://launchpad.net/quantum" Version = version.canonical_version_string() @@ -77,7 +69,7 @@ DataFiles = [ (ryu_plugin_config_path, ['etc/quantum/plugins/ryu/ryu.ini']), ] -setup( +setuptools.setup( name=Name, version=Version, url=Url, @@ -90,7 +82,8 @@ setup( install_requires=requires, dependency_links=depend_links, include_package_data=False, - packages=find_packages('.'), + packages=setuptools.find_packages('.'), + cmdclass=setup.get_cmdclass(), data_files=DataFiles, eager_resources=EagerResources, entry_points={ diff --git a/tools/install_venv.py b/tools/install_venv.py index 09b321bddc..50b1a3a486 100644 --- a/tools/install_venv.py +++ b/tools/install_venv.py @@ -36,6 +36,7 @@ PY_VERSION = "python%s.%s" % (sys.version_info[0], sys.version_info[1]) VENV_EXISTS = bool(os.path.exists(VENV)) + def die(message, *args): print >> sys.stderr, message % args sys.exit(1) @@ -67,7 +68,7 @@ def check_dependencies(): """Make sure virtualenv is in the path.""" if not HAS_VIRTUALENV: - raise Exception('Virtualenv not found. ' + \ + raise Exception('Virtualenv not found. ' + 'Try installing python-virtualenv') print 'done.' diff --git a/tox.ini b/tox.ini index 818bd99ade..0d3d4d139a 100644 --- a/tox.ini +++ b/tox.ini @@ -3,39 +3,26 @@ envlist = py26,py27,pep8 [testenv] setenv = VIRTUAL_ENV={envdir} + NOSE_WITH_OPENSTACK=1 + NOSE_OPENSTACK_COLOR=1 + NOSE_OPENSTACK_RED=0.05 + NOSE_OPENSTACK_YELLOW=0.025 + NOSE_OPENSTACK_SHOW_ELAPSED=1 + NOSE_OPENSTACK_STDOUT=1 deps = -r{toxinidir}/tools/pip-requires -r{toxinidir}/tools/test-requires -commands = nosetests --where=quantum/tests/unit {posargs} +commands = nosetests {posargs} + +[tox:jenkins] +sitepackages = True +downloadcache = ~/cache/pip [testenv:pep8] deps = pep8 -commands = pep8 --repeat --show-source quantum setup.py +commands = pep8 --repeat --show-source --exclude=.venv,.tox,dist,doc . + +[testenv:cover] +setenv = NOSE_WITH_COVERAGE=1 [testenv:venv] commands = {posargs} - -[testenv:cover] -commands = nosetests --with-coverage --cover-html --cover-erase --cover-package=quantum {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:jenkinspep8] -deps = file://{toxinidir}/.cache.bundle -commands = pep8 --repeat --show-source quantum setup.py - -[testenv:jenkinscover] -deps = file://{toxinidir}/.cache.bundle -commands = nosetests --where=quantum/tests/unit --cover-erase --cover-package=quantum --with-xcoverage {posargs} - -[testenv:jenkinsvenv] -deps = file://{toxinidir}/.cache.bundle -commands = {posargs}