Command Workflows¶
How commands flow through the tooling layers in this project.
The Three Layers¶
This project has three ways to run developer commands, each building on the one below:
┌─────────────────────────────────────────────┐
│ Layer 3: Task Runner (Taskfile.yml) │ ← task test
│ Convenience shortcuts, no Hatch knowledge │
├─────────────────────────────────────────────┤
│ Layer 2: Hatch (pyproject.toml envs) │ ← hatch run test
│ Manages virtualenvs, installs deps │
├─────────────────────────────────────────────┤
│ Layer 1: Python tools (pytest, ruff, mypy) │ ← pytest
│ The actual tools that do the work │
└─────────────────────────────────────────────┘
Each layer is optional — you can work at whichever level you prefer.
How a Command Flows¶
When you run task test, here's what happens:
task test
→ Taskfile.yml runs: hatch run test
→ Hatch activates the default env (creates it if needed)
→ Hatch runs the "test" script defined in pyproject.toml
→ Which executes: pytest {args}
The same pattern applies to every command:
| You type | Taskfile runs | Hatch script | Actual tool |
|---|---|---|---|
task test |
hatch run test |
test |
pytest |
task test:cov |
hatch run test-cov |
test-cov |
pytest --cov |
task lint |
hatch run lint |
lint |
ruff check src/ tests/ |
task lint:fix |
hatch run lint-fix |
lint-fix |
ruff check --fix src/ tests/ |
task fmt |
hatch run fmt |
fmt |
ruff format src/ tests/ |
task fmt:check |
hatch run fmt-check |
fmt-check |
ruff format --check src/ tests/ |
task typecheck |
hatch run typecheck |
typecheck |
mypy src/ |
task security |
hatch run bandit -r src/ |
(direct) | bandit -r src/ |
task check |
hatch run check |
check |
lint + fmt-check + typecheck + test |
task test:matrix |
hatch run test:run |
test:run |
pytest across Python 3.11–3.13 |
task docs:serve |
hatch run docs:serve |
docs:serve |
mkdocs serve |
task docs:build |
hatch run docs:build |
docs:build |
mkdocs build --strict |
task docs:commands |
(runs script directly) | — | python scripts/generate_command_reference.py |
Direct commands vs Hatch scripts
Most Task commands map to a named Hatch script (e.g. lint →
ruff check src/ tests/). A few — like security — run the tool
directly via hatch run <command> without a named script. The
result is the same; the only difference is whether a shorthand
alias exists in [tool.hatch.envs.default.scripts].
Pick Your Layer¶
Layer 1: Direct tools (no Hatch, no Task)¶
Use this if you manage your own virtualenv with pip install -e ".[dev]".
pytest # run tests
ruff check src/ tests/ # lint
ruff format src/ tests/ # format
mypy src/ # type check
bandit -r src/ # security lint
mkdocs serve # serve docs
Pros: No extra tooling. Works in any venv. Cons: You manage the venv, dependency installs, and Python versions yourself.
Default paths
The Hatch scripts default to src/ tests/ for Ruff and src/ for
mypy. If you run direct tools, remember to pass the same paths or
you may lint/format files that Hatch normally skips.
Layer 2: Hatch¶
Use this if you want managed environments but don't want Task installed.
hatch shell # enter the dev environment
hatch run test # run tests (auto-creates env if needed)
hatch run lint # lint
hatch run fmt # format
hatch run typecheck # type check
hatch run test:run # test across Python 3.11–3.13
hatch run docs:serve # serve docs (uses docs env)
hatch env show # show all environments
Pros: Automatic venv creation, dep syncing, multi-version matrix.
Cons: Requires Hatch installed (pipx install hatch).
Layer 3: Task runner¶
Use this for the shortest commands. Requires both Hatch and Task.
task test # run tests
task lint # lint
task fmt # format
task typecheck # type check
task check # all quality gates
task test:matrix # test across Python 3.11–3.13
task docs:serve # serve docs
task # list all available tasks
Pros: Shortest commands, discoverable via task --list.
Cons: Requires both Hatch and Task installed.
Which Layer Should I Use?¶
| Situation | Recommended layer |
|---|---|
| Quick contribution, minimal setup | Layer 1 (pip + direct tools) |
| Regular development | Layer 2 (Hatch) or Layer 3 (Task) |
| CI/CD workflows | Layer 2 (Hatch) — Task is not installed in CI |
| Multi-version testing | Layer 2 or 3 — Hatch manages the matrix |
| First time, just want to run tests | Layer 3 if Task is installed, else Layer 2 |
Passing CLI Arguments¶
All three layers support forwarding extra arguments to the underlying tool.
Append -- then your arguments:
Arguments after the script name are forwarded automatically:
Hatch scripts use {args} or {args: default} placeholders in
pyproject.toml. When you pass arguments, they replace the
placeholder; when you don't, the default is used.
More Task Shortcuts¶
Beyond the core table above, the Taskfile provides shortcuts for common
workflows. Run task --list-all to see everything.
Testing¶
| Task | What it does |
|---|---|
task test:v |
Tests with verbose output |
task test:cov |
Tests with coverage report |
task test:unit |
Unit tests only (tests/unit/) |
task test:integration |
Integration tests only |
task test:lf |
Rerun last-failed tests |
task test:x |
Stop on first failure |
task test:k |
Run tests matching a keyword |
task test:matrix |
All Python versions (3.11–3.13) |
task test:matrix:cov |
Matrix with coverage |
Environment¶
| Task | What it does |
|---|---|
task shell |
Enter the Hatch dev shell |
task env:show |
Show all Hatch envs and scripts |
task env:reset |
Remove and recreate the default env |
task env:prune |
Remove ALL Hatch environments |
Pre-commit¶
| Task | What it does |
|---|---|
task pre-commit:install |
Install all hook stages |
task pre-commit:run |
Run all hooks on all files |
task pre-commit:update |
Update hooks to latest versions |
task pre-commit:hook |
Run a single hook (e.g. -- ruff) |
Dependencies & Actions¶
| Task | What it does |
|---|---|
task deps:versions |
Show installed vs latest dep versions |
task deps:upgrade |
Upgrade dependencies in pyproject.toml |
task deps:outdated |
Check for outdated packages |
task actions:versions |
Show SHA-pinned action versions |
task actions:upgrade |
Upgrade SHA-pinned actions |
task actions:check |
CI gate: exit non-zero if stale actions |
Utility¶
| Task | What it does |
|---|---|
task build |
Build source + wheel distributions |
task clean:all |
Remove all build artifacts and caches |
task doctor |
Print diagnostics bundle for bug reports |
task doctor:repo |
Run repository health checks |
task commit |
Interactive conventional commit |
task version |
Show project version |
task security |
Run bandit security linter |
Doctor & Health Checks¶
| Task | What it does |
|---|---|
task doctor:all |
All health checks in one report |
task doctor:env |
Environment health check |
task doctor:repo |
Repository structure checks |
task doctor:git |
Git health dashboard |
task doctor:git:refresh |
Fetch, prune stale refs, sync tags |
task doctor:git:cleanup |
Delete stale branches, run gc |
task doctor:git:commits |
Detailed commit report |
task doctor:git:watch |
Re-run git dashboard every N seconds |
task doctor:git:config:export |
Export git config reference |
task doctor:git:config:apply |
Apply recommended git config |
task doctor:git:config:minimal |
Apply core subset (12 keys) |
Adding Your Own Commands¶
Hatch scripts¶
Add a new entry to [tool.hatch.envs.default.scripts] in pyproject.toml:
Then run with hatch run my-command.
Task shortcuts¶
Add a new task to Taskfile.yml:
Then run with task my-command.
Compound scripts¶
Hatch scripts can reference other scripts by name to create pipelines:
This is how task check / hatch run check runs all quality gates in
sequence — it's a compound script that calls four other scripts.
Where Commands Are Defined¶
| Layer | Config file | Section |
|---|---|---|
| Hatch scripts | pyproject.toml |
[tool.hatch.envs.default.scripts] |
| Hatch test matrix | pyproject.toml |
[tool.hatch.envs.test] |
| Hatch docs env | pyproject.toml |
[tool.hatch.envs.docs] |
| Task shortcuts | Taskfile.yml |
tasks: |
To see all available commands:
task # list Task shortcuts
task --list-all # include internal tasks
hatch env show # show Hatch envs and their scripts
See Also¶
- developer-commands.md — Complete command reference
- dev-setup.md — Environment setup instructions
- Getting Started — Quick start guide
- Command Reference — Auto-generated task & script reference
- ADR 016 — Why Hatch
- ADR 017 — Why Taskfile