-
Notifications
You must be signed in to change notification settings - Fork 0
Global Config
letsgo.mod describes a release, and travels with the repository. config.mod
describes a machine, and does not.
The rule that separates them: nothing in the global file may change what a release is. Not a byte of output, not a gate, not a version, not where something is published. If a setting could make your laptop and CI produce different releases from the same commit, it does not belong here — and letsgo rejects it rather than letting it quietly work.
os.UserConfigDir()/letsgo/config.mod
which is ~/.config/letsgo/config.mod on Linux,
~/Library/Application Support/letsgo/config.mod on macOS, and
%AppData%\letsgo\config.mod on Windows. $LETSGO_CONFIG points somewhere
else. A missing default file is fine; a LETSGO_CONFIG pointing at a missing
file is an error, because that one was asked for.
It is the same directive syntax as letsgo.mod, and
letsgo fmt formats it.
// ~/.config/letsgo/config.mod
go /usr/local/go1.27.1/bin/go
git /usr/bin/git
cache /mnt/big/letsgo-cache
plugins /mnt/big/letsgo-plugins
plugin-repo acme/letsgo-plugins-mirror
proxy https://goproxy.acme.internal
color auto
update-check weekly
| Directive | What it sets |
|---|---|
go <path> |
The Go toolchain to run |
git <path> |
The git to run |
tool <name> <path> |
Where to find a named tool, such as govulncheck or apidiff
|
cache <dir> or cache off
|
The build cache |
plugins <dir> |
The plugin store root |
plugin-repo <owner/name> |
Where letsgo plugin install fetches from |
proxy <url> |
The module proxy to warm |
token-command <argv...> |
A credential helper for the forge token |
| `color auto | always |
| `update-check off | daily |
That is the complete set. Anything else — build, brew, image, disable,
project — is an error naming the directive and saying it belongs in
letsgo.mod. The error is the feature: a build linux/amd64 that worked here
would mean a release whose targets depend on whose machine ran it.
flag > environment > global > default.
A flag beats everything, because it was typed for this run. The environment beats the global file, because CI sets the environment and CI should not have to know what is in a developer's home directory. The global file beats the built-in default, which is the only thing it is allowed to beat.
letsgo plan --explain names the source of every machine value, so you can see
which layer won:
proxy https://goproxy.acme.internal ~/.config/letsgo/config.mod
go /usr/local/go1.27.1/bin/go ~/.config/letsgo/config.mod
cache /mnt/big/letsgo-cache ~/.config/letsgo/config.mod
No global value ever reaches the manifest — with one exception that was already there, the Go version, which is a build input and recorded as one. The path you found that Go at is not.
A credential helper, for people who keep forge tokens in a password manager or a short-lived issuer rather than in an environment variable:
token-command op read op://vault/github/token
It runs only when neither a flag nor the environment has already supplied a token, so it never overrides something more explicit. Its output is used and not written anywhere: not logged, not cached, not put in the manifest.
A token-command that exits non-zero falls through to "no token", with its
standard error shown. That is the useful failure — a broken helper should look
like a missing token and say why, rather than aborting a command that might not
have needed one.
Before it, the machine-specific settings had nowhere to go but letsgo.mod,
which meant either committing your own paths to a shared repository or carrying
a local diff forever. Splitting them is what makes it possible to check the
global file against a hard rule — and a rule that is checked is worth more than
a convention that is documented.
Start here
Releasing
Checking
Extending
Running it
About