Tools
Useful tools.
Go linting¶
Use ./build.sh lint from the repository root. It checks shell formatting
and authored text with Opengrep, then runs golangci-lint v2; a globally
installed v1 binary cannot read .golangci.yaml. It validates the Go linter
configuration and exits nonzero for findings. It does not apply fixes.
The first run needs network access to download dependencies and may take
longer while Go compiles the tool.
Apply available automatic fixes before fixing remaining findings by hand. From the repository root, run:
| Bash | |
|---|---|
This command rewrites source files. Review the diff, fix any remaining
findings, then rerun ./build.sh lint to check the result. Not every linter
supports autofix. build.sh does not forward flags to the linter, so use the
direct command above rather than ./build.sh lint --fix.
The tool version and dependencies are pinned in tools/golangci-lint.mod
and tools/golangci-lint.sum, separate from the application module. This
follows upstream's dedicated module-file guidance
to avoid mixing linter dependencies with application and build-tool
dependencies. Upstream recommends release binaries for general installation;
the isolated Go tool lets this repository build the linter with its required
Go toolchain without relying on a global installation.
To inspect the pinned tool or validate only the configuration:
| Bash | |
|---|---|
To upgrade, choose a stable release from the upstream release
notes that
supports the repository's Go version, replace
vX.Y.Z below with that version, and run:
| Bash | |
|---|---|
Commit both tool module files and any required configuration updates. Do not
upgrade the tool's transitive dependencies independently. Review the enabled
linters when upgrading: .golangci.yaml enables all linters except its
explicit exclusions, so releases can add checks and findings.
JavaScript tooling¶
Use Node.js 22+ and pnpm. The versions of
Tailwind CSS, Prettier, Playwright, and Wrangler are pinned in package.json
and resolved in pnpm-lock.yaml. pnpm-workspace.yaml permits only the
native build scripts required by these dependencies. Install from the root:
Use pnpm css:watch while changing styles and pnpm exec prettier for
formatting. pnpm exec playwright and pnpm exec wrangler run the same
versions used in the CI images. The Playwright browser-image tag must match
the pinned Playwright package version.
The compiled CSS is tracked. ./build.sh build only regenerates it if it is
missing; run pnpm css:build after changing Tailwind classes or source CSS.
Go-only builds do not require installing JavaScript dependencies while the
compiled CSS exists.
Shell formatting¶
shfmt is pinned in go.mod as a Go tool.
Format tracked .sh and .bash files (excluding Fish scripts), or check them
without modifying the working tree:
./build.sh format formats shell, templ and Go sources without building.
./build.sh build does not format sources. CI runs the shell check on
branches and tags.
Opengrep¶
Opengrep is a non-sucky version of Semgrep that doesn't hide features.
Download it at https://github.com/opengrep/opengrep/releases/.
For Arch Linux users
If you get libcrypt.so.1: cannot open shared object file, install libxcrypt-compat with sudo pacman -S libxcrypt-compat.
Common usage:
| Bash | |
|---|---|
The blocking Opengrep rules live in opengrep.lint.yaml and run through
./build.sh lint and GitLab CI. opengrep.yaml contains non-blocking
i18n message inventory rules. No separate Opengrep command is needed
before committing; ./build.sh lint also runs the Go analyzers.
goimports-reviser¶
This tool organizes imports into three groups -- std, 3rdparty, ours.
Install with
| Bash | |
|---|---|
Format all code:
| Bash | |
|---|---|