Project
Contributing
The scope, the Makefile targets, the layout of the code, the rules for a change and the AI disclosure.
Glazier is a one-person project that grew a test matrix larger than itself. If you want to add to it, this page is the short version of what the repository expects from a change. The long version is CONTRIBUTING.md, and the very long version, the one with the reasoning behind every odd decision, is AGENTS.md. Read that one before you “simplify” anything in the command runner. Each piece is there because a shell bit me.
Scope
In scope:
- The profile syntax.
- The tmux client library.
- The CLI commands.
- The quality of the diagnostics.
- The documentation.
Out of scope:
- Anything that belongs in your
tmux.conf, for example key bindings or the status line. - Support for a multiplexer other than tmux.
Getting started
You need Go 1.26 or later and tmux on your PATH. The end-to-end test skips itself without tmux, but you want it to run.
$ git clone https://github.com/wilhelm-murdoch/glazier.git
$ cd glazier
$ make test
The Makefile pins each tool and runs it with go run <tool>@<version>. No global install and no bootstrap script is necessary. The pinned tools download on first use.
Makefile targets
| Target | What it does |
|---|---|
make test | Runs the unit tests with gotestsum. |
make race | Runs the unit tests under the race detector. CGO is required. |
make lint | Runs golangci-lint with gosec. The configuration is in .golangci.yml. |
make cover | Runs the unit tests with coverage. It fails under the 80% floor. |
make vuln | Runs the govulncheck vulnerability scan. |
make fuzz | Finds and runs each native Go Fuzz* target. FUZZTIME is 10 s for each target. |
make vet | Runs go vet. |
make fmt | Runs gofmt on the tree. |
make build | Builds a version-stamped binary at bin/<os>-<arch>/glaze. |
make e2e | Runs every end-to-end case on the tmux in your PATH. Set RUN='TestX/case' to filter. |
make e2e-matrix | Runs every end-to-end case on six tmux targets in Docker. Set BASE=github/main to compare with a base revision. |
make all | Runs deps, build, test, race, lint, cover, vuln and the checks of the e2e module. |
CI calls these same targets. A green local make all is a green build. CI also runs the tests on macOS, on the minimum supported Go version and on the latest stable release, and runs the end-to-end matrix. See Compatibility for the targets.
How the code is organised
cmd/glaze/main.gowires the CLI withurfave/cli/v3. There is one entry for each subcommand.cmd/glaze/actions/holds one file for each subcommand.base.goholds the shared profile resolution and the diagnostics scaffolding.internal/spec/holds thehcldecspecification tree for the profile schema.internal/decoders/decodes the rawcty.Valueinto the typedSession,WindowandPanestructs.internal/parser/wrapshclparse, collects the variables from--varandGLAZE_ENV_*and holds the template function table.internal/diagnostics/renders the Terraform-style diagnostics and holds the custom validators for layout strings, directories and sizes.pkg/tmux/is the tmux client library. Every tmux call goes through theCommanderinterface, which is the seam that the tests use.e2e_test.godrives a real tmux server on a throwaway socket.pkg/files/resolves the profile path and expands~.e2e/is a separate module. It runs the compiled binary against real tmux servers and never imports Glazier.
Adding or changing behaviour
- New behaviour needs a test. Fakes go through
tmuxtest.RecorderorOverrideCommandFactory. Never start tmux in a unit test. - A change that touches shared mutable state must stay safe under
-race. Runmake race. - A user-facing error is an HCL diagnostic where a profile is involved. Extend the validators in
internal/diagnostics. Do not return a bare error. - A new profile attribute needs a spec entry, a decoder field, a validator if the value is constrained, documentation in the README and a test at each layer.
Pull requests
- Keep a change focused. Put unrelated work in a separate pull request.
- Write a clear, imperative commit message that explains the why.
- Make sure that
make test,make race,make lintandmake vetpass. - Add a test for each new behaviour.
For a security problem, do not open a pull request or a public issue. See Security and SECURITY.md.
Licence
Glazier is released under the MIT Licence. When you contribute, you agree that your work is licensed under the same licence.
AI disclosure
The architecture, the functionality and the base structure of this project are my own. I use AI as a tool for time-consuming work: documentation, tests and bug hunting. I also use it as a sounding board for structural decisions that keep the project easy to adopt and maintain. For a solo developer it is a force multiplier for high-quality code. There is always a human as a final verification step. It is a tool for drudgery and toil, not a crutch.