A CLI tool for running commands with additional environment variables read from config files instead of exported or prefixing every call. Made because I got sick of forgetting to set/unset something and prefer commandline flags over environment variables.
Particularly helpful if you're doing a lot torch/triton tweaking.
Instead of:
TORCHINDUCTOR_FORCE_DISABLE_CACHES=1 TRITON_ALWAYS_COMPILE=1 python prog.pyYou can:
# TORCHINDUCTOR_FORCE_DISABLE_CACHES always set to 1 by config file,
# TRITON_ALWAYS_COMPILE gets toggle flag from config file!
tacoshop --triton python train.pyRequires Python 3.11+. No runtime dependencies.
pip install -e .
Generate a starter config with commented-out examples:
tacoshop initOr create a tacoshop.toml in your project directory by hand:
TORCHINDUCTOR_FORCE_DISABLE_CACHES = 1
[TRITON_ALWAYS_COMPILE]
flag = "--triton"
value = 1
description = "Force Triton to always recompile kernels"
[TORCH_LOGS]
flag = "--logs"
description = "Set torch logging channels (e.g. +dynamo)"Then run your program through tacoshop:
# Static vars are always set
tacoshop python train.py
# Activate a flag-toggled var
tacoshop --triton python train.py
# Supply a value at the command line
tacoshop --logs "+dynamo" python train.py
# Combine them
tacoshop --triton --logs "+dynamo" python train.pyTop-level key-value pairs are set every time tacoshop runs:
TORCHINDUCTOR_FORCE_DISABLE_CACHES = 1
MY_STRING_VAR = "hello"For more control (description, append mode), use the table form:
[MY_VAR]
value = 42
description = "Always-on var with a description"Table entries with a flag field create CLI flags that activate the variable:
# Boolean toggle — flag activates a preset value
[TRITON_ALWAYS_COMPILE]
flag = "--triton"
value = 1
description = "Force Triton to always recompile kernels"
# Value-required — user supplies the value at the CLI
[TORCH_LOGS]
flag = "--logs"
description = "Set torch logging channels"Instead of replacing an existing env var, you can add to it. append = true adds to the end, prepend = true adds to the front. The separator field controls the join character (default: empty string). You cannot set both on the same variable.
The separator is inserted between the existing and new values automatically. If the join edge already has the separator, it won't be doubled.
[TORCH_LOGS]
flag = "--logs"
append = true
separator = ","
description = "Append to torch logging channels"
[PYTHONPATH]
value = "/my/modules"
prepend = true
separator = ":"
description = "Ensure my modules are found first"Given TORCH_LOGS="+inductor" and PYTHONPATH="/existing/path" in the calling environment:
tacoshop --logs "+dynamo" python train.py
# TORCH_LOGS="+inductor,+dynamo" ← appended with "," separator
# PYTHONPATH="/my/modules:/existing/path" ← prepended with ":" separatorBoth modes work for static and flag-mapped variables.
| TOML type | Env var value |
|---|---|
| Integer | str() (e.g. 1 → "1") |
| Float | str() (e.g. 3.14 → "3.14") |
| Boolean | true → "1", false → "0" |
| String | As-is |
| Form | Has flag? |
Has value? |
Behavior |
|---|---|---|---|
| Top-level scalar | — | — | Static, always set |
| Table | Yes | Yes | Flag activates preset value |
| Table | Yes | No | Flag with required CLI value |
| Table | No | Yes | Static (verbose form, allows description/append) |
| Table | No | No | Error |
Tacoshop loads config files from up to three locations, lowest to highest priority:
- System-wide:
~/.tacoshop.toml - Repo-level:
tacoshop.tomlor.tacoshop.tomlat the git repository root - Directory-level:
tacoshop.tomlor.tacoshop.tomlin the current working directory
At each level, the non-dotfile name is preferred. Higher-priority files overwrite lower-priority ones per variable name. If the git root is the same as the current directory, only one copy is loaded.
Use tacoshop trace to see which files were loaded and what they define. Helpful for making sure everything is set how you expect!
tacoshop [FLAGS...] COMMAND [ARGS...]Tacoshop flags are parsed left to right. The first unrecognized token starts the wrapped command — everything from that point onward is passed through untouched, including the command's own flags:
tacoshop --triton python train.py --epochs 10 --verbose
# ^^^^^^^^ tacoshop flag
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ commandUse -- to explicitly separate tacoshop flags from the command:
tacoshop --triton -- python train.py| Flag | Description |
|---|---|
--help, -h |
Show help (includes config-defined flags) |
--verbose, -v |
Print each env var to stderr before running |
--dry-run |
Show env vars and command without executing |
--version |
Print version |
tacoshop help — Show help (same as --help / -h).
tacoshop trace — Display all configured variables with a load-order trace showing how each value is set, overwritten, appended, or prepended across config files and the calling environment.
tacoshop init — Create a tacoshop.toml template in the current directory with commented-out examples of each config style. Refuses to overwrite an existing file.
tacoshop print COMMAND [ARGS...] — Print a copy-pasteable one-liner with env var prefixes, useful for sharing with someone who doesn't have tacoshop:
$ tacoshop --triton print python train.py
TORCHINDUCTOR_FORCE_DISABLE_CACHES=1 TRITON_ALWAYS_COMPILE=1 python train.pytacoshop dumpenv [-o FILE] — Export managed env vars as a bash-sourceable shell script. Respects flags: tacoshop --triton dumpenv includes the flag-toggled variable in the output. Writes to stdout by default, or to a file with -o.
Tacoshop is transparent: stdin, stdout, and stderr are passed through to the wrapped command. The exit code is forwarded. All tacoshop-internal output goes to stderr so piping and redirection work as expected:
tacoshop python train.py | tee output.log
tacoshop python -c "exit(42)"; echo $? # prints 42