Files
kandev/scripts/resolve-go-lint-base.test.sh
T
2026-08-27 10:08:04 +00:00

155 lines
6.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# resolve-go-lint-base.test.sh — regression coverage for the Go lint hook's
# comparison base. A fork's origin can be stale, so the resolver must prefer
# the conventional canonical upstream ref without weakening lint enforcement.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RESOLVER="$ROOT_DIR/scripts/resolve-go-lint-base"
status=0
fail() {
printf 'FAIL %s\n' "$*"
status=1
}
expect_eq() {
local label=$1 want=$2 got=$3
if [ "$got" = "$want" ]; then
printf 'ok %-34s %s\n' "$label" "$got"
else
fail "$label (want $want, got $got)"
fi
}
expect_fail() {
local label=$1 needle=$2 repo=$3 output
if output=$(cd "$repo" && "$RESOLVER" 2>&1); then
fail "$label (unexpected success: $output)"
elif [[ "$output" == *"$needle"* ]]; then
printf 'ok %-34s %s\n' "$label" "$needle"
else
fail "$label (expected $needle in: $output)"
fi
}
new_repo() {
local repo
repo=$(mktemp -d)
git -C "$repo" init -q
git -C "$repo" config user.email test@example.com
git -C "$repo" config user.name 'Hook test'
git -C "$repo" commit --allow-empty -qm initial
git -C "$repo" branch -M main
git -C "$repo" remote add origin https://example.test/fork.git
git -C "$repo" update-ref refs/remotes/origin/main HEAD
git -C "$repo" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
echo "$repo"
}
fork_repo="" single_repo="" release_repo="" configured_repo=""
dangling_repo="" ambiguous_repo="" unsafe_repo="" history_repo="" missing_repo=""
full_ref_repo="" collision_repo="" untrusted_repo="" namespace_repo=""
diverged_repo="" merge_repo=""
cleanup() {
local repo
for repo in "$fork_repo" "$single_repo" "$release_repo" "$configured_repo" \
"$dangling_repo" "$ambiguous_repo" "$unsafe_repo" "$history_repo" "$missing_repo" \
"$full_ref_repo" "$collision_repo" "$untrusted_repo" "$namespace_repo" \
"$diverged_repo" "$merge_repo"; do
[ -z "$repo" ] || rm -rf "$repo"
done
}
trap cleanup EXIT
fork_repo=$(new_repo)
git -C "$fork_repo" remote add upstream git@github.com:kdlbs/kandev.git
git -C "$fork_repo" update-ref refs/remotes/upstream/main HEAD
expect_eq 'fork prefers canonical upstream' 'refs/remotes/upstream/main' "$(cd "$fork_repo" && "$RESOLVER")"
single_repo=$(new_repo)
expect_eq 'single remote uses origin default' 'refs/remotes/origin/main' "$(cd "$single_repo" && "$RESOLVER")"
release_repo=$(new_repo)
git -C "$release_repo" update-ref -d refs/remotes/origin/main
git -C "$release_repo" update-ref refs/remotes/origin/release HEAD
git -C "$release_repo" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/release
git -C "$release_repo" remote add upstream https://github.com/kdlbs/kandev.git
git -C "$release_repo" update-ref refs/remotes/upstream/release HEAD
expect_eq 'non-main default follows upstream' 'refs/remotes/upstream/release' "$(cd "$release_repo" && "$RESOLVER")"
configured_repo=$(new_repo)
git -C "$configured_repo" remote add upstream https://github.com/kdlbs/kandev.git
git -C "$configured_repo" update-ref refs/remotes/upstream/release HEAD
git -C "$configured_repo" config kandev.lintBaseRef upstream/release
expect_eq 'configured ref is honored' 'refs/remotes/upstream/release' "$(cd "$configured_repo" && "$RESOLVER")"
dangling_repo=$(new_repo)
git -C "$dangling_repo" config kandev.lintBaseRef upstream/main
expect_fail 'missing configured ref fails closed' 'does not resolve' "$dangling_repo"
ambiguous_repo=$(new_repo)
git -C "$ambiguous_repo" config --add kandev.lintBaseRef origin/main
git -C "$ambiguous_repo" config --add kandev.lintBaseRef upstream/main
expect_fail 'multiple configured refs fail closed' 'ambiguous' "$ambiguous_repo"
missing_repo=$(new_repo)
git -C "$missing_repo" update-ref -d refs/remotes/origin/main
expect_fail 'missing default ref fails closed' 'does not resolve' "$missing_repo"
unsafe_repo=$(new_repo)
git -C "$unsafe_repo" config kandev.lintBaseRef 'origin/main --not-a-ref'
expect_fail 'unsafe configured ref is rejected' 'safe ref format' "$unsafe_repo"
history_repo=$(new_repo)
git -C "$history_repo" branch previous
git -C "$history_repo" switch -q previous
git -C "$history_repo" switch -q main
git -C "$history_repo" config kandev.lintBaseRef '@{-1}'
expect_fail 'checkout history is not a base ref' 'remote-tracking' "$history_repo"
full_ref_repo=$(new_repo)
expect_eq 'resolver emits fully qualified ref' 'refs/remotes/origin/main' "$(cd "$full_ref_repo" && "$RESOLVER")"
collision_repo=$(new_repo)
git -C "$collision_repo" tag origin/main
expect_eq 'tag collision still selects remote ref' 'refs/remotes/origin/main' "$(cd "$collision_repo" && "$RESOLVER")"
untrusted_repo=$(new_repo)
git -C "$untrusted_repo" remote add upstream https://example.test/not-kandev.git
git -C "$untrusted_repo" update-ref refs/remotes/upstream/main HEAD
expect_fail 'untrusted upstream fails closed' 'canonical' "$untrusted_repo"
namespace_repo=$(new_repo)
git -C "$namespace_repo" config kandev.lintBaseRef refs/heads/main
expect_fail 'configured local branch is rejected' 'remote-tracking' "$namespace_repo"
diverged_repo=$(new_repo)
git -C "$diverged_repo" branch feature
git -C "$diverged_repo" switch -q feature
git -C "$diverged_repo" commit --allow-empty -qm feature
git -C "$diverged_repo" switch -q main
git -C "$diverged_repo" commit --allow-empty -qm base-advance
diverged_base=$(git -C "$diverged_repo" rev-parse HEAD)
diverged_fork=$(git -C "$diverged_repo" rev-parse HEAD~1)
git -C "$diverged_repo" update-ref refs/remotes/origin/main "$diverged_base"
git -C "$diverged_repo" switch -q feature
expect_eq 'diverged history uses merge base' "$diverged_fork" "$(cd "$diverged_repo" && "$RESOLVER" --comparison-base)"
merge_repo=$(new_repo)
git -C "$merge_repo" branch feature
git -C "$merge_repo" switch -q feature
git -C "$merge_repo" commit --allow-empty -qm feature
git -C "$merge_repo" switch -q main
git -C "$merge_repo" commit --allow-empty -qm base-advance
merge_base_tip=$(git -C "$merge_repo" rev-parse HEAD)
git -C "$merge_repo" update-ref refs/remotes/origin/main "$merge_base_tip"
git -C "$merge_repo" switch -q feature
printf '%s\n' "$merge_base_tip" > "$merge_repo/.git/MERGE_HEAD"
expect_eq 'base merge keeps incoming tip' "$merge_base_tip" "$(cd "$merge_repo" && "$RESOLVER" --comparison-base)"
if [ "$status" -eq 0 ]; then
echo 'All Go lint base resolver checks passed.'
fi
exit "$status"