toolroom
Typed surfaces for command-line tools, generated from the tools themselves.
from livery.toolroom.tools import git, cmake, ruff
git.switch("-c", "release/v1.4")
cmake.build("build", parallel=8)
ruff.check("src", fix=True, select=["E", "F"])
A tool room is where precision tools are made, kept with their
measurements, repaired when they drift, and issued for use. That is the
whole design, one verb at a time: a stub generator reads each tool's own
--help and writes a typed surface for it; the surfaces are kept with
the version they were read from; a weekly refresh re-takes them when the
tool moves; and the bridge issues any tool as a Python handle —
including tools no stub has ever described.
toolroom.terraform("plan") runs whether or not toolroom has heard of
terraform.
Beta. toolroom is pre-1.0: minor versions may include breaking changes — always called out in the changelog, never in a patch release. Pin the minor if you build on it.
No transcription
toolroom does not transcribe a tool's flags into Python parameters. Transcription drifts: the wrapper pins the flag-set its author copied, the tool moves on, and one day a call emits a flag the installed binary rejects. Instead, keyword arguments translate mechanically, so the installed tool's own CLI stays the single source of truth, at whatever version it is:
fix=True→--fix(False/None→ omitted entirely)strict=off→--no-strict(offis thetoolroom.offsentinel)output_format="github"→--output-format githubselect=["E", "F"]→--select E --select Fx=1(single letter) →-x 1- a trailing underscore escapes Python keywords:
import_="x"→--import x
Attribute access chains subcommands
(toolroom.docker.compose.up(detach=True)), and positional strings pass
through verbatim. The typed stubs suggest — your editor knows the
flags and what each one does — but they never forbid: the hints decide
whether your editor can help, never whether a call works.
Using the tools has the
full grammar.
Standalone, or hosted
With nothing else installed, a call spawns the tool with plain
subprocess and answers in a Result — the exit code as an int
subclass, carrying the captured streams. A failure raises ToolError
unless the call opted into nofail.
When footman is present in the
process, the same call routes through footman's run() instead and
inherits everything a task run means: capture, replay-on-failure,
dry-run, recording(), --json receipts, parallel lanes. Neither
package imports or depends on the other — they were designed together
and are better together, but each is useful with the other absent.
With footman tells
that story.
Built, not run
.argv turns a handle's call into a command line instead of an
execution — an ordinary list[str], with .posix() and .windows()
for the moment it crosses into a shell:
cmd = git.push.argv(force=True) # ["git", "push", "--force"]
cmd.posix() # "git push --force", quoted for a POSIX shell
Testing
Code that calls tools is tested with toolroom.testing.answers(): the
handles stay real — chaining, flag translation, redaction are all
exercised — and only execution is replaced, answered from a table of
canned output and exit codes:
from livery.toolroom.tools.testing import answers
with answers({("git", "push"): 1}) as calls:
release() # exercises the failure path
assert calls[0].argv == ["git", "push"]
Testing has the whole story.
Install
uv add toolroom # or: pip install toolroom
toolroom has zero runtime dependencies and needs Python 3.11+. The docs live at willemkokke.github.io/toolroom. MIT licensed.
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 livery_toolroom-0.7.0.tar.gz.
File metadata
- Download URL: livery_toolroom-0.7.0.tar.gz
- Upload date:
- Size: 161.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8346da07e544db1b909b98acbcf9cef2d67056e10bc4dc8dac11e256e6e1965
|
|
| MD5 |
d42f72dbe26e4509671a77d0ddd01c8e
|
|
| BLAKE2b-256 |
88e1f45e8ede58bae1b252ed4d01b523cb945639fa1c17b2ababf4ed18d4d4c9
|
File details
Details for the file livery_toolroom-0.7.0-py3-none-any.whl.
File metadata
- Download URL: livery_toolroom-0.7.0-py3-none-any.whl
- Upload date:
- Size: 197.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe9eeffc53adf742c5a1737b89ed283202c13fcb4862a3f373737648b2d1aa28
|
|
| MD5 |
d8582fd9133a89029b50218691c94382
|
|
| BLAKE2b-256 |
c55a5202f562f98d0226d34e5df612f0d179388473aa76f62d244cecf579cc86
|