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.
Metadata
Release files for livery-toolroom 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| livery_toolroom-0.11.0.tar.gz | 56.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| livery_toolroom-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 123.6 kB
Release files / livery_toolroom-0.11.0.tar.gz
| Download URL | livery_toolroom-0.11.0.tar.gz |
|---|---|
| Size | 56.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
580da43cdc950fc99a182a6f5f0af529d37128b88d4f3c52a426d44dfbde7b01
|
|
BLAKE2b-256 checksum How to use checksums |
76b393fd747b699b41658221ddadd7c948ce7c7d397d14c3290e9307c031fe59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / livery_toolroom-0.11.0-py3-none-any.whl
| Download URL | livery_toolroom-0.11.0-py3-none-any.whl |
|---|---|
| Size | 66.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1d8c511b2a82c16a43bc7c1f2ca6338f698e4b97b7d662958db24fc13bb697a6
|
|
BLAKE2b-256 checksum How to use checksums |
55d15fe0f2b4eafb68429d66c66df980032a60a0a72895f560471a16c27efbdf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|