diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index dd64bee..b64fd1b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -22,19 +22,23 @@ jobs: # This information is repeated in tox.ini # (see https://github.com/fedora-python/tox-github-action/issues/8) # Generate it by: tox -l | sed "s/^/- /" + - py36-tox324 - py36-tox3 - - py36-toxmaster + - py36-tox4 + - py37-tox324 - py37-tox3 - - py37-toxmaster - - py38-tox3 - - py38-toxmaster - - py39-tox3 - - py39-toxmaster - - py310-tox3 - - py310-toxmaster - py37-tox4 + - py38-tox324 + - py38-tox3 - py38-tox4 + - py39-tox324 + - py39-tox3 - py39-tox4 + - py310-tox324 + - py310-tox3 - py310-tox4 + - py311-tox324 + - py311-tox3 + - py311-tox4 # Use GitHub's Linux Docker host runs-on: ubuntu-latest diff --git a/README.rst b/README.rst index 35a85e0..0f49390 100644 --- a/README.rst +++ b/README.rst @@ -232,20 +232,20 @@ installs (a newer version of) ``tox`` and the missing packages into that environment and proxies all ``tox`` invocations trough that. Unfortunately, this is undesired for ``tox-current-env``. - 1. Starting with ``tox`` 3.23, it is possible to invoke it as - ``tox --no-provision`` to prevent the provision entirely. + 1. It is possible to invoke ``tox`` with ``--no-provision`` + to prevent the provision entirely. When requirements are missing, ``tox`` fails instead of provisioning. If a path is passed as a value for ``--no-provision``, the requirements will be serialized to the file, as JSON. - 2. Starting with ``tox`` 3.22, the requires, if specified, are included in the + 2. The requires, if specified, are included in the results of ``tox --print-deps-to``. This only works when they are installed (otherwise see the first point). 3. The minimal tox version, if specified, is included in the results of - ``tox --print-deps-to`` (as ``tox >= X.Y.Z``). + ``tox --print-deps-to``. This only works when the version requirement is satisfied (otherwise see the first point). -With ``tox >= 3.23``, the recommend way to handle this is: +The recommend way to handle this is: 1. Run ``tox --no-provision provision.json --print-deps-to=...`` or similar. 2. If the command fails, install requirements from ``provision.json`` to the diff --git a/setup.py b/setup.py index 9f18b8f..073588a 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setup( packages=find_packages("src"), entry_points={"tox": ["current-env = tox_current_env.hooks"]}, install_requires=[ - "tox>=3.15", + "tox>=3.24", "importlib_metadata; python_version < '3.8'" ], extras_require={ @@ -42,6 +42,7 @@ setup( "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Testing", ], diff --git a/src/tox_current_env/hooks3.py b/src/tox_current_env/hooks3.py index 62e956b..33b0a9d 100644 --- a/src/tox_current_env/hooks3.py +++ b/src/tox_current_env/hooks3.py @@ -61,13 +61,9 @@ def _allow_all_externals(envconfig): setattr(envconfig, option, "*") break else: - # If none was set, we set one of them, preferably the new one: - if hasattr(envconfig, "allowlist_externals"): - envconfig.allowlist_externals = "*" - else: - # unless we need to fallback to the old and deprecated - # TODO, drop this when we drop support for tox < 3.18 - envconfig.whitelist_externals = "*" + # If none was set, we set the new one + envconfig.allowlist_externals = "*" + @tox.hookimpl def tox_configure(config): @@ -225,8 +221,7 @@ def tox_dependencies(config): """Get dependencies of tox itself, 'minversion' and 'requires' config options""" if config.minversion is not None: yield f"tox >= {config.minversion}" - # config does not have the "requires" attribute until tox 3.22: - yield from getattr(config, "requires", []) + yield from config.requires @tox.hookimpl diff --git a/tests/fixtures/tox.ini b/tests/fixtures/tox.ini index 0055b26..e218977 100644 --- a/tests/fixtures/tox.ini +++ b/tests/fixtures/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,py39,py310 +envlist = py36,py37,py38,py39,py310,py311 [testenv] deps = diff --git a/tests/test_integration.py b/tests/test_integration.py index 5dcf3ba..02e576b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -6,7 +6,6 @@ import sys import textwrap import pytest -from packaging.version import parse as ver from utils import ( DOT_TOX, @@ -14,7 +13,6 @@ from utils import ( NATIVE_EXECUTABLE, NATIVE_SITE_PACKAGES, NATIVE_TOXENV, - TOX_VERSION, envs_from_tox_ini, is_available, modify_config, @@ -107,7 +105,6 @@ def test_print_deps_with_tox_minversion(projdir, toxenv, print_deps_stdout_arg): assert result.stdout == expected -@pytest.mark.xfail(TOX_VERSION < ver("3.22"), reason="No support in old tox") @pytest.mark.parametrize("toxenv", envs_from_tox_ini()) def test_print_deps_with_tox_requires(projdir, toxenv, print_deps_stdout_arg): with modify_config(projdir / "tox.ini") as config: @@ -125,7 +122,6 @@ def test_print_deps_with_tox_requires(projdir, toxenv, print_deps_stdout_arg): assert result.stdout == expected -@pytest.mark.xfail(TOX_VERSION < ver("3.22"), reason="No support in old tox") @pytest.mark.parametrize("toxenv", envs_from_tox_ini()) def test_print_deps_with_tox_minversion_and_requires( projdir, toxenv, print_deps_stdout_arg @@ -547,8 +543,6 @@ def test_self_is_not_installed(projdir, flag, usedevelop): @pytest.mark.parametrize("externals", [None, "allowlist_externals", "whitelist_externals"]) def test_externals(projdir, externals): - if externals == "allowlist_externals" and TOX_VERSION < ver("3.18"): - pytest.xfail("No support in old tox") with modify_config(projdir / 'tox.ini') as config: config['testenv']['commands'] = "echo assertme" if externals is not None: diff --git a/tests/test_integration_tox4.py b/tests/test_integration_tox4.py index ccca154..93594ad 100644 --- a/tests/test_integration_tox4.py +++ b/tests/test_integration_tox4.py @@ -4,14 +4,13 @@ import shutil import textwrap import pytest -from packaging.version import parse as ver from utils import ( DOT_TOX, NATIVE_EXEC_PREFIX_MSG, NATIVE_SITE_PACKAGES, NATIVE_TOXENV, - TOX_VERSION, + TOX_MIN_VERSION, envs_from_tox_ini, modify_config, needs_all_pythons, @@ -32,7 +31,7 @@ def test_print_deps(toxenv, print_deps_stdout_arg): result = tox("-e", toxenv, print_deps_stdout_arg) expected = textwrap.dedent( f""" - tox>={TOX_VERSION} + tox>={TOX_MIN_VERSION} six py {tox_footer(toxenv)} @@ -57,7 +56,6 @@ def test_print_deps_with_tox_minversion(projdir, toxenv, print_deps_stdout_arg): assert prep_tox_output(result.stdout) == expected -@pytest.mark.xfail(TOX_VERSION < ver("3.22"), reason="No support in old tox") @pytest.mark.parametrize("toxenv", envs_from_tox_ini()) def test_print_deps_with_tox_requires(projdir, toxenv, print_deps_stdout_arg): with modify_config(projdir / "tox.ini") as config: @@ -67,7 +65,7 @@ def test_print_deps_with_tox_requires(projdir, toxenv, print_deps_stdout_arg): f""" setuptools>30 pluggy - tox>={TOX_VERSION} + tox>={TOX_MIN_VERSION} six py {tox_footer(toxenv)} @@ -76,7 +74,6 @@ def test_print_deps_with_tox_requires(projdir, toxenv, print_deps_stdout_arg): assert prep_tox_output(result.stdout) == expected -@pytest.mark.xfail(TOX_VERSION < ver("3.22"), reason="No support in old tox") @pytest.mark.parametrize("toxenv", envs_from_tox_ini()) def test_print_deps_with_tox_minversion_and_requires( projdir, toxenv, print_deps_stdout_arg @@ -117,7 +114,7 @@ def test_allenvs_print_deps(print_deps_stdout_arg): result = tox(print_deps_stdout_arg) expected = [] for env in envs_from_tox_ini(): - expected.extend((f"tox>={TOX_VERSION}", "six", "py", f"{env}: OK")) + expected.extend((f"tox>={TOX_MIN_VERSION}", "six", "py", f"{env}: OK")) expected.pop() # The last "py310: OK" is not there expected.append(tox_footer(spaces=0)) expected = ("\n".join(expected)).splitlines() @@ -140,7 +137,7 @@ def test_print_deps_to_file(toxenv, tmp_path): depspath = tmp_path / "deps" result = tox("-e", toxenv, "--print-deps-to", str(depspath)) assert sorted(depspath.read_text().splitlines()) == sorted( - [f"tox>={TOX_VERSION}", "six", "py"] + [f"tox>={TOX_MIN_VERSION}", "six", "py"] ) expected = tox_footer(toxenv, spaces=0) + "\n" assert prep_tox_output(result.stdout) == expected @@ -160,7 +157,7 @@ def test_allenvs_print_deps_to_file(tmp_path, option): depspath = tmp_path / "deps" result = tox(option, str(depspath)) assert sorted(depspath.read_text().splitlines()) == sorted( - [f"tox>={TOX_VERSION}", "six", "py"] * len(envs_from_tox_ini()) + [f"tox>={TOX_MIN_VERSION}", "six", "py"] * len(envs_from_tox_ini()) ) expected = "" for env in envs_from_tox_ini()[:-1]: @@ -303,7 +300,7 @@ def test_print_deps_without_python_command(tmp_path, print_deps_stdout_arg): result = tox("-e", NATIVE_TOXENV, print_deps_stdout_arg, env=env) expected = textwrap.dedent( f""" - tox>={TOX_VERSION} + tox>={TOX_MIN_VERSION} six py {tox_footer(NATIVE_TOXENV)} @@ -342,10 +339,7 @@ def test_self_is_not_installed(projdir, flag, usedevelop): def test_self_is_installed_with_regular_tox(projdir, usedevelop): with modify_config(projdir / "tox.ini") as config: config["testenv"]["usedevelop"] = str(usedevelop) - _ = tox("-e", NATIVE_TOXENV, "-v", quiet=False) - egg_link = DOT_TOX / f"{NATIVE_TOXENV}/{NATIVE_SITE_PACKAGES}" / "test.egg-link" - dist_info = ( - DOT_TOX / f"{NATIVE_TOXENV}/{NATIVE_SITE_PACKAGES}" / "test-0.0.0.dist-info" - ) - to_test = egg_link if usedevelop else dist_info - assert to_test.exists() + result = tox("-e", NATIVE_TOXENV, "-v", quiet=False) + assert "test-0.0.0" in result.stdout + if usedevelop: + assert "test-0.0.0-0.editable" in result.stdout diff --git a/tests/utils.py b/tests/utils.py index b7a948f..dd53b31 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -52,7 +52,12 @@ def tox(*args, quiet=True, **kwargs): return cp -TOX_VERSION = ver(tox("--version").stdout.split(" ")[0].split("+")[0]) +TOX_MIN_VERSION = TOX_VERSION = ver(tox("--version").stdout.split(" ")[0].split("+")[0]) +# TOX_MIN_VERSION follows the same logic as tox itself +# see: https://github.com/tox-dev/tox/blob/6cf388db53402c2595ca8b673ddabece46f4d06e/src/tox/provision.py#L76-L84 +if TOX_MIN_VERSION.is_devrelease or TOX_MIN_VERSION.is_prerelease: + TOX_MIN_VERSION = ver(f"{TOX_VERSION.base_version}a0") + TOX4 = TOX_VERSION.major == 4 # if TOX4: # DOT_TOX /= "4" diff --git a/tox.ini b/tox.ini index 11aa1eb..f0a7167 100644 --- a/tox.ini +++ b/tox.ini @@ -2,15 +2,15 @@ # This information is repeated in .github/workflows/main.yaml # (see https://github.com/fedora-python/tox-github-action/issues/8) -envlist = {py36,py37,py38,py39,py310}-tox{3,master},{py37,py38,py39,py310}-tox4 +envlist = {py36,py37,py38,py39,py310,py311}-tox{324,3,4} [testenv] extras = tests deps= + tox324: tox >=3.24,<3.25 tox3: tox < 4 - toxmaster: git+https://github.com/tox-dev/tox.git@legacy - tox4: git+https://github.com/tox-dev/tox.git@rewrite + tox4: tox >=4,< 5 commands = !tox4: pytest -v {posargs} tests/test_integration.py tox4: pytest -v {posargs} tests/test_integration_tox4.py