Skip to content

Migrate tox.ini into pyproject.toml #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .config/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ gerrit
gitpython
gitreview
hashseed
hexsha
htmlproofer
inlinehilite
jeepney
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
integration
pkg
lower
devel

platforms: linux,macos
build:
Expand Down Expand Up @@ -161,14 +162,6 @@ jobs:
name: logs.zip
path: .

- name: Check for expected number of coverage.xml reports
run: |
JOBS_PRODUCING_COVERAGE=7
if [ "$(find . -name coverage.xml | wc -l | bc)" -ne "${JOBS_PRODUCING_COVERAGE}" ]; then
echo "::error::Number of coverage.xml files was not the expected one (${JOBS_PRODUCING_COVERAGE}): $(find . -name coverage.xml |xargs echo)"
exit 1
fi

- name: Upload coverage data
uses: codecov/codecov-action@v5
with:
Expand Down
13 changes: 4 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ci:
- renovate-config-validator # container limits
repos:
- repo: https://github.com/renovatebot/pre-commit-hooks
rev: 41.57.1
rev: 41.61.1
hooks:
- id: renovate-config-validator
args: [--strict]
Expand All @@ -29,7 +29,7 @@ repos:
hooks:
- id: markdownlint
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v5.0.0
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-merge-conflict
Expand Down Expand Up @@ -63,13 +63,8 @@ repos:
- id: toml-sort-fix
alias: toml

- repo: https://github.com/tox-dev/tox-ini-fmt
rev: 1.6.0
hooks:
- id: tox-ini-fmt

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.7
rev: v0.12.8
hooks:
- id: ruff-format
alias: ruff
Expand Down Expand Up @@ -99,7 +94,7 @@ repos:

# keep at bottom as these are slower
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.8.6
rev: 0.8.8
hooks:
- id: uv-sync
- id: uv-lock
Expand Down
1 change: 1 addition & 0 deletions .taplo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ compact_arrays = true
compact_entries = false
compact_inline_tables = true
inline_table_expand = false
reorder_inline_tables = true
reorder_keys = true
222 changes: 193 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -214,24 +214,16 @@ ignore = [
"FBT",
"SIM",
"PGH",
"TCH",
"TC",
"PLR",
"INP",
"RET"
]
select = ["ALL"]

[tool.ruff.lint.flake8-pytest-style]
parametrize-values-type = "tuple"

[tool.ruff.lint.isort]
known-first-party = ["mk"]

[tool.ruff.lint.per-file-ignores]
"test/**/*.py" = ["S"]

[tool.ruff.lint.pydocstyle]
convention = "google"
flake8-pytest-style.parametrize-values-type = "tuple"
isort.known-first-party = ["mk"]
per-file-ignores."test/**/*.py" = ["S"]
pydocstyle.convention = "google"

[tool.setuptools_scm]
# To prevent accidental pick of mobile version tags such 'v6'
Expand All @@ -249,27 +241,199 @@ tag_regex = "^(?P<prefix>v)?(?P<version>[0-9.]+)(?P<suffix>.*)?$"
write_to = "src/mk/_version.py"

[tool.tomlsort]
# used by pre-commit hook
in_place = true
sort_inline_arrays = false
sort_inline_tables = true
sort_table_keys = true

[tool.tox]
env_list = ["py", "lint", "docs", "pkg", "lower", "devel", "integration"]
requires = [
"pip>=24",
"setuptools>=65.3",
"tox>=4.28.3",
"tox-extra>=2.1",
"tox-uv>=1.27"
]
skip_missing_interpreters = true

[tool.tox.env.clean]
commands = [
"find . -type d \\( -name __pycache__ -o -name .mypy_cache \\) -delete",
"find . -type f \\( -name '*.py[co]' -o -name \".coverage*\" -o -name coverage.xml \\) -delete"
]
commands_post = []
commands_pre = []
deps = []
description = "Remove temporary files"
skip_install = true

[tool.tox.env.deps]
commands = [
[
"pre-commit",
"run",
"--all-files",
"--show-diff-on-failure",
"--hook-stage",
"manual",
"deps"
],
[
"pre-commit",
"autoupdate"
],
{extend = true, of = ["tool", "tox", "env", "lint", "commands"], replace = "ref"}
]
commands_post = [
{extend = true, of = ["tool", "tox", "env", "lint", "commands_post"], replace = "ref"}
]
commands_pre = [
{extend = true, of = ["tool", "tox", "env", "lint", "commands_pre"], replace = "ref"}
]
dependency_groups = [
{extend = true, of = ["tool", "tox", "env", "lint", "dependency_groups"], replace = "ref"}
]
description = "Bump all test dependencies"
env_dir = "{work_dir}/lint"
runner = "{[tool.tox.testenv.lint]runner}"
skip_install = true

[tool.tox.env.devel]
commands = [
[
"sh",
"-c",
"uv pip list -q --format=freeze | tr '\\n' ','"
],
{extend = true, of = ["tool", "tox", "env_run_base", "commands"], replace = "ref"},
[
"git",
"restore",
"uv.lock"
]
]
description = "Run the tests with newest dependencies (no lock and allowing prereleases)"
runner = "uv-venv-lock-runner"
uv_sync_flags = ["--upgrade", "--prerelease=allow"]
uv_sync_locked = false

[tool.tox.env.docs]
commands = [
[
"sh",
"-c",
"cd docs && mk changelog"
],
[
"mkdocs",
{default = ["build", "--strict", "--site-dir=_readthedocs/html/"], extend = true, replace = "posargs"}
]
]
description = "Builds docs"
extras = ["docs"]
package = "editable"
skip_install = false

[tool.tox.env.integration]
commands = [["ansible", "--version"], ["nox", "--version"], ["mk", "test-integration"]]
dependency_groups = ["integration"]
description = "Run integrations tests"
package = "editable"

[tool.tox.env.lint]
commands = [
[
"{env_python}",
"-m",
"pre_commit",
"run",
"--all-files",
"--show-diff-on-failure",
{extend = true, replace = "posargs"}
]
]
dependency_groups = ["lint"]
description = "Run all linters"
runner = "uv-venv-runner"
skip_install = true

[tool.tox.env.lower]
dependency_groups = ["dev", "lower"]
description = "Run the tests with lower constraints dependencies"
runner = "uv-venv-runner"

[tool.tox.env.pkg]
commands = [["bash", "./tools/pkg.sh"]]
commands_post = []
commands_pre = []
description = "Build package, verify metadata, install package and assert behavior when ansible is missing."
skip_install = true

[tool.tox.env_run_base]
allowlist_externals = ["find", "git", "rm", "sh", "bash"]
commands = [
[
"coverage",
"run",
"-m",
"pytest",
{default = ["-ra", "--showlocals", "--doctest-modules", "--durations=10", "-m", "not eco"], extend = true, replace = "posargs"}
],
[
"sh",
"-c",
"coverage combine -a -q --data-file={env_dir}/.coverage {work_dir}/*/.coverage.* && coverage xml --data-file={env_dir}/.coverage -o {env_dir}/coverage.xml --fail-under=0 && coverage report --data-file={env_dir}/.coverage"
]
]
commands_pre = [["sh", "-c", "rm -f {env_dir}/.coverage* 2>/dev/null || true"]]
description = "Run tests"
group = "test"
package = "editable"
pass_env = [
"CI",
"CURL_CA_BUNDLE",
"FORCE_COLOR",
"GH_*",
"GITHUB_*",
"HOME",
"LANG",
"LC_*",
"NO_COLOR",
"PYTEST_*",
"PYTEST_REQPASS",
"PYTHON*",
"PYTHONBREAKPOINT",
"PYTHONHTTPSVERIFY",
"PYTHONIOENCODING",
"PYTHONPYCACHEPREFIX",
"PY_COLORS",
"PRE_COMMIT_HOME",
"REQUESTS_CA_BUNDLE",
"RTD_TOKEN",
"SETUPTOOLS_SCM_DEBUG",
"SSH_AUTH_SOCK",
"SSL_CERT_FILE",
"UV_*"
]
runner = "uv-venv-lock-runner"

[tool.tox.env_run_base.set_env]
ANSIBLE_DEVEL_WARNING = "false"
ANSIBLE_FORCE_COLOR = "1"
ANSIBLE_NOCOWS = "1"
COVERAGE_FILE = "{env:COVERAGE_FILE:{env_dir}/.coverage.{env_name}}"
COVERAGE_PROCESS_START = "{tox_root}/pyproject.toml"
DYLD_FALLBACK_LIBRARY_PATH = "/opt/homebrew/lib:{env:LD_LIBRARY_PATH}"
FORCE_COLOR = "1"
MK_CONFIG_FILE = "/dev/null"
PIP_DISABLE_PIP_VERSION_CHECK = "1"
PRE_COMMIT_COLOR = "always"
PYTHONHASHSEED = "0"
TERM = "dump"

[tool.uv]
# do not include 'lower' constraints in default groups
default-groups = ["dev", "docs"]
package = true

# [tool.uv.pip]
# annotation-style = "line"
# custom-compile-command = "tox run -e deps"
# no-emit-package = [
# "backports-tarfile",
# "cryptography",
# "exceptiongroup",
# "jeepney",
# "pip",
# "resolvelib",
# "secretstorage",
# "twine",
# "typing_extensions",
# "uv"
# ]
6 changes: 4 additions & 2 deletions src/mk/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ def __init__(self) -> None:
self.branch = self.repo.active_branch.name
logging.info("Detected active branch '%s'", self.branch)
except TypeError:
logging.warning("No branch detected.")
# https://github.com/gitpython-developers/GitPython/issues/633#issuecomment-786710029
logging.debug("No branch detected.")
self.branch = f"detached on {self.repo.head.object.hexsha}"

self.root = Path(self.repo.working_dir)
hash_key = f"{sys.version_info.major}{sys.version_info.minor}{self.root}"
self.hash = hashlib.sha256(hash_key.encode("UTF-8")).hexdigest()[:5]
self.cache = Cache(f"~/.cache/mk.{self.hash}/")

if self.repo.is_dirty():
logging.warning("Repo is dirty on %s", self.repo.active_branch)
logging.warning("Repo is dirty on %s", self.branch)

@cached_property
def pm(self) -> pluggy.PluginManager:
Expand Down
19 changes: 19 additions & 0 deletions tools/pkg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# cspell: ignore euox
set -euox pipefail
env | grep TOX

echo "Isolate pipx for testing..."
export PIPX_HOME="${TOX_WORK_DIR:-.tox}/.pipx"
export PIPX_BIN_DIR="${PIPX_HOME}/bin"
export PATH="${PIPX_BIN_DIR}:${PATH}"
rm -rf "${PIPX_HOME}"
pipx install --force -e .

rm -rf dist
python3 -c "import os.path, shutil, sys; dist_dir = 'dist'; os.path.isdir(dist_dir) or sys.exit(0); print('Removing {!s} contents...'.format(dist_dir), file=sys.stderr); shutil.rmtree(dist_dir)"
python3 -m build

python3 -m twine check --strict dist/*
python3 -m pip install "mk @ file://$(pwd)/$(echo dist/*.whl)"
python3 -m pip uninstall -y mk
Loading