diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 9ff19fc..0000000 --- a/.coveragerc +++ /dev/null @@ -1,3 +0,0 @@ -[run] -branch=True -source=dddp diff --git a/CHANGES.rst b/CHANGES.rst index 487f523..b110bb5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,11 @@ This project adheres to `Semantic Versioning `_. develop ------- +* Dropped support for Django 1.7 (didn't work anyway). +* Require `setuptools>=18.5` at install time due to use of + `python_platform_implementation` environment marker. +* Moved repository to https://github.com/django-ddp/django-ddp (new + Github organisation). * Add missing versions and dates to the change log, and note on Semantic Versioning. * Back to universal wheels, thanks to PEP-0496 environment markers. @@ -13,6 +18,9 @@ develop * Set `application_name` on PostgreSQL async connection. * Send `django.core.signals.request_finished` when closing WebSocket. * Don't require `DJANGO_SETTINGS_MODULE` to import API. +* Tox test suite updated to runs against Python 2.7/3.3/3.4/3.5 and + Django 1.8/1.9. +* Build wheels from tox environment to ensure consistency. 0.18.1 (2015-11-06) ------------------- diff --git a/Makefile b/Makefile index 8b2e277..6396fa7 100644 --- a/Makefile +++ b/Makefile @@ -2,49 +2,53 @@ NAME := $(shell python setup.py --name) VERSION := $(shell python setup.py --version) SDIST := dist/${NAME}-${VERSION}.tar.gz -WHEEL_PY2 := dist/$(subst -,_,${NAME})-${VERSION}-py2-none-any.whl -WHEEL_PY3 := dist/$(subst -,_,${NAME})-${VERSION}-py3-none-any.whl -WHEEL_PYPY := dist/$(subst -,_,${NAME})-${VERSION}-pypy-none-any.whl +WHEEL := dist/$(subst -,_,${NAME})-${VERSION}-py2.py3-none-any.whl .PHONY: all test clean clean-docs clean-dist upload-docs upload-pypi dist .INTERMEDIATE: dist.intermediate docs -all: docs dist +all: .travis.yml docs dist test: tox -vvv -clean: clean-docs clean-dist +clean: clean-docs clean-dist clean-pyc clean-docs: $(MAKE) -C docs/ clean clean-dist: - rm -f "${SDIST}" "${WHEEL_PY2}" "${WHEEL_PY3}" + rm -f "${SDIST}" "${WHEEL}" + +clean-pyc: + find . -type f -name \*.pyc -print0 | xargs -0 rm docs: $(shell find docs/ -type f -name \*.rst) docs/conf.py docs/Makefile $(shell find docs/_static/ -type f) $(shell find docs/_templates/ -type f) README.rst CHANGES.rst $(MAKE) -C docs/ clean html touch "$@" -dist: ${SDIST} ${WHEEL_PY2} ${WHEEL_PY3} +dist: ${SDIST} ${WHEEL} + @echo 'Build successful, `${MAKE} upload` when ready to release.' ${SDIST}: dist.intermediate + @echo "Testing ${SDIST}..." + tox --installpkg ${SDIST} -${WHEEL_PY2}: dist.intermediate - -${WHEEL_PY3}: dist.intermediate - -${WHEEL_PYPY}: - tox -e pypy-test-dist +${WHEEL}: dist.intermediate + @echo "Testing ${WHEEL}..." + tox --installpkg ${WHEEL} dist.intermediate: $(shell find dddp -type f) - tox -e py27-test-dist,py34-test-dist + tox -e dist upload: upload-pypi upload-docs -upload-pypi: ${SDIST} ${WHEEL_PY2} ${WHEEL_PY3} - twine upload "${WHEEL_PY2}" "${WHEEL_PY3}" "${SDIST}" +upload-pypi: ${SDIST} ${WHEEL} + twine upload "${WHEEL}" "${SDIST}" upload-docs: docs/_build/ python setup.py upload_sphinx --upload-dir="$ "$@" diff --git a/README.rst b/README.rst index da945eb..58e64ab 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,4 @@ +========== Django DDP ========== @@ -259,6 +260,7 @@ Contributors This project is forever grateful for the love, support and respect given by the awesome team at `Common Code`_. +.. _Django DDP: https://github.com/django-ddp/django-ddp .. _Django: https://www.djangoproject.com/ .. _Django signals: https://docs.djangoproject.com/en/stable/topics/signals/ .. _Common Code: https://commoncode.com.au/ diff --git a/dddp/__init__.py b/dddp/__init__.py index 5978f8c..834f6c7 100644 --- a/dddp/__init__.py +++ b/dddp/__init__.py @@ -1,11 +1,11 @@ -"""Django/PostgreSQL implementation of the Meteor DDP service.""" +"""Django/PostgreSQL implementation of the Meteor server.""" from __future__ import unicode_literals -import os.path import sys from gevent.local import local from dddp import alea __version__ = '0.18.1' +__url__ = 'https://github.com/django-ddp/django-ddp' default_app_config = 'dddp.apps.DjangoDDPConfig' diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 101a9b6..0000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ --r requirements.txt -Sphinx==1.3.1 -Sphinx-PyPI-upload==0.2.1 -cloud_sptheme==1.7 -twine==1.6.4 diff --git a/docs/changelog.rst b/docs/reference/changelog.rst similarity index 100% rename from docs/changelog.rst rename to docs/reference/changelog.rst diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..40fe1a6 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +# things you need to build from source and distribute a release +Sphinx==1.3.3 +Sphinx-PyPI-upload==0.2.1 +twine==1.6.4 +sphinxcontrib-dashbuilder==0.1.0 diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..dc85271 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,2 @@ +# things required to run test suite +# (nothing required! we use unittest from stdlib...) diff --git a/requirements.txt b/requirements.txt index e0617b0..7a314e6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ -Django==1.8.5 -gevent==1.0.2 +Django>=1.7 +gevent==1.0.2 ; platform_python_implementation == "CPython" and python_version < "3.0" +gevent==1.1rc2 ; platform_python_implementation != "CPython" or python_version >= "3.0" gevent-websocket==0.9.5 -psycopg2==2.6.1 +psycopg2==2.6.1 ; platform_python_implementation == "CPython" +psycopg2cffi>=2.7.2 ; platform_python_implementation != "CPython" six==1.10.0 diff --git a/setup.py b/setup.py index 92958f1..9b0ca55 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,43 @@ #!/usr/bin/env python """Django/PostgreSQL implementation of the Meteor server.""" -from distutils.version import StrictVersion +import os.path import setuptools -import sys +import subprocess +from distutils import log +from distutils.version import StrictVersion +from distutils.command.build import build # setuptools 18.5 introduces support for the `platform_python_implementation` # environment marker: https://github.com/jaraco/setuptools/pull/28 +__requires__ = 'setuptools>=18.5' + +assert StrictVersion(setuptools.__version__) >= StrictVersion('18.5'), \ + 'Installation from source requires setuptools>=18.5.' + + +class Build(build): + + """Build all files of a package.""" + + def run(self): + """Build our package.""" + cmdline = [ + 'meteor', + 'build', + '--directory', + '../build', + ] + meteor_dir = os.path.join( + os.path.dirname(__file__), + 'dddp', + 'test', + 'meteor_todos', + ) + log.info('Building meteor app %r (%s)', meteor_dir, ' '.join(cmdline)) + subprocess.check_call(cmdline, cwd=meteor_dir) + return build.run(self) -if not StrictVersion(setuptools.__version__) >= StrictVersion('18.5'): - # TODO: Is there an official way to upgrade setuptools in-place? - import subprocess - subprocess.check_call(['pip', 'install', '-U', 'setuptools>=18.5']) - sys.stderr.write( - 'Your setuptools has been upgraded, ' - 'please re-run setup to continue.' - ) - sys.exit(1) CLASSIFIERS = [ # Beta status until 1.0 is released @@ -54,8 +75,8 @@ CLASSIFIERS = [ "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", - "Framework :: Django :: 1.7", "Framework :: Django :: 1.8", + "Framework :: Django :: 1.9", ] setuptools.setup( @@ -65,41 +86,62 @@ setuptools.setup( long_description=open('README.rst').read(), author='Tyson Clugg', author_email='tyson@clugg.net', - url='https://github.com/commoncode/django-ddp', + url='https://github.com/django-ddp/django-ddp', + keywords=[ + 'django ddp meteor websocket websockets realtime real-time live ' + 'liveupdate live-update livequery live-query' + ], license='MIT', packages=setuptools.find_packages(), - include_package_data=True, + include_package_data=True, # install data files specified in MANIFEST.in + zip_safe=False, # TODO: Move dddp.test into it's own package. setup_requires=[ - 'setuptools>=18.5', + # packages required to run the setup script + __requires__, ], install_requires=[ - 'Django>=1.7', + 'Django>=1.8', 'django-dbarray>=0.2', - 'gevent-websocket>=0.9,!=0.9.4', 'meteor-ejson>=1.0', 'psycogreen>=1.0', 'pybars3>=0.9.1', 'six>=1.10.0', ], extras_require={ + # We need gevent version dependent upon environment markers, but the + # extras_require seem to be a separate phase from setup/install of + # install_requires. So we specify gevent-websocket (which depends on + # gevent) here in order to honour environment markers. + '': [ + 'gevent-websocket>=0.9,!=0.9.4', + ], + # Django 1.9 doesn't support Python 3.3 + ':python_version=="3.3"': [ + 'Django<1.9', + ], # CPython < 3.0 can use gevent 1.0 - ':platform_python_implementation == "CPython" ' - 'and python_version < "3.0"': [ + ':platform_python_implementation=="CPython" and python_version<"3.0"': [ 'gevent>=1.0', ], # everything else needs gevent 1.1 - ':platform_python_implementation != "CPython" ' - 'or python_version >= "3.0"': [ - 'gevent>=1.1rc1', + ':platform_python_implementation!="CPython" or python_version>="3.0"': [ + 'gevent>=1.1rc2', ], # CPython can use plain old psycopg2 - ':platform_python_implementation == "CPython"': [ + ':platform_python_implementation=="CPython"': [ 'psycopg2>=2.5.4', ], # everything else must use psycopg2cffi ':platform_python_implementation != "CPython"': [ 'psycopg2cffi>=2.7.2', ], + 'develop': [ + # things you need to distribute a wheel from source (`make dist`) + 'Sphinx>=1.3.3', + 'Sphinx-PyPI-upload>=0.2.1', + 'twine>=1.6.4', + 'sphinxcontrib-dashbuilder>=0.1.0', + ], }, entry_points={ 'console_scripts': [ @@ -107,4 +149,8 @@ setuptools.setup( ], }, classifiers=CLASSIFIERS, + test_suite='dddp.test.run_tests', + cmdclass={ + 'build': Build, + }, ) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index bc04b49..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1 +0,0 @@ --r requirements.txt diff --git a/tox.ini b/tox.ini index 1788129..19f9648 100644 --- a/tox.ini +++ b/tox.ini @@ -4,45 +4,154 @@ # and then run "tox" from this directory. [tox] -# require tox>=2.1.1 or refuse to run the tests. + +# require tox 2.1.1 or later minversion=2.1.1 -# return success even if some of the specified environments are missing +# don't fail if missing a python version specified in envlist skip_missing_interpreters=True -# "envlist" is a comma separated list of environments, each environment name -# contains factors separated by hyphens. For example, "py27-unittest" has 2 -# factors: "py27" and "unittest". Other settings such as "setenv" accept the -# factor names as a prefixes (eg: "unittest: ...") so that prefixed settings -# only apply if the environment being run contains that factor. - +# list of environments to run by default envlist = - py27-test, - py33-test, - py34-test, - py35-test, - pypy-test, + lint + clean + py33-django{1.8} + {py27,py34,py35,pypy,pypy3}-django{1.8,1.9} + report + [testenv] +# virtualenv only installs setuptools==0.18.2 but we need 0.18.5: +# - https://github.com/pypa/virtualenv/issues/807 +# - https://github.com/pypa/virtualenv/issues/801 +# - https://github.com/pypa/virtualenv/issues/717 +# - https://github.com/pypa/virtualenv/issues/781 +# - https://github.com/pypa/virtualenv/issues/580 +# - https://github.com/pypa/virtualenv/issues/563 +# - https://github.com/pypa/virtualenv/issues/491 +# wheel 0.25.0 needed for Python 3.5: +# - https://bitbucket.org/pypa/wheel/issues/146/wheel-building-fails-on-cpython-350b3 +install_command=sh -c 'pip install -U "setuptools>=18.5" "wheel>=0.25.0" "pip>=7.1.2" && pip install "$@" && sync' sh {opts} {packages} +whitelist_externals=sh + +# force clean environment each time recreate=True -usedevelop=True + +# build sdist from setup.py and install from that (validate setup.py) +usedevelop=False + +# list of environment variables passed through to commands passenv= - BUILD_NUMBER - BUILD_URL - XDG_CACHE_HOME + ; https://help.ubuntu.com/community/EnvironmentVariables#Other_environment_variables + USER + LOGNAME + HOME + TERM + TERMCAP -# stop running commands if previous commands fail -ignore_errors = False + ; https://help.ubuntu.com/community/EnvironmentVariables#Graphical_desktop-related_variables + DISPLAY + XDG_CACHE_HOME + C_INCLUDE_PATH + CFLAGS + ; https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project + BUILD_NUMBER + BUILD_ID + BUILD_URL + NODE_NAME + JOB_NAME + BUILD_TAG + JENKINS_URL + EXECUTOR_NUMBER + JAVA_HOME + WORKSPACE + GIT_COMMIT + GIT_URL + GIT_BRANCH + + ; http://www.postgresql.org/docs/current/static/libpq-envars.html + PGHOST + PGHOSTADDR + PGPORT + PGDATABASE + PGUSER + PGPASSWORD + PGPASSFILE + PGSERVICE + PGSERVICEFILE + PGREALM + PGOPTIONS + PGAPPNAME + PGSSLMODE + PGREQUIRESSL + PGSSLCOMPRESSION + PGSSLCERT + PGSSLKEY + PGSSLROOTCERT + PGSSLCRL + PGREQUIREPEER + PGKRBSRVNAME + PGSSLLIB + PGCONNECT_TIMEOUT + PGCLIENTENCODING + PGDATESTYLE + PGTZ + PGGEQO + PGSYSCONFDIR + PGLOCALEDIR + +# `pip install -rrequierements.txt` <-- tox doesn't understand PEP-0496 Environment Markers. +# pypy coverage fails with --concurrency set to `gevent` +# pypy install gevent fails building wheel commands = - dist: check-manifest - py{27,33,34,35}-test: coverage run --concurrency=gevent {toxinidir}/dddp/test/manage.py test -v3 --noinput - pypy-test: coverage run {toxinidir}/dddp/test/manage.py test -v3 --noinput - test: coverage report - dist: {envpython} setup.py --quiet --no-user-cfg sdist --dist-dir={toxinidir}/dist/ - dist: {envpython} setup.py --quiet --no-user-cfg bdist_wheel --dist-dir={toxinidir}/dist/ + {py27,py33,py34,py35}: pip install -rrequirements.txt + {pypy,pypy3}: pip install --no-binary gevent -rrequirements.txt + {py27,py33,py34,py35}: coverage run --append --concurrency=gevent --source=dddp setup.py test + {pypy,pypy3}: coverage run --append --source=dddp setup.py test deps = - test: coverage - dist: check-manifest - dist: wheel + #-rrequirements.txt + django1.8: Django>=1.8,<1.9 + django1.9: Django>=1.9,<1.10 + coverage + + +[testenv:dist] +commands = + check-manifest --ignore "dddp/test/build*,dddp/test/meteor_todos/.meteor/local*" + {envpython} setup.py --quiet --no-user-cfg sdist --dist-dir={toxinidir}/dist/ + {envpython} setup.py --quiet --no-user-cfg bdist_wheel --dist-dir={toxinidir}/dist/ + +# the `dist` environment doesn't need our package installed +skip_install=True + +deps = + -rrequirements-dev.txt + check-manifest + wheel + + +[testenv:clean] +skip_install=True +deps=coverage +commands= + coverage erase + + +[testenv:report] +skip_install=True +deps=coverage +commands= + coverage report + coverage html + + +[testenv:lint] +usedevelop=True +commands= + pip install -rrequirements.txt + prospector --doc-warnings --zero-exit {toxinidir}/dddp/ +deps = + prospector==0.10.2 + pylint==1.4.5