From 7da5a82a79cf3b45d76ac73ecdd6da72192f04eb Mon Sep 17 00:00:00 2001 From: Vsevolod Strukchinsky Date: Tue, 30 Jun 2026 19:44:35 +0500 Subject: [PATCH] chore: add devenv development environment Add a devenv (devenv.sh) config pinning the Go toolchain to match go.mod along with golangci-lint, golines, goimports, gopls, and dlv, so the dev environment is reproducible across machines. Includes convenience scripts (build/test/test-race/lint/bench/modernize) wrapping the canonical commands. Wire up direnv auto-activation via .envrc, ignore devenv's generated state in .gitignore (keeping devenv.lock tracked), and document the optional setup in the README. Co-Authored-By: Claude Opus 4.8 (1M context) --- .envrc | 5 +++++ .gitignore | 5 +++++ README.md | 38 +++++++++++++++++++++++++++++++ devenv.lock | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ devenv.nix | 48 +++++++++++++++++++++++++++++++++++++++ devenv.yaml | 5 +++++ 6 files changed, 166 insertions(+) create mode 100644 .envrc create mode 100644 devenv.lock create mode 100644 devenv.nix create mode 100644 devenv.yaml diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..6f3d8d41 --- /dev/null +++ b/.envrc @@ -0,0 +1,5 @@ +# Auto-load the devenv shell via direnv — https://devenv.sh/automatic-shell-activation/ +# Run `direnv allow` once to trust this file. +source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k=" + +use devenv diff --git a/.gitignore b/.gitignore index 4d792c40..2a1da9b4 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,8 @@ interop/certs/ # Local custom prompts CLAUDE.local.md + +# devenv (https://devenv.sh) — generated state; devenv.lock is committed +.devenv* +devenv.local.nix +.direnv/ diff --git a/README.md b/README.md index dc1a23c4..d6a5de51 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,44 @@ golangci-lint run # lint + format check (.golangci.yml) For the benchmark suite and the `benchstat` regression-comparison workflow, see [`benchmarks/README.md`](benchmarks/README.md). +### Development environment (devenv + direnv) + +The repo ships a [devenv](https://devenv.sh) config (`devenv.nix`) that pins the +Go toolchain (matching `go.mod`) plus `golangci-lint`, `golines`, `goimports`, +`gopls`, and `dlv` — so everyone builds against the same versions. It is +optional: a plain `go` install works fine. With [Nix](https://nixos.org) +installed: + +```sh +# One-time: install devenv and direnv. +nix profile add nixpkgs#devenv nixpkgs#direnv +``` + +Then either enter the shell on demand: + +```sh +devenv shell # drops you into a shell with the full toolchain on PATH +devenv test # sanity-check the toolchain wiring +``` + +…or let [direnv](https://direnv.net) load it automatically on `cd` (recommended). +Hook direnv into your shell once (see the +[direnv setup guide](https://direnv.net/docs/hook.html)), e.g. for zsh: + +```sh +echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc +``` + +then trust this repo's `.envrc` once: + +```sh +direnv allow # run from the repo root; re-run if .envrc changes +``` + +After that the environment activates whenever you enter the directory. Inside +the shell, convenience scripts wrap the canonical commands: `build`, `test`, +`test-race`, `lint`, `bench`, and `modernize`. + ### Interoperability tests This implementation is registered (as `moq-go`) in the diff --git a/devenv.lock b/devenv.lock new file mode 100644 index 00000000..84c06e74 --- /dev/null +++ b/devenv.lock @@ -0,0 +1,65 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1782824668, + "narHash": "sha256-/fWk/eiw0PzFSxO2XsPBmiGEe7fB04jC6fro1mn+8+o=", + "owner": "cachix", + "repo": "devenv", + "rev": "a247a920e43d7633e48e9fc0cd95bab53514a72f", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "nixpkgs": { + "inputs": { + "nixpkgs-src": "nixpkgs-src" + }, + "locked": { + "lastModified": 1782132010, + "narHash": "sha256-ZnAVHdVrotp80iIMm5CSR1fdxPlw7Uwmwxb+O/wsgZ8=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "12866ae2dddbc0ab8b329915f8072bb9c75bde89", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs-src": { + "flake": false, + "locked": { + "lastModified": 1781607440, + "narHash": "sha256-rxO+uc/KFbSJp+pgyXRuAX6QlG9hJdnt0BXpEQRXY+U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3e41b24abd260e8f71dbe2f5737d24122f972158", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} \ No newline at end of file diff --git a/devenv.nix b/devenv.nix new file mode 100644 index 00000000..e32f1746 --- /dev/null +++ b/devenv.nix @@ -0,0 +1,48 @@ +{ pkgs, lib, config, ... }: + +{ + # https://devenv.sh/basics/ + # A reproducible Go development environment for moq-go. + + # https://devenv.sh/languages/ + # Provides the Go toolchain (matching go.mod's `go 1.26`) plus go env wiring. + languages.go.enable = true; + + # https://devenv.sh/packages/ + # Tooling the repo expects on PATH. The lint config (.golangci.yml) enables the + # `goimports` and `golines` formatters, so both must be available. + packages = with pkgs; [ + golangci-lint # `golangci-lint run` — see .golangci.yml + golines # long-line formatter enabled in .golangci.yml + gotools # provides goimports + gopls # language server + delve # `dlv` debugger + gnumake # the Makefile drives build/test/interop targets + ]; + + # https://devenv.sh/scripts/ + # Thin wrappers around the canonical commands from CLAUDE.md / the Makefile. + scripts.build.exec = "go build ./..."; + scripts.test.exec = "go test ./..."; + scripts.test-race.exec = "go test -race ./..."; + scripts.lint.exec = "golangci-lint run"; + scripts.bench.exec = "go test -run='^$' -bench=. -benchmem ./..."; + # modernize check (errorsastype) — see CLAUDE.md; run standalone until + # golangci-lint bundles the analyzer. Pass -fix to apply. + scripts.modernize.exec = '' + go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest \ + -errorsastype "$@" ./... + ''; + + enterShell = '' + echo "moq-go devenv — go $(go version | cut -d' ' -f3 | sed 's/go//')" + echo " scripts: build | test | test-race | lint | bench | modernize" + ''; + + # https://devenv.sh/tests/ + # `devenv test` sanity-checks the toolchain wiring. + enterTest = '' + go version + golangci-lint version + ''; +} diff --git a/devenv.yaml b/devenv.yaml new file mode 100644 index 00000000..c7ad7997 --- /dev/null +++ b/devenv.yaml @@ -0,0 +1,5 @@ +# devenv inputs — https://devenv.sh/inputs/ +# `rolling` tracks a recent nixpkgs so the Go toolchain matches go.mod (go 1.26). +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling