From dd480c14ed28c9369f5c8002ecc9017cb6713c5e Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:10:27 +0200 Subject: [PATCH 01/12] MAINT: share `passenv` through base environment --- tox.ini | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tox.ini b/tox.ini index c50672ec..cd550c0a 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,6 @@ envlist = doc py sty -passenv = PYTHONPATH skip_install = True skip_missing_interpreters = True skipsdist = True @@ -15,6 +14,7 @@ commands = pytest {posargs} description = Run all unit tests +passenv = * [testenv:cov] allowlist_externals = @@ -40,7 +40,6 @@ commands = docs/ docs/_build/html description = Build documentation and API through Sphinx -passenv = * setenv = FORCE_COLOR = yes @@ -59,7 +58,6 @@ commands = docs/ docs/_build/html description = Set up a server to directly preview changes to the HTML pages -passenv = * setenv = FORCE_COLOR = yes @@ -73,7 +71,6 @@ commands = docs/ docs/_build/linkcheck description = Check external links in the documentation (requires internet connection) -passenv = * setenv = FORCE_COLOR = yes @@ -89,7 +86,6 @@ commands = --noshow description = Visualize module dependencies -passenv = * [testenv:sty] allowlist_externals = From 1ba5c10567a268cbc84b747022cef9f9fabbcbca Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:11:56 +0200 Subject: [PATCH 02/12] DX: remove `pydeps` support --- pyproject.toml | 4 ---- tox.ini | 13 ------------- 2 files changed, 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a1425e0b..a5784f2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,6 @@ dev = [ "compwa-policy[sty]", "compwa-policy[test]", "labels", - "pydeps", "sphinx-autobuild", "tox >=1.9", # for skip_install, use_develop 'sphinx-autobuild!=2024.4.*; python_version <"3.10.0"', @@ -184,9 +183,6 @@ cmd = "tox -e doclive" [tool.pixi.feature.dev.tasks.linkcheck] cmd = "tox -e linkcheck" -[tool.pixi.feature.dev.tasks.pydeps] -cmd = "tox -e pydeps" - [tool.pixi.feature.dev.tasks.sty] cmd = "pre-commit run --all-files" diff --git a/tox.ini b/tox.ini index cd550c0a..d29b6520 100644 --- a/tox.ini +++ b/tox.ini @@ -74,19 +74,6 @@ description = setenv = FORCE_COLOR = yes -[testenv:pydeps] -allowlist_externals = - pydeps -changedir = src -commands = - pydeps compwa_policy \ - -o module_structure.svg \ - --exclude '*._*' \ - --max-bacon=1 \ - --noshow -description = - Visualize module dependencies - [testenv:sty] allowlist_externals = pre-commit From 99f3a24dd09865f823d08022c82637f7af00fc12 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:13:07 +0200 Subject: [PATCH 03/12] MAINT: remove `FORCE_COLOR` from `tox` --- tox.ini | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tox.ini b/tox.ini index d29b6520..4e78a249 100644 --- a/tox.ini +++ b/tox.ini @@ -40,8 +40,6 @@ commands = docs/ docs/_build/html description = Build documentation and API through Sphinx -setenv = - FORCE_COLOR = yes [testenv:doclive] allowlist_externals = @@ -58,8 +56,6 @@ commands = docs/ docs/_build/html description = Set up a server to directly preview changes to the HTML pages -setenv = - FORCE_COLOR = yes [testenv:linkcheck] allowlist_externals = @@ -71,8 +67,6 @@ commands = docs/ docs/_build/linkcheck description = Check external links in the documentation (requires internet connection) -setenv = - FORCE_COLOR = yes [testenv:sty] allowlist_externals = From b06e37d97a7975a6444a432cc850e6cfa008b4cd Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:13:26 +0200 Subject: [PATCH 04/12] MAINT: move `description` on one line --- tox.ini | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tox.ini b/tox.ini index 4e78a249..31ed21a0 100644 --- a/tox.ini +++ b/tox.ini @@ -12,8 +12,7 @@ allowlist_externals = pytest commands = pytest {posargs} -description = - Run all unit tests +description = Run all unit tests passenv = * [testenv:cov] @@ -25,8 +24,7 @@ commands = --cov-report=html \ --cov-report=xml \ --cov=compwa_policy -description = - Compute test coverage +description = Compute test coverage [testenv:doc] allowlist_externals = @@ -38,8 +36,7 @@ commands = --keep-going \ --show-traceback \ docs/ docs/_build/html -description = - Build documentation and API through Sphinx +description = Build documentation and API through Sphinx [testenv:doclive] allowlist_externals = @@ -54,8 +51,7 @@ commands = --watch docs \ --watch src \ docs/ docs/_build/html -description = - Set up a server to directly preview changes to the HTML pages +description = Set up a server to directly preview changes to the HTML pages [testenv:linkcheck] allowlist_externals = @@ -65,15 +61,13 @@ commands = --builder linkcheck \ --show-traceback \ docs/ docs/_build/linkcheck -description = - Check external links in the documentation (requires internet connection) +description = Check external links in the documentation (requires internet connection) [testenv:sty] allowlist_externals = pre-commit commands = pre-commit run {posargs} --all-files -description = - Perform all linting, formatting, and spelling checks +description = Perform all linting, formatting, and spelling checks setenv = SKIP = pyright From 16bfd9dcc0364fd1f3f36347e93ba5d7f59495e1 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:14:46 +0200 Subject: [PATCH 05/12] DX: run `cov` instead of `py` in `tox` CI --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 31ed21a0..3acbeedf 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist = + cov doc - py sty skip_install = True skip_missing_interpreters = True From 3db157c2156d7d18cbae53e9a5abe1153439daf2 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:15:40 +0200 Subject: [PATCH 06/12] DX: run `linkcheck` in `tox` CI job Avoids raising a `RemovedInSphinx80Warning` warnings --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 3acbeedf..968ce919 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,7 @@ envlist = cov doc + linkcheck sty skip_install = True skip_missing_interpreters = True From 56b3d85614070bd54102eb54ca2715a48e93d178 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:16:44 +0200 Subject: [PATCH 07/12] DX: disable Sphinx warnings in `linkcheck` job --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 968ce919..b9cbc7dc 100644 --- a/tox.ini +++ b/tox.ini @@ -63,6 +63,8 @@ commands = --show-traceback \ docs/ docs/_build/linkcheck description = Check external links in the documentation (requires internet connection) +setenv = + PYTHONWARNINGS = [testenv:sty] allowlist_externals = From 1428e8770e8c7f7afcdb17187d369147eb53a2ae Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:18:55 +0200 Subject: [PATCH 08/12] MAINT: write CLI flags with `=` sign --- tox.ini | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tox.ini b/tox.ini index b9cbc7dc..28cddac4 100644 --- a/tox.ini +++ b/tox.ini @@ -32,7 +32,7 @@ allowlist_externals = sphinx-build commands = sphinx-build \ - --builder html \ + --builder=html \ --fail-on-warning \ --keep-going \ --show-traceback \ @@ -45,12 +45,12 @@ allowlist_externals = commands = sphinx-autobuild \ --open-browser \ - --re-ignore '.*\.egg-info' \ - --re-ignore '.*/__pycache__/.*' \ - --re-ignore 'docs/_build/.*' \ - --re-ignore 'docs/api/.*' \ - --watch docs \ - --watch src \ + --re-ignore='.*\.egg-info' \ + --re-ignore='.*/__pycache__/.*' \ + --re-ignore='docs/_build/.*' \ + --re-ignore='docs/api/.*' \ + --watch=docs \ + --watch=src \ docs/ docs/_build/html description = Set up a server to directly preview changes to the HTML pages @@ -59,7 +59,7 @@ allowlist_externals = sphinx-build commands = sphinx-build \ - --builder linkcheck \ + --builder=linkcheck \ --show-traceback \ docs/ docs/_build/linkcheck description = Check external links in the documentation (requires internet connection) From 4fecd6c49d990835698567ff2bc4a9b742eaf7a2 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:20:29 +0200 Subject: [PATCH 09/12] FIX: start `sphinx-autobuild` on random available port --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 28cddac4..0c1d7823 100644 --- a/tox.ini +++ b/tox.ini @@ -45,6 +45,7 @@ allowlist_externals = commands = sphinx-autobuild \ --open-browser \ + --port=0 \ --re-ignore='.*\.egg-info' \ --re-ignore='.*/__pycache__/.*' \ --re-ignore='docs/_build/.*' \ From ec1533a5401f82cbffc3f5fbadac0f77a8ace9c3 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:26:14 +0200 Subject: [PATCH 10/12] MAINT: use `--ignore` instead of `--re-ignore` where possible --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 0c1d7823..ab2f1321 100644 --- a/tox.ini +++ b/tox.ini @@ -44,12 +44,12 @@ allowlist_externals = sphinx-autobuild commands = sphinx-autobuild \ + --ignore=docs/_build \ + --ignore=docs/api \ --open-browser \ --port=0 \ --re-ignore='.*\.egg-info' \ --re-ignore='.*/__pycache__/.*' \ - --re-ignore='docs/_build/.*' \ - --re-ignore='docs/api/.*' \ --watch=docs \ --watch=src \ docs/ docs/_build/html From ce449401a4b075cc589f3fe9fcf773effb87cbb3 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:39:37 +0200 Subject: [PATCH 11/12] ENH: read Tox config from `tox.ini` or `pyproject.toml` --- src/compwa_policy/check_dev_files/pixi.py | 10 ++++---- src/compwa_policy/check_dev_files/tox.py | 30 ++++++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/compwa_policy/check_dev_files/pixi.py b/src/compwa_policy/check_dev_files/pixi.py index c82458f6..9c7e119c 100644 --- a/src/compwa_policy/check_dev_files/pixi.py +++ b/src/compwa_policy/check_dev_files/pixi.py @@ -9,9 +9,9 @@ import yaml from tomlkit import inline_table, string +from compwa_policy.check_dev_files.tox import read_tox_config from compwa_policy.errors import PrecommitError from compwa_policy.utilities import CONFIG_PATH, append_safe, vscode -from compwa_policy.utilities.cfg import open_config from compwa_policy.utilities.executor import Executor from compwa_policy.utilities.match import filter_files from compwa_policy.utilities.pyproject import ( @@ -190,9 +190,9 @@ def __import_conda_environment(pyproject: ModifiablePyproject) -> None: def __import_tox_tasks(pyproject: ModifiablePyproject) -> None: - if not CONFIG_PATH.tox.exists(): + tox = read_tox_config() + if tox is None: return - tox = open_config(CONFIG_PATH.tox) tox_jobs = ___get_tox_job_names(tox) imported_tasks = [] blacklisted_jobs = {"jcache"} # cspell:ignore jcache @@ -308,9 +308,9 @@ def __install_package_editable(pyproject: ModifiablePyproject) -> None: def __outsource_pixi_tasks_to_tox(pyproject: ModifiablePyproject) -> None: - if not CONFIG_PATH.tox.exists(): + tox = read_tox_config() + if tox is None: return - tox = open_config(CONFIG_PATH.tox) blacklisted_jobs = {"sty"} updated_tasks = [] for tox_job, pixi_task in ___get_tox_job_names(tox).items(): diff --git a/src/compwa_policy/check_dev_files/tox.py b/src/compwa_policy/check_dev_files/tox.py index 34f89f31..70364fd2 100644 --- a/src/compwa_policy/check_dev_files/tox.py +++ b/src/compwa_policy/check_dev_files/tox.py @@ -7,21 +7,16 @@ from compwa_policy.errors import PrecommitError from compwa_policy.utilities import CONFIG_PATH +from compwa_policy.utilities.pyproject import Pyproject def main(has_notebooks: bool) -> None: - if not CONFIG_PATH.tox.exists(): + tox = read_tox_config() + if tox is None: return - tox = _read_tox_config(CONFIG_PATH.tox) _check_expected_sections(tox, has_notebooks) -def _read_tox_config(path: Path) -> ConfigParser: - config = ConfigParser() - config.read(path) - return config - - def _check_expected_sections(tox: ConfigParser, has_notebooks: bool) -> None: # cspell:ignore doclive docnb docnblive testenv sections: set[str] = set(tox) @@ -40,7 +35,24 @@ def _check_expected_sections(tox: ConfigParser, has_notebooks: bool) -> None: missing_sections = expected_sections - sections if missing_sections: msg = ( - f"{CONFIG_PATH.tox} is missing job definitions:" + f"Tox configuration is missing job definitions:" f" {', '.join(sorted(missing_sections))}" ) raise PrecommitError(msg) + + +def read_tox_config() -> ConfigParser | None: + if CONFIG_PATH.tox.is_file(): + config = ConfigParser() + config.read(CONFIG_PATH.tox) + return config + if CONFIG_PATH.pyproject.is_file(): + pyproject = Pyproject.load() + if not pyproject.has_table("tool.tox"): + return None + tox_table = pyproject.get_table("tool.tox") + tox_config_str = tox_table.get("legacy_tox_ini") + if tox_config_str is not None: + config = ConfigParser() + config.read_string(tox_config_str) + return None From e384656c439bc0e3aa6dacf6dc2dc377af5a36d8 Mon Sep 17 00:00:00 2001 From: Remco de Boer <29308176+redeboer@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:49:35 +0200 Subject: [PATCH 12/12] FEAT: merge `tox.ini` into `pyproject.toml` --- .cspell.json | 1 - pyproject.toml | 81 ++++++++++++++++++++++++ src/compwa_policy/check_dev_files/tox.py | 40 ++++++++++-- src/compwa_policy/utilities/toml.py | 5 ++ tox.ini | 77 ---------------------- 5 files changed, 122 insertions(+), 82 deletions(-) delete mode 100644 tox.ini diff --git a/.cspell.json b/.cspell.json index 29d017c9..8f940d0a 100644 --- a/.cspell.json +++ b/.cspell.json @@ -37,7 +37,6 @@ "labels/*.toml", "pyproject.toml", "pyrightconfig.json", - "tox.ini", "typings" ], "language": "en-US", diff --git a/pyproject.toml b/pyproject.toml index a5784f2c..f2f481dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -340,3 +340,84 @@ sort_first = [ ] spaces_indent_inline_array = 4 trailing_comma_inline_array = true + +[tool.tox] +legacy_tox_ini = """ +[tox] +envlist = + cov + doc + linkcheck + sty +skip_install = True +skip_missing_interpreters = True +skipsdist = True + +[testenv] +allowlist_externals = + pytest +commands = + pytest {posargs} +description = Run all unit tests +passenv = * + +[testenv:cov] +allowlist_externals = + pytest +commands = + pytest {posargs} \ + --cov-fail-under=35 \ + --cov-report=html \ + --cov-report=xml \ + --cov=compwa_policy +description = Compute test coverage + +[testenv:doc] +allowlist_externals = + sphinx-build +commands = + sphinx-build \ + --builder=html \ + --fail-on-warning \ + --keep-going \ + --show-traceback \ + docs/ docs/_build/html +description = Build documentation and API through Sphinx + +[testenv:doclive] +allowlist_externals = + sphinx-autobuild +commands = + sphinx-autobuild \ + --ignore=docs/_build \ + --ignore=docs/api \ + --open-browser \ + --port=0 \ + --re-ignore='.*\\.egg-info' \ + --re-ignore='.*/__pycache__/.*' \ + --watch=docs \ + --watch=src \ + docs/ docs/_build/html +description = Set up a server to directly preview changes to the HTML pages + +[testenv:linkcheck] +allowlist_externals = + sphinx-build +commands = + sphinx-build \ + --builder=linkcheck \ + --show-traceback \ + docs/ docs/_build/linkcheck +description = Check external links in the documentation (requires internet connection) +setenv = + PYTHONWARNINGS = + +[testenv:sty] +allowlist_externals = + pre-commit +commands = + pre-commit run {posargs} --all-files +description = Perform all linting, formatting, and spelling checks +setenv = + SKIP = pyright +""" diff --git a/src/compwa_policy/check_dev_files/tox.py b/src/compwa_policy/check_dev_files/tox.py index 70364fd2..6a98d3a0 100644 --- a/src/compwa_policy/check_dev_files/tox.py +++ b/src/compwa_policy/check_dev_files/tox.py @@ -2,21 +2,49 @@ from __future__ import annotations +import re from configparser import ConfigParser from pathlib import Path +from typing import TYPE_CHECKING from compwa_policy.errors import PrecommitError from compwa_policy.utilities import CONFIG_PATH -from compwa_policy.utilities.pyproject import Pyproject +from compwa_policy.utilities.pyproject import ModifiablePyproject, Pyproject +from compwa_policy.utilities.toml import to_multiline_string + +if TYPE_CHECKING: + from tomlkit.items import String def main(has_notebooks: bool) -> None: + _merge_tox_ini_into_pyproject() tox = read_tox_config() if tox is None: return _check_expected_sections(tox, has_notebooks) +def _merge_tox_ini_into_pyproject() -> None: + if not CONFIG_PATH.tox.is_file(): + return + with open(CONFIG_PATH.tox) as file: + tox_ini = file.read() + with ModifiablePyproject.load() as pyproject: + tox_table = pyproject.get_table("tool.tox", create=True) + tox_table["legacy_tox_ini"] = __ini_to_toml(tox_ini) + CONFIG_PATH.tox.unlink() + msg = f"Merged {CONFIG_PATH.tox} into {CONFIG_PATH.pyproject}" + pyproject.changelog.append(msg) + + +def __ini_to_toml(ini: str) -> String: + ini = re.sub(r"(? None: # cspell:ignore doclive docnb docnblive testenv sections: set[str] = set(tox) @@ -43,9 +71,7 @@ def _check_expected_sections(tox: ConfigParser, has_notebooks: bool) -> None: def read_tox_config() -> ConfigParser | None: if CONFIG_PATH.tox.is_file(): - config = ConfigParser() - config.read(CONFIG_PATH.tox) - return config + return _load_tox_ini() if CONFIG_PATH.pyproject.is_file(): pyproject = Pyproject.load() if not pyproject.has_table("tool.tox"): @@ -56,3 +82,9 @@ def read_tox_config() -> ConfigParser | None: config = ConfigParser() config.read_string(tox_config_str) return None + + +def _load_tox_ini() -> ConfigParser: + config = ConfigParser() + config.read(CONFIG_PATH.tox) + return config diff --git a/src/compwa_policy/utilities/toml.py b/src/compwa_policy/utilities/toml.py index 293afa3d..0fdbc6dd 100644 --- a/src/compwa_policy/utilities/toml.py +++ b/src/compwa_policy/utilities/toml.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any, Iterable import tomlkit +from tomlkit.items import String, StringType, Trivia if TYPE_CHECKING: from tomlkit.items import Array @@ -18,3 +19,7 @@ def to_toml_array(items: Iterable[Any], multiline: bool | None = None) -> Array: else: array.multiline(multiline) return array + + +def to_multiline_string(value: str) -> String: + return String(StringType.MLB, value, value, Trivia()) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index ab2f1321..00000000 --- a/tox.ini +++ /dev/null @@ -1,77 +0,0 @@ -[tox] -envlist = - cov - doc - linkcheck - sty -skip_install = True -skip_missing_interpreters = True -skipsdist = True - -[testenv] -allowlist_externals = - pytest -commands = - pytest {posargs} -description = Run all unit tests -passenv = * - -[testenv:cov] -allowlist_externals = - pytest -commands = - pytest {posargs} \ - --cov-fail-under=35 \ - --cov-report=html \ - --cov-report=xml \ - --cov=compwa_policy -description = Compute test coverage - -[testenv:doc] -allowlist_externals = - sphinx-build -commands = - sphinx-build \ - --builder=html \ - --fail-on-warning \ - --keep-going \ - --show-traceback \ - docs/ docs/_build/html -description = Build documentation and API through Sphinx - -[testenv:doclive] -allowlist_externals = - sphinx-autobuild -commands = - sphinx-autobuild \ - --ignore=docs/_build \ - --ignore=docs/api \ - --open-browser \ - --port=0 \ - --re-ignore='.*\.egg-info' \ - --re-ignore='.*/__pycache__/.*' \ - --watch=docs \ - --watch=src \ - docs/ docs/_build/html -description = Set up a server to directly preview changes to the HTML pages - -[testenv:linkcheck] -allowlist_externals = - sphinx-build -commands = - sphinx-build \ - --builder=linkcheck \ - --show-traceback \ - docs/ docs/_build/linkcheck -description = Check external links in the documentation (requires internet connection) -setenv = - PYTHONWARNINGS = - -[testenv:sty] -allowlist_externals = - pre-commit -commands = - pre-commit run {posargs} --all-files -description = Perform all linting, formatting, and spelling checks -setenv = - SKIP = pyright