test(10.2-02): add nested-layout hygiene gate
- Refuse root package directories, old imports, missing READMEs, and stale status text\n- Validate Go vet and tests across framework and Fonoteka
This commit is contained in:
161
scripts/check-phase10.2.sh
Executable file
161
scripts/check-phase10.2.sh
Executable file
@@ -0,0 +1,161 @@
|
|||||||
|
#!/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'
|
||||||
|
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" != '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 "$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"
|
||||||
|
expect_refusal 'old import' 'old import' "$scratch" "$app"
|
||||||
|
rm "$scratch/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
|
||||||
Reference in New Issue
Block a user