- Align Git-backed source enumeration with the fallback scan - Prove tracked historical imports are ignored in self-test
169 lines
4.5 KiB
Bash
Executable File
169 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Phase 10.2 fail-closed gate for the nested framework layout and onboarding.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
APP="$(cd "$ROOT/../fonoteka.go" && pwd)"
|
|
NAMES=(backpack boardwalk bonfire bouncer cabana compass festival fetchguard lagoon pact party phrasebook postcard surf tide towel wire wristband)
|
|
IMPORT_PREFIX='git.golem15.com/golem15/summercms/'
|
|
STALE_STATUS='Pre-alpha. Planning and research. Nothing runs yet.'
|
|
|
|
usage() {
|
|
cat >&2 <<'EOF'
|
|
usage:
|
|
check-phase10.2.sh --self-test
|
|
check-phase10.2.sh --layout
|
|
check-phase10.2.sh --imports
|
|
check-phase10.2.sh --readmes
|
|
check-phase10.2.sh --status
|
|
check-phase10.2.sh --go
|
|
check-phase10.2.sh --all
|
|
EOF
|
|
exit 2
|
|
}
|
|
|
|
refuse() {
|
|
echo "refuse: $*" >&2
|
|
return 1
|
|
}
|
|
|
|
tracked_source_files() {
|
|
local repo="$1"
|
|
if git -C "$repo" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
git -C "$repo" ls-files -z -- '*.go' '*.tmpl' '*.sh' ':(exclude).planning/**'
|
|
return
|
|
fi
|
|
(
|
|
cd "$repo"
|
|
find . -path './.planning' -prune -o -type f \( -name '*.go' -o -name '*.tmpl' -o -name '*.sh' \) -print0
|
|
)
|
|
}
|
|
|
|
check_layout() {
|
|
local root="$1" name
|
|
for name in "${NAMES[@]}"; do
|
|
if [[ -d "$root/$name" ]]; then
|
|
refuse "leftover root dir: $name"
|
|
return 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_imports_in() {
|
|
local repo="$1" file name
|
|
while IFS= read -r -d '' file; do
|
|
[[ "$file" != .planning/* ]] || continue
|
|
[[ "$file" != 'scripts/check-phase10.2.sh' ]] || continue
|
|
for name in "${NAMES[@]}"; do
|
|
if grep -Fq "${IMPORT_PREFIX}${name}" "$repo/$file"; then
|
|
refuse "old import: $repo/$file uses ${name} outside modules"
|
|
return 1
|
|
fi
|
|
done
|
|
done < <(tracked_source_files "$repo")
|
|
}
|
|
|
|
check_imports() {
|
|
check_imports_in "$1" || return 1
|
|
check_imports_in "$2"
|
|
}
|
|
|
|
check_readmes() {
|
|
local root="$1" name
|
|
for name in "${NAMES[@]}"; do
|
|
if [[ ! -f "$root/modules/$name/README.md" ]]; then
|
|
refuse "missing README: modules/$name/README.md"
|
|
return 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_status() {
|
|
local root="$1"
|
|
if grep -Fq "$STALE_STATUS" "$root/README.md"; then
|
|
refuse "stale Status: README still claims nothing runs"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_hygiene() {
|
|
local root="$1" app="$2"
|
|
check_layout "$root" || return 1
|
|
check_imports "$root" "$app" || return 1
|
|
check_readmes "$root" || return 1
|
|
check_status "$root" || return 1
|
|
}
|
|
|
|
run_go() {
|
|
(cd "$ROOT" && go vet ./...)
|
|
(cd "$ROOT" && go test ./...)
|
|
(cd "$APP" && go vet ./... ./plugins/golem15/fonoteka/... ./plugins/golem15/user/...)
|
|
(cd "$APP" && go test ./... ./plugins/golem15/fonoteka/... ./plugins/golem15/user/...)
|
|
echo "phase10.2 go passed"
|
|
}
|
|
|
|
expect_refusal() {
|
|
local name="$1" want="$2" root="$3" app="$4" output
|
|
if output="$(check_hygiene "$root" "$app" 2>&1)"; then
|
|
echo "refuse: self-test accepted planted $name" >&2
|
|
exit 1
|
|
fi
|
|
if ! grep -Fq "$want" <<<"$output"; then
|
|
echo "refuse: self-test $name failed for the wrong rule: $output" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
run_self_test() {
|
|
bash -n "${BASH_SOURCE[0]}"
|
|
local scratch app name
|
|
scratch="$(mktemp -d)"
|
|
app="$(mktemp -d)"
|
|
trap 'rm -rf "$scratch" "$app"' RETURN
|
|
cp "$ROOT/README.md" "$scratch/README.md"
|
|
for name in "${NAMES[@]}"; do
|
|
mkdir -p "$scratch/modules/$name"
|
|
cp "$ROOT/modules/$name/README.md" "$scratch/modules/$name/README.md"
|
|
done
|
|
|
|
check_hygiene "$scratch" "$app"
|
|
mkdir -p "$scratch/.planning"
|
|
printf '%s%s\n' "$IMPORT_PREFIX" backpack >"$scratch/.planning/historical.go"
|
|
git -C "$scratch" init -q
|
|
git -C "$scratch" add README.md modules .planning/historical.go
|
|
check_hygiene "$scratch" "$app"
|
|
|
|
mkdir "$scratch/backpack"
|
|
expect_refusal 'leftover root dir' 'leftover root dir' "$scratch" "$app"
|
|
rmdir "$scratch/backpack"
|
|
|
|
printf '%s%s\n' "$IMPORT_PREFIX" backpack >"$scratch/old_import.go"
|
|
git -C "$scratch" add old_import.go
|
|
expect_refusal 'old import' 'old import' "$scratch" "$app"
|
|
git -C "$scratch" rm -q -f old_import.go
|
|
|
|
mv "$scratch/modules/backpack/README.md" "$scratch/modules/backpack/README.saved"
|
|
expect_refusal 'missing README' 'missing README' "$scratch" "$app"
|
|
mv "$scratch/modules/backpack/README.saved" "$scratch/modules/backpack/README.md"
|
|
|
|
printf '\n%s\n' "$STALE_STATUS" >>"$scratch/README.md"
|
|
expect_refusal 'stale Status' 'stale Status' "$scratch" "$app"
|
|
|
|
echo "phase10.2 self-test passed"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
--self-test) run_self_test ;;
|
|
--layout) check_layout "$ROOT" ;;
|
|
--imports) check_imports "$ROOT" "$APP" ;;
|
|
--readmes) check_readmes "$ROOT" ;;
|
|
--status) check_status "$ROOT" ;;
|
|
--go) run_go ;;
|
|
--all)
|
|
check_hygiene "$ROOT" "$APP"
|
|
run_go
|
|
echo "phase10.2 check passed"
|
|
;;
|
|
*) usage ;;
|
|
esac
|