diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..417be10 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,8 @@ +[run] +branch = True +source = $COVERAGE_HOME/src/plone/recipe/zeoserver +parallel = true +data_file = $COVERAGE_HOME/.coverage + +[report] +precision = 2 diff --git a/.gitignore b/.gitignore index de13ba3..66ec592 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ -.installed.cfg *.pyc +.coverage +.coverage.* +.installed.cfg +.tox/ bin/ develop-eggs/ +htmlcov/ include/ lib/ parts/ diff --git a/.travis.yml b/.travis.yml index 33c1e93..8f3e11a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,22 @@ language: python -sudo: false +dist: xenial python: - 2.7 - - 3.5 - 3.6 + - 3.7 +before_install: + - pip install -U setuptools pip + - pip install -U coverage coveralls zope.testrunner install: - - python bootstrap.py - - bin/buildout + - pip install -U -e .[zrs] script: - - bin/test -v1 + - export COVERAGE_HOME=$(pwd) + - export COVERAGE_PROCESS_START=$COVERAGE_HOME/.coveragerc + - coverage run -m zope.testrunner --test-path=src --all -v1 notifications: email: false +after_success: + - coverage combine + - coveralls cache: pip: true - directories: - - eggs/ diff --git a/CHANGES.rst b/CHANGES.rst index e732116..b6091e8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,16 +1,16 @@ Changelog ========= -1.4.3 (unreleased) ------------------- +2.0 (unreleased) +---------------- Breaking changes: -- *add item here* +- Drop support for ``ZODB3`` but require ``ZODB >= 5``. New features: -- *add item here* +- Add support for Python 3.6 and 3.7. Bug fixes: diff --git a/MANIFEST.in b/MANIFEST.in index fc44ccb..869f7ea 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,8 @@ -include * + include *.rst -recursive-include src * + include tox.ini + exclude tox.ini -global-exclude *pyc + recursive-include src *.bat + recursive-include src *.in + recursive-include src *.txt diff --git a/README.rst b/README.rst index 9b57c57..32847ec 100644 --- a/README.rst +++ b/README.rst @@ -196,7 +196,7 @@ zeo-conf repozo The path to the repozo.py backup script. A wrapper for this will be generated in bin/repozo, which sets up the appropriate environment for - running this. Defaults to using the repozo script from the ZODB3 egg. + running this. Defaults to using the repozo script from the ZODB egg. Set this to an empty value if you do not want this script to be generated. repozo-script-name @@ -209,7 +209,7 @@ zeopack The path to the zeopack.py backup script. A wrapper for this will be generated in bin/zeopack (unless you change `zeopack-script-name`), which sets up the appropriate environment to run this. Defaults to using the zeopack - script from the ZODB3 egg. Set this option to an empty value if you do not + script from the ZODB egg. Set this option to an empty value if you do not want this script to be generated. zeopack-script-name diff --git a/setup.py b/setup.py index fa7d427..aa662c9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ import sys -version = '1.4.3.dev0' +version = '2.0.dev0' additional_install_requires = [] @@ -34,9 +34,16 @@ 'Framework :: Plone', 'Framework :: Plone :: 5.1', 'Framework :: Plone :: 5.2', - 'Framework :: Zope2', + 'Framework :: Zope', + 'Framework :: Zope :: 4', 'Programming Language :: Python', + 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: Implementation', + 'Programming Language :: Python :: Implementation :: CPython', ], packages=find_packages('src'), include_package_data=True, @@ -46,8 +53,8 @@ 'setuptools', 'zc.buildout', 'zc.recipe.egg', - 'ZODB3 >= 3.8', - 'zope.mkzeoinstance >=4', + 'ZODB >= 5', + 'zope.mkzeoinstance >=4.1', 'ZopeUndo', ] + additional_install_requires, extras_require={ diff --git a/src/plone/recipe/zeoserver/recipe.py b/src/plone/recipe/zeoserver/recipe.py index f8e4481..0a24b2e 100644 --- a/src/plone/recipe/zeoserver/recipe.py +++ b/src/plone/recipe/zeoserver/recipe.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from pkg_resources import get_distribution -from pkg_resources import parse_version - import logging import os import shutil @@ -506,11 +503,8 @@ def _write_file(self, path, content): # the template used to build a blob storage -zodb_version = get_distribution('ZODB3').version -if parse_version(zodb_version) >= parse_version('3.9'): - # ZODB 3.9+ supports blobs natively - blob_storage_template = """ +blob_storage_template = """ path %(file_storage)s blob-dir %(blob_storage)s @@ -519,20 +513,6 @@ def _write_file(self, path, content): """.strip() -else: - # ZODB 3.8 needs a blob storage wrapper - blob_storage_template = """ - - blob-dir %(blob_storage)s - - path %(file_storage)s - %(pack_gc)s - %(pack_keep_old)s - - -""".strip() - - zrs_template = """ %%import zc.zrs diff --git a/src/plone/recipe/zeoserver/tests/test_docs.py b/src/plone/recipe/zeoserver/tests/test_docs.py index 998c622..84dba40 100644 --- a/src/plone/recipe/zeoserver/tests/test_docs.py +++ b/src/plone/recipe/zeoserver/tests/test_docs.py @@ -28,7 +28,8 @@ def setUp(test): install('Twisted', test) install('hyperlink', test) install('idna', test) - dependencies = pkg_resources.working_set.require('ZODB3') + install('PyHamcrest', test) + dependencies = pkg_resources.working_set.require('ZODB') for dep in dependencies: try: install(dep.project_name, test) diff --git a/src/plone/recipe/zeoserver/tests/zeoserver.txt b/src/plone/recipe/zeoserver/tests/zeoserver.txt index d53dc00..080a4a8 100644 --- a/src/plone/recipe/zeoserver/tests/zeoserver.txt +++ b/src/plone/recipe/zeoserver/tests/zeoserver.txt @@ -37,7 +37,8 @@ Let's run it:: We should have a basic zeo.conf:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> conf = open(os.path.join(zeo, 'etc', 'zeo.conf')).read() + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... conf = f.read() >>> print(conf.replace('\\', '/')) %define INSTANCE .../sample-buildout/parts/zeo @@ -105,7 +106,8 @@ Now, let's create a simple buildout to create a primary replication:: We should have primary zrs config in zeo.conf:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> print(open(os.path.join(zeo, 'etc', 'zeo.conf')).read()) + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... print(f.read()) %define INSTANCE ... ... %import zc.zrs @@ -138,7 +140,8 @@ And for a secondary:: We should have primary zrs config in zeo.conf:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> print(open(os.path.join(zeo, 'etc', 'zeo.conf')).read()) + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... print(f.read()) %define INSTANCE ... ... %import zc.zrs @@ -186,7 +189,8 @@ Let's run it:: We should have a zeo.conf with a rotatezlog:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> print(open(os.path.join(zeo, 'etc', 'zeo.conf')).read()) + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... print(f.read()) %define INSTANCE ... ... @@ -230,7 +234,8 @@ Let's run it:: We should have a zeo.conf with a log level set to `error`:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> print(open(os.path.join(zeo, 'etc', 'zeo.conf')).read()) + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... print(f.read()) %define INSTANCE ... ... @@ -266,7 +271,8 @@ Let's run it:: We should have a zeo.conf with log file rotation enabled:: >>> zeo = os.path.join(sample_buildout, 'parts', 'zeo') - >>> print(open(os.path.join(zeo, 'etc', 'zeo.conf')).read()) + >>> with open(os.path.join(zeo, 'etc', 'zeo.conf')) as f: + ... print(f.read()) %define INSTANCE ... ... @@ -313,7 +319,8 @@ Now check the values for `host`, `port` and `unix`:: >>> zeopack_path = os.path.join(sample_buildout, 'bin', 'zeopack') >>> if WINDOWS: ... zeopack_path += '-script.py' - >>> zeopack = open(zeopack_path, 'r').read() + >>> with open(zeopack_path, 'r') as f: + ... zeopack = f.read() >>> 'host = "127.0.0.1"' in zeopack True >>> 'port = "8001"' in zeopack @@ -344,7 +351,8 @@ Now check the values for `host`, `port` and `unix`:: >>> zeopack_path = os.path.join(sample_buildout, 'bin', 'zeopack') >>> if WINDOWS: ... zeopack_path += '-script.py' - >>> zeopack = open(zeopack_path, 'r').read() + >>> with open(zeopack_path, 'r') as f: + ... zeopack = f.read() >>> 'host = "192.168.0.11"' in zeopack True >>> 'port = "8001"' in zeopack @@ -375,7 +383,8 @@ Now check the values for `storage`:: >>> zeopack_path = os.path.join(sample_buildout, 'bin', 'zeopack') >>> if WINDOWS: ... zeopack_path += '-script.py' - >>> zeopack = open(zeopack_path, 'r').read() + >>> with open(zeopack_path, 'r') as f: + ... zeopack = f.read() >>> 'storage = "9"' in zeopack True @@ -403,7 +412,8 @@ Now check the values for `host`, `port` and `unix`:: >>> zeopack_path = os.path.join(sample_buildout, 'bin', 'zeopack') >>> if WINDOWS: ... zeopack_path += '-script.py' - >>> zeopack = open(zeopack_path, 'r').read() + >>> with open(zeopack_path, 'r') as f: + ... zeopack = f.read() >>> 'host = None' in zeopack True >>> 'port = None' in zeopack @@ -465,15 +475,17 @@ be different and correspond as the buildout specified:: >>> zeopack_paths = [os.path.join(sample_buildout, 'bin', script) for script in zeopack_scripts] >>> if WINDOWS: ... zeopack_paths = [zeopack + '-script.py' for zeopack in zeopacks] - >>> zeopacks = [open(zeopack_path, 'r').read() for zeopack_path in zeopack_paths] - - >>> 'username = "firstuser"' in zeopacks[0] + >>> with open(zeopack_paths[0], 'r') as f: + ... first_zeopack = f.read() + >>> with open(zeopack_paths[1], 'r') as f: + ... second_zeopack = f.read() + >>> 'username = "firstuser"' in first_zeopack True - >>> 'username = "seconduser"' in zeopacks[0] + >>> 'username = "seconduser"' in first_zeopack False - >>> 'username = "firstuser"' in zeopacks[1] + >>> 'username = "firstuser"' in second_zeopack False - >>> 'username = "seconduser"' in zeopacks[1] + >>> 'username = "seconduser"' in second_zeopack True Restore the original simple configuration:: @@ -532,7 +544,8 @@ Our generated script now has a reference to the relative path. >>> zeo_path = join('bin', 'zeo') >>> if WINDOWS: ... zeo_path += '-script.py' - >>> open(zeo_path).read() + >>> with open(zeo_path) as f: + ... f.read() '...base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))...' Extra paths in scripts @@ -569,17 +582,20 @@ The generated scripts should have the extra path. >>> parts_bin = join('parts', 'zeo', 'bin') - >>> extra in open(join('bin', 'zeo' + suffix)).read() + >>> with open(join('bin', 'zeo' + suffix)) as f: + ... extra in f.read() True >>> if not WINDOWS: - ... extra in open(join(parts_bin, 'runzeo' + suffix)).read() + ... with open(join(parts_bin, 'runzeo' + suffix)) as f: + ... extra in f.read() ... else: ... print(True) True >>> if not WINDOWS: - ... extra in open(join(parts_bin, 'zeoctl' + suffix)).read() + ... with open(join(parts_bin, 'zeoctl' + suffix)) as f: + ... extra in f.read() ... else: ... print(True) True @@ -613,5 +629,6 @@ The main script should have the initialization. ... else: ... suffix = '' - >>> 'foo = 1' in open(join('bin', 'zeo' + suffix)).read() + >>> with open(join('bin', 'zeo' + suffix)) as f: + ... 'foo = 1' in f.read() True diff --git a/tox.ini b/tox.ini index 74aa833..ecdf9bd 100644 --- a/tox.ini +++ b/tox.ini @@ -2,38 +2,36 @@ envlist = flake8, py27, - py35, py36, + py37, coverage, skip_missing_interpreters = False [testenv] +usedevelop = true commands = - {envbindir}/buildout -c {toxinidir}/buildout.cfg buildout:directory={envdir} buildout:develop={toxinidir} bootstrap - {envbindir}/buildout -c {toxinidir}/buildout.cfg buildout:directory={envdir} buildout:develop={toxinidir} -n install test - coverage run {envbindir}/test --all {posargs:-vc} -skip_install = true + zope-testrunner --test-path=src --all {posargs:-vc} +extras = zrs deps = - setuptools==33.1.1 - zc.buildout - coverage -setenv = - COVERAGE_FILE=.coverage.{envname} + zope.testrunner [testenv:coverage] -basepython = python2.7 -deps = coverage +basepython = python3.6 +deps = + zope.testrunner + coverage setenv = - COVERAGE_FILE=.coverage + COVERAGE_HOME={toxinidir} + COVERAGE_PROCESS_START={toxinidir}/.coveragerc commands = - coverage erase + coverage run -m zope.testrunner --test-path=src {posargs:-vc} coverage combine coverage html - coverage xml - coverage report + coverage report --fail-under=62 [testenv:flake8] -basepython = python2.7 +basepython = python3.6 +skip_install = true deps = flake8 commands = flake8 --doctests src setup.py