From 71d21b8266ddaa8f4ac9b8bcf01978c0fca22297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Thu, 1 Aug 2019 12:39:12 +0200 Subject: [PATCH] Add --print-deps-to-file option for easier parsable dependencies Fixes https://github.com/fedora-python/tox-current-env/issues/13 --- README.rst | 5 +++-- src/tox_current_env/hooks.py | 21 +++++++++++++++--- tests/test_integration.py | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 21d4050..5ea96d1 100644 --- a/README.rst +++ b/README.rst @@ -14,10 +14,11 @@ The ``tox-current-env`` plugin adds two options: An attempt to run this with a Python version that doesn't match will fail (if ``tox`` is invoked from an Python 3.7 environment, any non 3.7 testenv will fail). -``tox --print-deps-only`` +``tox --print-deps-only`` / ``--print-deps-to-file`` Instead of running any ``commands``, - simply prints the declared dependencies in ``deps`` to the standard output. + simply prints the declared dependencies in ``deps`` to the standard output or specified file. This is useful for preparing the current environment for the above. + ``--print-deps-to-file`` will override the file, if it already exists. Invoking ``tox`` without any of the above options should behave as regular ``tox`` invocation without this plugin. Any deviation from this behavior is considered a bug. diff --git a/src/tox_current_env/hooks.py b/src/tox_current_env/hooks.py index 03dc706..82a2275 100644 --- a/src/tox_current_env/hooks.py +++ b/src/tox_current_env/hooks.py @@ -20,11 +20,23 @@ def tox_addoption(parser): default=False, help="Don't run tests, only print the dependencies", ) + parser.add_argument( + "--print-deps-to-file", + action="store", + dest="print_deps_path", + metavar="PATH", + default=None, + help="Like --print-deps-only, but to a file (overrides the file)", + ) @tox.hookimpl def tox_configure(config): """Stores options in the config. Makes all commands external and skips sdist""" + if config.option.print_deps_path is not None: + config.option.print_deps_only = True + with open(config.option.print_deps_path, "w", encoding="utf-8") as f: + f.write("") if config.option.current_env or config.option.print_deps_only: config.skipsdist = True for testenv in config.envconfigs: @@ -136,7 +148,10 @@ def tox_runtest(venv, redirect): """If --print-deps-only, prints deps instead of running tests""" config = venv.envconfig.config unsupported_raise(config, venv) - if config.option.print_deps_only: - for dependency in venv.get_resolved_dependencies(): - print(dependency) + if config.option.print_deps_path is not None: + with open(config.option.print_deps_path, "a", encoding="utf-8") as f: + print(*venv.get_resolved_dependencies(), sep="\n", file=f) + return True + if config.option.print_deps_only: + print(*venv.get_resolved_dependencies(), sep="\n") return True diff --git a/tests/test_integration.py b/tests/test_integration.py index 89cc83c..41a8c6c 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -113,6 +113,47 @@ def test_allenvs_print_deps_only(): assert result.stdout == expected +@pytest.mark.parametrize("toxenv", ["py36", "py37", "py38"]) +def test_print_deps_to_file(toxenv, tmp_path): + depspath = tmp_path / "deps" + result = tox("-e", toxenv, "--print-deps-to-file", str(depspath)) + assert depspath.read_text().splitlines() == ["six", "py"] + expected = textwrap.dedent( + f""" + ___________________________________ summary ____________________________________ + {toxenv}: commands succeeded + congratulations :) + """ + ).lstrip() + assert result.stdout == expected + + +def test_allenvs_print_deps_to_file(tmp_path): + depspath = tmp_path / "deps" + result = tox("--print-deps-to-file", str(depspath)) + assert depspath.read_text().splitlines() == ["six", "py"] * 3 + expected = textwrap.dedent( + """ + ___________________________________ summary ____________________________________ + py36: commands succeeded + py37: commands succeeded + py38: commands succeeded + congratulations :) + """ + ).lstrip() + assert result.stdout == expected + + +def test_allenvs_print_deps_to_existing_file(tmp_path): + depspath = tmp_path / "deps" + depspath.write_text("nada") + result = tox("--print-deps-to-file", str(depspath)) + lines = depspath.read_text().splitlines() + assert "nada" not in lines + assert "six" in lines + assert "py" in lines + + @needs_py3678 def test_regular_run(): result = tox()