diff --git a/docs/changelog/3024.feature.rst b/docs/changelog/3024.feature.rst new file mode 100644 index 000000000..d63fa00da --- /dev/null +++ b/docs/changelog/3024.feature.rst @@ -0,0 +1,2 @@ +Addded ``--list-dependencies`` and ``--no-list-dependencies`` CLI parameters. +If unspecified, defaults to listing when in CI, but not otherwise. diff --git a/src/tox/session/cmd/run/common.py b/src/tox/session/cmd/run/common.py index 49aeb87b6..2846f8d90 100644 --- a/src/tox/session/cmd/run/common.py +++ b/src/tox/session/cmd/run/common.py @@ -22,6 +22,7 @@ from tox.session.state import State from tox.tox_env.api import ToxEnv from tox.tox_env.runner import RunToxEnv +from tox.util.ci import is_ci from tox.util.graph import stable_topological_sort from tox.util.spinner import MISS_DURATION, Spinner @@ -156,6 +157,19 @@ def __call__( help="if recreate is set do not recreate packaging tox environment(s)", action="store_true", ) + list_deps = parser.add_mutually_exclusive_group() + list_deps.add_argument( + "--list-dependencies", + action="store_true", + default=is_ci(), + help="list the dependencies installed during environment setup", + ) + list_deps.add_argument( + "--no-list-dependencies", + action="store_false", + dest="list_dependencies", + help="never list the dependencies installed during environment setup", + ) if mode not in ("devenv", "config", "depends"): parser.add_argument( "--skip-pkg-install", diff --git a/src/tox/tox_env/python/api.py b/src/tox/tox_env/python/api.py index da9e435fa..6e57626ed 100644 --- a/src/tox/tox_env/python/api.py +++ b/src/tox/tox_env/python/api.py @@ -15,7 +15,6 @@ from tox.config.main import Config from tox.tox_env.api import ToxEnv, ToxEnvCreateArgs from tox.tox_env.errors import Fail, Recreate, Skip -from tox.util.ci import is_ci class VersionInfo(NamedTuple): @@ -227,12 +226,11 @@ def prepend_env_var_path(self) -> list[Path]: def _done_with_setup(self) -> None: """called when setup is done""" super()._done_with_setup() - running_in_ci = is_ci() - if self.journal or running_in_ci: + if self.journal or self.options.list_dependencies: outcome = self.installer.installed() if self.journal: self.journal["installed_packages"] = outcome - if running_in_ci: + if self.options.list_dependencies: logging.warning(",".join(outcome)) def python_cache(self) -> dict[str, Any]: diff --git a/tests/config/cli/test_cli_env_var.py b/tests/config/cli/test_cli_env_var.py index 61dbf962c..1d83175e9 100644 --- a/tests/config/cli/test_cli_env_var.py +++ b/tests/config/cli/test_cli_env_var.py @@ -10,6 +10,7 @@ from tox.pytest import CaptureFixture, LogCaptureFixture, MonkeyPatch from tox.session.env_select import CliEnv from tox.session.state import State +from tox.util.ci import is_ci def test_verbose() -> None: @@ -63,6 +64,7 @@ def test_verbose_no_test() -> None: "factors": [], "labels": [], "skip_env": "", + "list_dependencies": is_ci(), } @@ -121,6 +123,7 @@ def test_env_var_exhaustive_parallel_values( "labels": [], "exit_and_dump_after": 0, "skip_env": "", + "list_dependencies": is_ci(), } assert options.parsed.verbosity == 4 assert options.cmd_handlers == core_handlers diff --git a/tests/config/cli/test_cli_ini.py b/tests/config/cli/test_cli_ini.py index c7324e1a6..623a56f51 100644 --- a/tests/config/cli/test_cli_ini.py +++ b/tests/config/cli/test_cli_ini.py @@ -19,6 +19,7 @@ from tox.pytest import CaptureFixture, LogCaptureFixture, MonkeyPatch from tox.session.env_select import CliEnv from tox.session.state import State +from tox.util.ci import is_ci @pytest.fixture() @@ -102,6 +103,7 @@ def default_options() -> dict[str, Any]: "labels": [], "exit_and_dump_after": 0, "skip_env": "", + "list_dependencies": is_ci(), } @@ -139,6 +141,7 @@ def test_ini_exhaustive_parallel_values(core_handlers: dict[str, Callable[[State "labels": [], "exit_and_dump_after": 0, "skip_env": "", + "list_dependencies": is_ci(), } assert options.parsed.verbosity == 4 assert options.cmd_handlers == core_handlers diff --git a/tests/tox_env/python/test_python_api.py b/tests/tox_env/python/test_python_api.py index 3348acdab..a9ff7522e 100644 --- a/tests/tox_env/python/test_python_api.py +++ b/tests/tox_env/python/test_python_api.py @@ -218,9 +218,25 @@ def test_python_set_hash_seed_incorrect(tox_project: ToxProjectCreator) -> None: @pytest.mark.parametrize("in_ci", [True, False]) def test_list_installed_deps(in_ci: bool, tox_project: ToxProjectCreator, mocker: MockerFixture) -> None: - mocker.patch("tox.tox_env.python.api.is_ci", return_value=in_ci) + mocker.patch("tox.session.cmd.run.common.is_ci", return_value=in_ci) result = tox_project({"tox.ini": "[testenv]\nskip_install = true"}).run("r", "-e", "py") if in_ci: assert "pip==" in result.out else: assert "pip==" not in result.out + + +@pytest.mark.parametrize("list_deps", ["--list-dependencies", "--no-list-dependencies"]) +@pytest.mark.parametrize("in_ci", [True, False]) +def test_list_installed_deps_explicit_cli( + list_deps: str, + in_ci: bool, + tox_project: ToxProjectCreator, + mocker: MockerFixture, +) -> None: + mocker.patch("tox.session.cmd.run.common.is_ci", return_value=in_ci) + result = tox_project({"tox.ini": "[testenv]\nskip_install = true"}).run(list_deps, "r", "-e", "py") + if list_deps == "--list-dependencies": + assert "pip==" in result.out + else: + assert "pip==" not in result.out