CLI tool for managing environment variable sets bound to named profiles or working directories.
Project description
dotgoblin
CLI tool for managing environment variable sets bound to named profiles or working directories. Secrets stay off disk via shell interpolation at runtime.
Installation
With uv (recommended)
# Run directly without installing
uvx dotgoblin --help
# Install globally
uv tool install dotgoblin
# Install from source
uv tool install .
# Or add to a project
uv add dotgoblin
With pip
pip install dotgoblin
From source
git clone https://github.com/frizzy/dotgoblin.git
cd dotgoblin
uv sync
Quick start
# Create a set
dotgoblin set create myapp
# Add variables
dotgoblin var set myapp DATABASE_URL "postgres://localhost:5432/app"
dotgoblin var set myapp API_KEY '$(pass show myapp/api-key)'
# Bind your project directory to the set
cd ~/Code/myapp
dotgoblin bind myapp
# Run a command with the injected env
dotgoblin -- flask run
# Or reference a set explicitly
dotgoblin --set myapp -- flask run
# Preview what would be injected
dotgoblin --dry-run -- flask run
Concepts
- Set — a named collection of environment variables stored as TOML
- Binding — maps a working directory to a set, so
dotgoblin -- <cmd>auto-selects it - Section — sets can have named sections (e.g.
local,prod) that override base variables - Secret interpolation — values like
$(pass show key)are evaluated at runtime, keeping secrets off disk
Storage
All config lives in ~/.config/dotgoblin/ (override with DOTGOBLIN_DIR):
~/.config/dotgoblin/
├── sets/
│ ├── myapp.toml
│ └── ...
└── bindings.toml
Set file format
# Top-level variables apply to all sections
APP_NAME = "myapp"
[_meta]
default = "local"
[local]
DATABASE_URL = "postgres://localhost:5432/app"
API_KEY = "$(pass show local/api-key)"
[prod]
DATABASE_URL = "postgres://prod.db:5432/app"
API_KEY = "$(pass show prod/api-key)"
Commands
Run a command
dotgoblin -- <command...>
dotgoblin --set <name> -- <command...>
dotgoblin --set <name>:<section> -- <command...>
dotgoblin --set :<section> -- <command...> # use bound set with specific section
dotgoblin --dry-run -- <command...>
Variables are merged on top of your current shell environment.
Manage sets
dotgoblin set create <name> # create a new empty set
dotgoblin set list # list all sets
dotgoblin set show <name> # show variables (secrets shown as raw expressions)
dotgoblin set cat <name> # print resolved env in envfile format (--export for `export …`)
dotgoblin set edit <name> # open in $EDITOR
dotgoblin set rm <name> # delete (fails if bound)
Manage variables
dotgoblin var set <set> <KEY> <value> # set a variable
dotgoblin var rm <set> <KEY> # remove a variable
Bindings
Multiple directories can be bound to the same set.
dotgoblin bind [<set-name>] # bind current directory to a set
dotgoblin bind add <set-name> <dir> # bind an arbitrary directory
dotgoblin bind list [<set-name>] # list all bindings (or filter by set)
dotgoblin bind rm [<directory>] # remove a binding (default: cwd)
dotgoblin unbind # shortcut for bind rm
dotgoblin status # show active set and variables
If bind is called without a set name, an anonymous set is created automatically.
Secret interpolation
Any value containing $(...) is treated as a shell expression and evaluated at runtime. This keeps secrets out of the store files.
API_KEY = "$(pass show myapp/api-key)"
TOKEN = "Bearer $(cat ~/.tokens/myapp)"
DB_PASS = "$(op read 'op://Vault/DB/password')"
Interpolation only happens during dotgoblin -- <cmd> and --dry-run. All other commands display the raw expression. If a command fails, dotgoblin aborts with the failing key and stderr.
Resolution order
--set <name>flag (explicit, highest priority)- Directory binding (from
bindings.toml) - Error: no set found
Environment
| Variable | Description |
|---|---|
DOTGOBLIN_DIR |
Override config directory (default: ~/.config/dotgoblin/) |
EDITOR |
Editor used by dotgoblin set edit (default: vi) |
License
MIT
Project details
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 dotgoblin-0.1.0.tar.gz.
File metadata
- Download URL: dotgoblin-0.1.0.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de6caf544a91f56f052c8c729b134c7999bcc463a0c18506f1b3703f1f2472d8
|
|
| MD5 |
1c58065ab1ec850d8069c23f155b683f
|
|
| BLAKE2b-256 |
839bfbe01e97dcf07e5e193ad23a0de7f55b40ab35ee53293ee76ea1afb3572d
|
File details
Details for the file dotgoblin-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dotgoblin-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46bb884d6bee8367a1d98c1e046da4d39d13e749bb853e8420831f0b1765798c
|
|
| MD5 |
789b3eafd809db7ea4e03dc2cd7fcefc
|
|
| BLAKE2b-256 |
6b381ecb0440dfe45848686d6a7c548f83c28a5acd647f3bb5f2253047eaf685
|