Files
sandwich-hime/scripts/verify.sh
T
2026-08-11 20:15:06 -04:00

159 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-only
set -euo pipefail
repo_root=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
cd "$repo_root"
log() {
printf '\n==> %s\n' "$*"
}
run_module_checks() {
local module_dir=$1
local label=$2
log "$label: go test"
(
cd "$module_dir"
go test ./...
)
log "$label: go vet"
(
cd "$module_dir"
go vet ./...
)
}
example_sources() {
if [[ ! -d examples ]]; then
return 0
fi
find examples \
-type d \( -name .git -o -name vendor \) -prune -o \
-type f -name '*.sando' -print | LC_ALL=C sort
}
example_modules() {
if [[ ! -d examples ]]; then
return 0
fi
find examples \
-type d \( -name .git -o -name vendor \) -prune -o \
-type f -name go.mod -print | LC_ALL=C sort
}
generated_manifest() {
local source output digest modified
while IFS= read -r source; do
[[ -n "$source" ]] || continue
output="${source}.go"
if [[ ! -f "$output" ]]; then
printf 'missing %s\n' "$output"
continue
fi
if command -v sha256sum >/dev/null 2>&1; then
digest=$(sha256sum -- "$output" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
digest=$(shasum -a 256 -- "$output" | awk '{print $1}')
else
printf 'error: sha256sum or shasum is required for generation verification\n' >&2
return 1
fi
if stat -c '%Y' -- "$output" >/dev/null 2>&1; then
modified=$(stat -c '%Y' -- "$output")
else
modified=$(stat -f '%m' -- "$output")
fi
printf '%s %s %s\n' "$digest" "$modified" "$output"
done < <(example_sources)
}
log "repository scripts: shell syntax"
bash -n scripts/*.sh
run_module_checks . "compiler module"
log "compiler module: go build"
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/himesan-verify.XXXXXXXX")
cleanup() {
if [[ -n "${build_dir:-}" && -d "$build_dir" ]]; then
rm -rf -- "$build_dir"
fi
}
trap cleanup EXIT HUP INT TERM
go build -trimpath -o "$build_dir/himesan" ./cmd/himesan
if [[ ! -f sando/go.mod ]]; then
printf 'error: nested Apache runtime module sando/go.mod is missing\n' >&2
exit 1
fi
run_module_checks sando "sando runtime module"
log "static project site"
./scripts/check-site.sh
sources=()
while IFS= read -r source; do
[[ -n "$source" ]] || continue
sources[${#sources[@]}]=$source
done < <(example_sources)
if (( ${#sources[@]} == 0 )); then
log "generation: no .sando examples exist yet; skipping deterministic-generation check"
else
log "generation: read-only freshness check"
go run ./cmd/himesan check "${sources[@]}"
manifest_before="$build_dir/generated-before.txt"
manifest_first="$build_dir/generated-first.txt"
manifest_second="$build_dir/generated-second.txt"
generated_manifest >"$manifest_before"
log "generation: first deterministic pass"
go run ./cmd/himesan generate "${sources[@]}"
generated_manifest >"$manifest_first"
if ! cmp -s "$manifest_before" "$manifest_first"; then
printf 'error: generation changed committed output after check declared it fresh\n' >&2
diff -u "$manifest_before" "$manifest_first" || true
exit 1
fi
log "generation: second deterministic pass"
go run ./cmd/himesan generate "${sources[@]}"
generated_manifest >"$manifest_second"
if ! cmp -s "$manifest_first" "$manifest_second"; then
printf 'error: repeated generation changed output bytes or an unchanged timestamp\n' >&2
diff -u "$manifest_first" "$manifest_second" || true
exit 1
fi
go run ./cmd/himesan check "${sources[@]}"
fi
# Generated application code is not executed until the read-only freshness
# check and both deterministic passes prove it is compiler-owned and current.
module_count=0
while IFS= read -r module_file; do
[[ -n "$module_file" ]] || continue
module_count=$((module_count + 1))
module_dir=$(dirname -- "$module_file")
run_module_checks "$module_dir" "example module $module_dir"
done < <(example_modules)
if (( module_count == 0 )); then
log "examples: no example module exists yet; skipping module tests"
fi
if [[ "${HIMESAN_RACE:-0}" == 1 ]]; then
log "compiler module: race tests"
go test -race ./...
log "sando runtime module: race tests"
(
cd sando
go test -race ./...
)
fi
log "verification complete"