Summary
Makefile:55-56 is the ensure_golangci-lint prerequisite of make lint:
ensure_golangci-lint:
@$HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade golangci-lint
It has two independent defects. On a machine without golangci-lint,
make lint never reaches the linter:
Error: golangci-lint not installed
make: *** [ensure_golangci-lint] Error 1
Defect 1: $HOMEBREW_NO_AUTO_UPDATE is expanded by make, not the shell
GNU make expands $ followed by a single character as a one-character
variable name, so $HOMEBREW_NO_AUTO_UPDATE is read as the make variable H
followed by the literal text OMEBREW_NO_AUTO_UPDATE. H is undefined here,
so the recipe sets a variable named OMEBREW_NO_AUTO_UPDATE and
HOMEBREW_NO_AUTO_UPDATE is never set.
Reproduced with a probe makefile containing the same line. Undefined H:
$ make -f probe -n demo
echo OMEBREW_NO_AUTO_UPDATE=1 brew upgrade golangci-lint
Adding H := ZZZ to the same probe puts ZZZ exactly where the H was,
confirming which variable is being expanded:
$ make -f probe2 -n demo
echo ZZZOMEBREW_NO_AUTO_UPDATE=1 brew upgrade golangci-lint
Consequence: brew auto-update is not suppressed, so make lint triggers a full
brew update (and, past its 30 day interval, brew cleanup) before doing any
work. That is slow, and it mutates the developer's brew installation as a side
effect of running the project's linter.
Defect 2: brew upgrade cannot install a missing formula
brew upgrade <formula> requires the formula to be installed already. On a
fresh machine, or any machine that never installed golangci-lint, the target
fails with "Error: golangci-lint not installed" and make lint stops before
running golangci-lint run. The developer gets a brew error rather than a
lint result, and no hint about what to install.
Suggested fix
Set the env var so make passes it through to the shell, and make the target
idempotent for install-or-upgrade:
ensure_golangci-lint:
@HOMEBREW_NO_AUTO_UPDATE=1 brew list golangci-lint >/dev/null 2>&1 \
|| HOMEBREW_NO_AUTO_UPDATE=1 brew install golangci-lint
Notes for whoever picks this up:
HOMEBREW_NO_AUTO_UPDATE=1 with no $ is the simplest correct form.
$$HOMEBREW_NO_AUTO_UPDATE=1 also reaches the shell intact but reads as a
reference rather than an assignment, so prefer the plain form.
- Consider whether the target should upgrade at all. CI does not use brew: the
lint job in .github/workflows/test.yml:96-102 uses
golangci-lint-action@v9 with version: latest. A local target that only
ensures presence keeps local and CI behaviour aligned without surprise
upgrades.
- The repo's
.golangci.yml declares version: "2", so whatever mechanism is
chosen must provide golangci-lint v2.
- Alternative that needs no brew at all, if the team prefers pinning:
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@<version> run
Acceptance
make lint on a machine without golangci-lint installs it and reports lint
results, rather than failing with a brew error
make lint does not trigger brew update or brew cleanup
make lint on a machine that already has golangci-lint still works
Summary
Makefile:55-56is theensure_golangci-lintprerequisite ofmake lint:It has two independent defects. On a machine without golangci-lint,
make lintnever reaches the linter:Defect 1:
$HOMEBREW_NO_AUTO_UPDATEis expanded by make, not the shellGNU make expands
$followed by a single character as a one-charactervariable name, so
$HOMEBREW_NO_AUTO_UPDATEis read as the make variableHfollowed by the literal text
OMEBREW_NO_AUTO_UPDATE.His undefined here,so the recipe sets a variable named
OMEBREW_NO_AUTO_UPDATEandHOMEBREW_NO_AUTO_UPDATEis never set.Reproduced with a probe makefile containing the same line. Undefined
H:Adding
H := ZZZto the same probe putsZZZexactly where theHwas,confirming which variable is being expanded:
Consequence: brew auto-update is not suppressed, so
make linttriggers a fullbrew update(and, past its 30 day interval,brew cleanup) before doing anywork. That is slow, and it mutates the developer's brew installation as a side
effect of running the project's linter.
Defect 2:
brew upgradecannot install a missing formulabrew upgrade <formula>requires the formula to be installed already. On afresh machine, or any machine that never installed golangci-lint, the target
fails with "Error: golangci-lint not installed" and
make lintstops beforerunning
golangci-lint run. The developer gets a brew error rather than alint result, and no hint about what to install.
Suggested fix
Set the env var so make passes it through to the shell, and make the target
idempotent for install-or-upgrade:
Notes for whoever picks this up:
HOMEBREW_NO_AUTO_UPDATE=1with no$is the simplest correct form.$$HOMEBREW_NO_AUTO_UPDATE=1also reaches the shell intact but reads as areference rather than an assignment, so prefer the plain form.
lint job in
.github/workflows/test.yml:96-102usesgolangci-lint-action@v9withversion: latest. A local target that onlyensures presence keeps local and CI behaviour aligned without surprise
upgrades.
.golangci.ymldeclaresversion: "2", so whatever mechanism ischosen must provide golangci-lint v2.
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@<version> runAcceptance
make linton a machine without golangci-lint installs it and reports lintresults, rather than failing with a brew error
make lintdoes not triggerbrew updateorbrew cleanupmake linton a machine that already has golangci-lint still works