Tune gerenuk
Reference for the knobs. Tune for speed once a run_all reason repeats.
Where the diff comes from. The working tree - staged, unstaged and
untracked - is diffed from HEAD~1: the last commit plus what is not
committed yet. scope set to "branch" (or --scope branch) diffs the whole
branch from its merge-base with origin/main, then main, then master.
--base <REF> beats both. --workspace <PATH> names the project root.
Budgets. The walk says run_all at the first limit it hits. A flag
beats [tool.gerenuk] in pyproject.toml, which beats the default.
| Flag | Key | Default | Meaning |
|---|---|---|---|
--max-depth <N> | max-depth | 10 | levels from a changed symbol out to a test |
--max-symbols <N> | max-symbols | 500 | symbols visited before giving up |
--budget-ms <MS> | budget-ms | 30000 | wall clock for the walk; 0 disables it |
[tool.gerenuk]
max-depth = 20
suite-ms = 800
ignore-decorators = ["transformation", "celery.task"]
ignore-paths = ["**/*.md", "docs/**"]
docstrings = "code"
pytest-command = ["uv", "run", "pytest", "-o", "addopts="]
fallback-command = ["scripts/pick-subprojects.sh", "--from-gerenuk"]
suite-ms: how long the whole suite takes, from pytest’s summary line. A selection costs 1.5-2 s oftyfround-trips, so a suite declared at 2000 ms or under makesrunskip the walk and sayrun_all(fast_suite) whenever the diff would have needed one.impacted-testsignores it.ignore-decorators: dotted names, suffix-matched syntactically, of decorators that register a function with a runner. A changed symbol carrying one is reported as ignored; import aliases are not resolved.ignore-paths: non-Python files that never forcerun_all, matched on the repo-relative path (*,?,**) and listed asignored_paths; a.pyfile never is. Leave out anything a test reads, like checked docs.docstrings:ignore(default) selects nothing for a docstring-only edit;codecounts it, for code that reads__doc__(docopt, CLI help text).pytest-command: an argv, never a string, because the common value has arguments. Empty meanspytestonPATH;GERENUK_PYTESTbeats both.-o addopts=drops a coverage-carryingaddoptsfor the hook run only.fallback-command: whatrunexecs instead of the whole suite onrun_all. It gets the reason inGERENUK_FALLBACK_REASON, thechanged-symbolsreport as JSON on stdin, and its exit code is the hook’s.--fallback-command <JSON_ARRAY>andGERENUK_FALLBACKoverride it, in that order. An empty array anywhere is an error at startup.git-env:isolate(the default) removesGIT_DIR,GIT_INDEX_FILEand the rest of what a hook exports from pytest’s environment, so a test that creates a repository of its own never touches the one being committed;inheritkeeps them.--git-env <POLICY>beats it. The fallback inherits.
Binaries. GERENUK_TYF, GERENUK_GIT and GERENUK_PYTEST each name one
executable and skip the PATH lookup. Audit. gerenuk audit src/app.py
lists symbols nothing references, or only tests reach. Exit 1 on findings.
next: run gerenuk run --dry-run