A task runner with typed commands, nested groups, and instant shell completion.
Project description
footman
A task runner with the soul of duty and the UX of typer: typed function signatures become real flags and positionals, modules become nested command groups, independent tasks run in parallel by default, and shell completion answers from a cached manifest in ~25 ms — without importing your code.
Ships two console scripts, footman and the two-letter fm. Zero runtime
dependencies. Python 3.11+.
[!WARNING] Very early code. footman is alpha and moving fast — the public API, the decorator surface, the manifest format, and the CLI grammar can all change without notice or a deprecation cycle. Pin an exact version if you build on it.
Why
duty gets a lot right — the run() capture model, the decorator
ergonomics — and footman keeps those ideas. Where it pushes is the parts
that compound: completion served from a cache instead of re-importing your
project on every TAB (~15× faster, measured), eager type and choice
validation with errors that teach, a DAG scheduler that runs independent
tasks concurrently (the same four-step check lands ~4× sooner than duty
or invoke, measured), a monorepo task cascade that merges a tasks.py per
folder, and a first-party story for testing your tasks. The receipts live
in the comparison —
every number reproducible from comparison/.
Taste
uv add --dev footman # or: pip install footman
# tasks.py
from footman import task, group, run, tools
@task
def lint(fix: bool = False):
"Run ruff over the project."
tools.ruff.check("src", fix=fix)
@task(pre=[lint])
def test(*pytest_args):
"Run the test suite (extra args after --)."
tools.pytest(*pytest_args)
docs = group("docs", help="Documentation")
@docs.task
def serve(port: int = 8000):
"Serve the docs locally."
run(f"mkdocs serve -a localhost:{port}")
$ fm lint --fix
$ fm lint test docs serve --port 8001 # one chain; independent tasks run in parallel
$ fm test -- -k grammar -x # everything after -- goes to pytest
$ fm deploy produ
fm: deploy: <target> must be one of dev|staging|prod (got 'produ') — did you mean 'prod'?
$ fm --install-completion # detects your shell; TAB answers in ~25 ms
Learn more
Documentation — start with Getting started, then the good parts: typed signatures · chaining & parallelism · monorepos · composing tasks · running tools · testing your tasks · completion · CI & automation · comparison with duty / invoke / poe / typer
MIT licensed. The road to 1.0 lives in ROADMAP.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file footman-0.12.0.tar.gz.
File metadata
- Download URL: footman-0.12.0.tar.gz
- Upload date:
- Size: 91.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f3adf6d63c90f5bc3817e3eef7993d975faf0fdaebf2153f77b6d7eebbd7520
|
|
| MD5 |
f64cd99d3c77c50085cfab341effd379
|
|
| BLAKE2b-256 |
f74b76a09089425c5ce7f7c3b678c1239d9406d00a2b8cf69a05d760e17f49b1
|
Provenance
The following attestation bundles were made for footman-0.12.0.tar.gz:
Publisher:
release.yml on willemkokke/footman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
footman-0.12.0.tar.gz -
Subject digest:
5f3adf6d63c90f5bc3817e3eef7993d975faf0fdaebf2153f77b6d7eebbd7520 - Sigstore transparency entry: 2196033363
- Sigstore integration time:
-
Permalink:
willemkokke/footman@a07ce824309a6906ac0179ea090cb8fb7d14463e -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/willemkokke
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a07ce824309a6906ac0179ea090cb8fb7d14463e -
Trigger Event:
push
-
Statement type:
File details
Details for the file footman-0.12.0-py3-none-any.whl.
File metadata
- Download URL: footman-0.12.0-py3-none-any.whl
- Upload date:
- Size: 106.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0642d84879fcc60948bcb92a3d745c4e1af9b2d3fa4557014b7308361d8a4f1e
|
|
| MD5 |
ec3ef5f34d8fd9e73b3c3b489ee2ab32
|
|
| BLAKE2b-256 |
7549348f81441f36be4c8c1edb5ee961ae3b126a88f2d85e6591a77bdd2e97fd
|
Provenance
The following attestation bundles were made for footman-0.12.0-py3-none-any.whl:
Publisher:
release.yml on willemkokke/footman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
footman-0.12.0-py3-none-any.whl -
Subject digest:
0642d84879fcc60948bcb92a3d745c4e1af9b2d3fa4557014b7308361d8a4f1e - Sigstore transparency entry: 2196033434
- Sigstore integration time:
-
Permalink:
willemkokke/footman@a07ce824309a6906ac0179ea090cb8fb7d14463e -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/willemkokke
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a07ce824309a6906ac0179ea090cb8fb7d14463e -
Trigger Event:
push
-
Statement type: