Replaces #559, which conflicted. Model: opus-5-5
This commit is contained in:
+13
-45
@@ -1,55 +1,23 @@
|
||||
#!/bin/sh
|
||||
# script/lint: run the linter. golangci-lint is never installed locally: it
|
||||
# runs via docker only, one way, everywhere — script/lint builds
|
||||
# Dockerfile.lint, which COPYs the repo into the pinned golangci-lint image
|
||||
# and lints as a build step. This works even when the docker daemon is remote
|
||||
# and bind mounts are impossible, and it removes the host linter's shared
|
||||
# cache, which has attributed other checkouts' findings to this one.
|
||||
# script/lint: run the linter. Linting is a phase of the Dockerfile and
|
||||
# this builds that phase alone; the linter is never installed or run on
|
||||
# a developer host, where a shared result cache and a host-global lock
|
||||
# make its answer untrustworthy.
|
||||
#
|
||||
# --no-cache-filter=lint forces the lint stage to re-execute on every run; a
|
||||
# cached lint stage exits 0 in under a second having linted nothing. The deps
|
||||
# stage keeps its cache, so module downloads are not repeated.
|
||||
# --progress=plain keeps the linter's own output visible on success, so a
|
||||
# passing run shows the issue count rather than nothing.
|
||||
# --output=type=cacheonly leaves no image behind to clean up.
|
||||
#
|
||||
# docker silently ignores --no-cache-filter for a stage name that does not
|
||||
# match, so a rename or a typo would restore the cached false green with no
|
||||
# warning and a fast exit 0. The flag is therefore not trusted: the build
|
||||
# output is teed to a log and a run is only a pass if golangci-lint's own
|
||||
# summary line ("N issues." / "N issues:") is in it. No summary, no lint,
|
||||
# whatever the exit code says.
|
||||
# The phase is not the last stage in the file, so it is built only when
|
||||
# --target names it. --no-cache because a cached lint layer is a lint
|
||||
# that did not run. The tag makes each build replace the previous image
|
||||
# instead of leaving a dangling one behind.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
|
||||
log="$(mktemp -t webhooker-lint.XXXXXXXX)"
|
||||
rcfile="$(mktemp -t webhooker-lint-rc.XXXXXXXX)"
|
||||
trap 'rm -f "$log" "$rcfile"' EXIT INT TERM
|
||||
|
||||
# The pipeline's status is tee's, and POSIX sh has no pipefail, so the
|
||||
# build's status travels via a file. Output still streams live.
|
||||
{
|
||||
docker build \
|
||||
-f Dockerfile.lint \
|
||||
--no-cache-filter=lint \
|
||||
--progress=plain \
|
||||
--output=type=cacheonly \
|
||||
. 2>&1 && echo 0 >"$rcfile" || echo $? >"$rcfile"
|
||||
} | tee "$log" >&2
|
||||
|
||||
rc="$(cat "$rcfile")"
|
||||
[ "$rc" -eq 0 ] || exit "$rc"
|
||||
|
||||
if ! grep -qE '[0-9]+ issues[.:]' "$log"; then
|
||||
echo "script/lint: golangci-lint printed no summary line; the linter" >&2
|
||||
echo " did not run. Check that the stage named in --no-cache-filter" >&2
|
||||
echo " still matches a stage in Dockerfile.lint." >&2
|
||||
exit 1
|
||||
fi
|
||||
docker build --no-cache \
|
||||
--target lint \
|
||||
-t "$("$SCRIPT_DIR/projectname")-lint" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user