From d379ea516a913900f72cc48bb66c320dd62765f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Fri, 30 Dec 2022 09:22:01 -0800 Subject: [PATCH] Show installed packages after setup in CI envs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- docs/changelog/2685.bugfix.rst | 2 + pyproject.toml | 10 ++-- src/tox/tox_env/python/api.py | 10 +++- src/tox/tox_env/python/pip/pip_install.py | 8 +--- src/tox/util/ci.py | 29 ++++++++++++ tests/tox_env/python/test_python_api.py | 10 ++++ tests/tox_env/test_api.py | 2 + tests/tox_env/test_tox_env_runner.py | 2 + tests/util/test_ci.py | 56 +++++++++++++++++++++++ tox.ini | 3 +- whitelist.txt | 7 ++- 11 files changed, 119 insertions(+), 20 deletions(-) create mode 100644 docs/changelog/2685.bugfix.rst create mode 100644 src/tox/util/ci.py create mode 100644 tests/util/test_ci.py diff --git a/docs/changelog/2685.bugfix.rst b/docs/changelog/2685.bugfix.rst new file mode 100644 index 000000000..90beb0494 --- /dev/null +++ b/docs/changelog/2685.bugfix.rst @@ -0,0 +1,2 @@ +Restore tox 3 behaviour of showing the output of pip freeze, however now only active when running inside a CI +environment - by :user:`gaborbernat`. diff --git a/pyproject.toml b/pyproject.toml index a3f37aa50..4e2a44b25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] build-backend = "hatchling.build" -requires = ["hatchling>=1.11.1", "hatch-vcs>=0.3"] +requires = ["hatchling>=1.12", "hatch-vcs>=0.3"] [project] name = "tox" @@ -25,18 +25,18 @@ dependencies = [ "chardet>=5.1", "colorama>=0.4.6", "packaging>=22", - "platformdirs>=2.6", + "platformdirs>=2.6.2", "pluggy>=1", "pyproject-api>=1.2.1", 'tomli>=2.0.1; python_version < "3.11"', "virtualenv>=20.17.1", - "filelock>=3.8.2", + "filelock>=3.9", 'importlib-metadata>=5.2; python_version < "3.8"', 'typing-extensions>=4.4; python_version < "3.8"', ] optional-dependencies.docs = [ "furo>=2022.12.7", - "sphinx>=5.3", + "sphinx>=6", "sphinx-argparse-cli>=1.10", "sphinx-autodoc-typehints>=1.19.5", "sphinx-copybutton>=0.5.1", @@ -52,7 +52,7 @@ optional-dependencies.testing = [ "distlib>=0.3.6", "flaky>=3.7", "hatch-vcs>=0.3", - "hatchling>=1.11.1", + "hatchling>=1.12", "psutil>=5.9.4", "pytest>=7.2", "pytest-cov>=4", diff --git a/src/tox/tox_env/python/api.py b/src/tox/tox_env/python/api.py index bc841ad8c..9772a9412 100644 --- a/src/tox/tox_env/python/api.py +++ b/src/tox/tox_env/python/api.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import logging import sys from abc import ABC, abstractmethod from pathlib import Path @@ -14,6 +15,7 @@ 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): @@ -212,9 +214,13 @@ def prepend_env_var_path(self) -> list[Path]: def _done_with_setup(self) -> None: """called when setup is done""" super()._done_with_setup() - if self.journal: + running_in_ci = is_ci() + if self.journal or running_in_ci: outcome = self.installer.installed() - self.journal["installed_packages"] = outcome + if self.journal: + self.journal["installed_packages"] = outcome + if running_in_ci: + logging.warning(",".join(outcome)) def python_cache(self) -> dict[str, Any]: return { diff --git a/src/tox/tox_env/python/pip/pip_install.py b/src/tox/tox_env/python/pip/pip_install.py index 262974371..a148ce329 100644 --- a/src/tox/tox_env/python/pip/pip_install.py +++ b/src/tox/tox_env/python/pip/pip_install.py @@ -6,7 +6,6 @@ from packaging.requirements import Requirement -from tox.config.cli.parser import DEFAULT_VERBOSITY from tox.config.main import Config from tox.config.types import Command from tox.execute.request import StdinSource @@ -69,12 +68,7 @@ def post_process_install_command(self, cmd: Command) -> Command: def installed(self) -> list[str]: cmd: Command = self._env.conf["list_dependencies_command"] - result = self._env.execute( - cmd=cmd.args, - stdin=StdinSource.OFF, - run_id="freeze", - show=self._env.options.verbosity > DEFAULT_VERBOSITY, - ) + result = self._env.execute(cmd=cmd.args, stdin=StdinSource.OFF, run_id="freeze", show=False) result.assert_success() return result.out.splitlines() diff --git a/src/tox/util/ci.py b/src/tox/util/ci.py new file mode 100644 index 000000000..b65b2be6f --- /dev/null +++ b/src/tox/util/ci.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +import os + +_ENV_VARS = { # per https://adamj.eu/tech/2020/03/09/detect-if-your-tests-are-running-on-ci + "CI": None, # generic flag + "TF_BUILD": "true", # Azure Pipelines + "bamboo.buildKey": None, # Bamboo + "BUILDKITE": "true", # Buildkite + "CIRCLECI": "true", # Circle CI + "CIRRUS_CI": "true", # Cirrus CI + "CODEBUILD_BUILD_ID": None, # CodeBuild + "GITHUB_ACTIONS": "true", # GitHub Actions + "GITLAB_CI": None, # GitLab CI + "HEROKU_TEST_RUN_ID": None, # Heroku CI + "BUILD_ID": None, # Hudson + "TEAMCITY_VERSION": None, # TeamCity + "TRAVIS": "true", # Travis CI +} + + +def is_ci() -> bool: + """:return: a flag indicating if running inside a CI env or not""" + return any(e in os.environ if v is None else os.environ.get(e) == v for e, v in _ENV_VARS.items()) + + +__all__ = [ + "is_ci", +] diff --git a/tests/tox_env/python/test_python_api.py b/tests/tox_env/python/test_python_api.py index 6d8f2c80b..90e2ab655 100644 --- a/tests/tox_env/python/test_python_api.py +++ b/tests/tox_env/python/test_python_api.py @@ -179,3 +179,13 @@ def test_python_set_hash_seed_incorrect(tox_project: ToxProjectCreator) -> None: result = tox_project({"tox.ini": ""}).run("r", "-e", "py", "--hashseed", "ok") result.assert_failed(2) assert "tox run: error: argument --hashseed: invalid literal for int() with base 10: 'ok'" in result.err + + +@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) + result = tox_project({"tox.ini": "[testenv]\nskip_install = true"}).run("r", "-e", "py") + if in_ci: + assert "py: pip==" in result.out + else: + assert "py: pip==" not in result.out diff --git a/tests/tox_env/test_api.py b/tests/tox_env/test_api.py index 310e7fb5b..95efdc9e1 100644 --- a/tests/tox_env/test_api.py +++ b/tests/tox_env/test_api.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from pathlib import Path from tox.pytest import ToxProjectCreator diff --git a/tests/tox_env/test_tox_env_runner.py b/tests/tox_env/test_tox_env_runner.py index f1b34a90c..1910ab0b9 100644 --- a/tests/tox_env/test_tox_env_runner.py +++ b/tests/tox_env/test_tox_env_runner.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from pathlib import Path from tox.pytest import ToxProjectCreator diff --git a/tests/util/test_ci.py b/tests/util/test_ci.py new file mode 100644 index 000000000..5cfc9bb20 --- /dev/null +++ b/tests/util/test_ci.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +import pytest + +from tox.util.ci import _ENV_VARS, is_ci + + +@pytest.mark.parametrize( + "env_var", + { + "CI": None, # generic flag + "TF_BUILD": "true", # Azure Pipelines + "bamboo.buildKey": None, # Bamboo + "BUILDKITE": "true", # Buildkite + "CIRCLECI": "true", # Circle CI + "CIRRUS_CI": "true", # Cirrus CI + "CODEBUILD_BUILD_ID": None, # CodeBuild + "GITHUB_ACTIONS": "true", # GitHub Actions + "GITLAB_CI": None, # GitLab CI + "HEROKU_TEST_RUN_ID": None, # Heroku CI + "BUILD_ID": None, # Hudson + "TEAMCITY_VERSION": None, # TeamCity + "TRAVIS": "true", # Travis CI + }.items(), + ids=lambda v: v[0], # type: ignore +) +def test_is_ci(env_var: tuple[str, str | None], monkeypatch: pytest.MonkeyPatch) -> None: + for var in _ENV_VARS: + monkeypatch.delenv(var, raising=False) + monkeypatch.setenv(env_var[0], env_var[1] or "") + assert is_ci() + + +@pytest.mark.parametrize( + "env_var", + { + "TF_BUILD": "", # Azure Pipelines + "BUILDKITE": "", # Buildkite + "CIRCLECI": "", # Circle CI + "CIRRUS_CI": "", # Cirrus CI + "GITHUB_ACTIONS": "", # GitHub Actions + "TRAVIS": "", # Travis CI + }.items(), + ids=lambda v: v[0], # type: ignore +) +def test_is_ci_bad_set(env_var: tuple[str, str], monkeypatch: pytest.MonkeyPatch) -> None: + for var in _ENV_VARS: + monkeypatch.delenv(var, raising=False) + monkeypatch.setenv(env_var[0], env_var[1]) + assert not is_ci() + + +def test_is_ci_not(monkeypatch: pytest.MonkeyPatch) -> None: + for var in _ENV_VARS: + monkeypatch.delenv(var, raising=False) + assert not is_ci() diff --git a/tox.ini b/tox.ini index a534bedaf..d7bbdf472 100644 --- a/tox.ini +++ b/tox.ini @@ -60,7 +60,6 @@ commands = [testenv:docs] description = build documentation -basepython = python3.10 extras = docs commands = @@ -83,7 +82,7 @@ commands = description = do a release, required posarg of the version number skip_install = true deps = - gitpython>=3.1.29 + gitpython>=3.1.30 packaging>=22 towncrier>=22.12 commands = diff --git a/whitelist.txt b/whitelist.txt index 10c74ba74..ac48cb4b0 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -16,6 +16,7 @@ autouse binprm buf bufsize +buildkite cachetools canonicalize capfd @@ -78,7 +79,6 @@ getresult getsockname getsourcelines groupby -hardlink hookimpl hookspec hookspecs @@ -92,7 +92,6 @@ isatty isnumeric isspace iterdir -levelname levelno libs lightred @@ -159,12 +158,12 @@ string2lines stringify subparsers tcgetattr -TCSANOW +tcsanow tcsetattr -TIOCSWINSZ termios termux testenv +tiocswinsz tmpdir toml tomli