chore: add pre-commit hook to forbid committing root-level Go binaries
Build and Publish / BuildAndDeploy (push) Failing after 6s
Build and Publish / BuildAndDeploy (push) Failing after 6s
This commit is contained in:
1 parent
ef80e1745f
commit
c2adf87d54
2 files changed
+61
No files matched your search
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# pre-commit hook: forbid committing compiled Go binaries at the repo root.
|
||||
# Install: `make install-hooks` (idempotent — sets git core.hooksPath hooks/).
|
||||
# Bypass: `git commit --no-verify`.
|
||||
set -euo pipefail
|
||||
|
||||
# Only check newly-added files at exactly the repo root (no subdirs, no modifications).
|
||||
# `2>/dev/null || true` defends against rare git-diff failures (corrupted index, etc.)
|
||||
# propagating through `set -e` and killing the hook before any catches run.
|
||||
# Parens group OR tightly so awk errors aren't accidentally swallowed.
|
||||
STAGED_ROOT_FILES=$( (git diff --cached --name-only --diff-filter=A 2>/dev/null || true) | awk -F/ 'NF==1')
|
||||
[ -z "$STAGED_ROOT_FILES" ] && exit 0
|
||||
|
||||
# Without `go` on PATH we cannot reliably detect build artifacts — warn + exit safe.
|
||||
command -v go >/dev/null 2>&1 || { echo "WARN: go not on PATH; skipping root-binary check." >&2; exit 0; }
|
||||
|
||||
# Use `while IFS= read -r` instead of `for f in $(...)` to be safe against
|
||||
# whitespace in filenames.
|
||||
while IFS= read -r f; do
|
||||
[ -d "$f" ] && continue
|
||||
[ -e "$f" ] || continue
|
||||
|
||||
# Catch 1: a root binary whose name matches a Go cmd/<name>/ package.
|
||||
if [ -d "cmd/$f" ] && ls "cmd/$f"/*.go >/dev/null 2>&1; then
|
||||
echo "REJECT: '$f' looks like the build output of cmd/$f/." >&2
|
||||
echo " 'go build ./cmd/$f/' would produce this file at the repo root." >&2
|
||||
echo " Fix: add /$f to .gitignore, rebuild from cmd/$f/." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Catch 2: executable regular file at root. Broadens coverage to
|
||||
# arbitrary-ELF-at-root with unrelated names (Catch 1 only matches cmd/<n>/).
|
||||
if [ -x "$f" ] && [ -f "$f" ]; then
|
||||
echo "REJECT: '$f' is an executable file at the repo root." >&2
|
||||
echo " Executables at the repo root are treated as build artifacts." >&2
|
||||
echo " Fix: add /$f to .gitignore, or build into cmd/$f/ or internal/." >&2
|
||||
echo " Opt out per-file: git update-index --chmod=-x $f" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Catch 3: the staged root file is itself a buildable Go target.
|
||||
if go build -o /dev/null "./$f" 2>/dev/null; then
|
||||
echo "REJECT: '$f' is a buildable Go target at the root." >&2
|
||||
echo " 'go build ./$f' succeeded, so this is treated as a build artifact." >&2
|
||||
echo " Fix: add /$f to .gitignore, or move source under cmd/$f/ or internal/." >&2
|
||||
exit 1
|
||||
fi
|
||||
done <<< "$STAGED_ROOT_FILES"
|
||||
|
||||
exit 0
|
||||
Reference in new issue
Block a user