make check must not modify tracked files (ensure_pb regenerates mf.pb.go on mtime) #71
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Policy: "
make checkmust not modify any files in the repo."script/test:10-15,script/fmt:14-19, andscript/fmt-check:9-14eachcarry an identical copy of this heuristic:
Git does not preserve mtimes. On a fresh clone or a branch checkout, file
mtimes are set to checkout time in filesystem order, so
mfer/mf.protocaneasily appear newer than the committed
mfer/mf.pb.go. When that happens,script/checksilently regenerates a tracked, committed file — mutating theworking tree as a side effect of a read-only gate, and introducing a hard
protocdependency for anyone runningmake check.The comment in the scripts already concedes the intent: "the generated file
is committed, so this is normally a no-op". "Normally" is the problem.
There are also three divergent copies of the same logic, which is how they
will drift.
Definition of done
make checkprovably does not modify the working tree. Demonstrate it:touch
mfer/mf.protoso it is newer thanmfer/mf.pb.go, runmake check, and confirmgit status --porcelainis empty afterwards.make generate),never as a side effect of
test,lint,fmt-check, orcheck..pb.gois genuinely out of date with respect to the.proto, the check fails loudly with an actionable message tellingthe developer to run the regenerate target — it does not silently fix it.
work across a git checkout and must not be the basis of a gate.
make checkpasses anddocker build .succeeds.TODO.mdupdated inthe same commit.
Implementation requirements
comparing against the committed file, or comparing a recorded hash of the
.proto. Either is fine; mtime is not.protoc, do not makemake checkdepend on
protocbeing installed — that would trade one problem foranother. Skip the staleness check gracefully when the toolchain is absent
and say so, or run the check only in the Docker build where the toolchain
is guaranteed. Decide, and write down which you chose and why.
Dockerfilecurrently works around this exact hazard withRUN touch mfer/mf.pb.goin both the lint and build stages. Once thescripts no longer regenerate on mtime, those two
touchlines are deadworkarounds and must be removed as part of this change.
script/*POSIX sh with no bashisms.(closes #71).