返回 CodeWhale
preflight.sh
根目录 / scripts / preflight.sh
1 #!/usr/bin/env bash
2 # One local preflight for the generated files and ratchets that otherwise turn
3 # main red after a green PR: run it before you push.
4 #
5 # scripts/preflight.sh regenerate what can be regenerated, check the rest
6 # scripts/preflight.sh --check change nothing; fail if anything is stale
7 # scripts/preflight.sh --full also run the cargo-backed runtime-contract and
8 # persistence-backlog ratchets (minutes, offline)
9 # scripts/preflight.sh --base REF compare feature receipts against REF
10 # (default: merge base with origin/main)
11 #
12 # As a pre-push hook it runs in --check mode:
13 # ln -s ../../scripts/preflight.sh "$(git rev-parse --git-path hooks)/pre-push"
14 #
15 # What it covers, and the command that fixes each one:
16 # - crates/tui/CHANGELOG.md slice scripts/sync-changelog.sh (written here)
17 # - README locale stamps and links retranslate; check-readme-translations.py
18 # prints the new sha256 stamp to use
19 # - product lexicon (warn-only) python3 scripts/check-lexicon.py lists each hit
20 # - dead-code / blocking-calls each ratchet's --update, committed in the
21 # (and with --full runtime-contract, same PR with the reason in the PR body
22 # persistence-backlog)
23 # - feature release-note receipts add each feat commit's #issue to
24 # for this branch's own commits CHANGELOG.md in the same PR
25 set -uo pipefail
26
27 mode="write"
28 full=0
29 base=""
30 if [[ "$(basename "$0")" == "pre-push" ]]; then
31 # git passes <remote> <url>; the hook only ever checks.
32 mode="check"
33 set --
34 fi
35 while [[ "$#" -gt 0 ]]; do
36 case "$1" in
37 --check) mode="check"; shift ;;
38 --full) full=1; shift ;;
39 --base) base="${2:?--base needs a ref}"; shift 2 ;;
40 -h|--help) sed -n '2,26p' "$0"; exit 0 ;;
41 *) echo "usage: $0 [--check] [--full] [--base REF]" >&2; exit 2 ;;
42 esac
43 done
44
45 root="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || echo "${BASH_SOURCE[0]}")")/.." && pwd)"
46 cd "${root}" || exit 2
47
48 failed=()
49 step() {
50 local label="$1" fix="$2"
51 shift 2
52 echo "== ${label}"
53 if "$@"; then
54 return 0
55 fi
56 failed+=("${label}: ${fix}")
57 }
58
59 if [[ "${mode}" == "write" ]]; then
60 step "TUI changelog slice" "scripts/sync-changelog.sh" ./scripts/sync-changelog.sh
61 else
62 step "TUI changelog slice" "scripts/sync-changelog.sh" ./scripts/sync-changelog.sh --check
63 fi
64 step "README translations in sync" \
65 "retranslate the changed README sections, then update each stamp to the sha256 printed above" \
66 python3 scripts/check-readme-translations.py
67 step "README locale link symmetry" "link every README.<locale>.md from README.md" \
68 bash scripts/check-readme-locales.sh
69 # Warn-only: lists retired product words and engineering notes in English
70 # copy; never fails the preflight.
71 step "product lexicon (warn-only)" "python3 scripts/check-lexicon.py" \
72 python3 scripts/check-lexicon.py --summary
73 step "dead-code budget" "python3 scripts/check-dead-code-budget.py --update" \
74 python3 scripts/check-dead-code-budget.py
75 step "blocking-calls budget" "python3 scripts/check-blocking-calls-budget.py --update" \
76 python3 scripts/check-blocking-calls-budget.py
77 if [[ "${full}" == "1" ]]; then
78 step "runtime-contract budget" \
79 "python3 scripts/check-runtime-contract-budget.py --update --allow-increase" \
80 python3 scripts/check-runtime-contract-budget.py
81 step "persistence-backlog budget" \
82 "python3 scripts/check-persistence-backlog-budget.py --update" \
83 python3 scripts/check-persistence-backlog-budget.py
84 fi
85
86 if [[ -z "${base}" ]]; then
87 base="$(git merge-base HEAD origin/main 2>/dev/null || true)"
88 fi
89 if [[ -n "${base}" ]]; then
90 step "feature release-note receipts (${base:0:12}..HEAD)" \
91 "add each feat commit's #issue to CHANGELOG.md in this branch" \
92 ./scripts/release/check-feature-release-notes.sh "${base}" HEAD
93 else
94 echo "== feature release-note receipts: skipped (no origin/main; pass --base REF)"
95 fi
96
97 echo
98 if [[ "${#failed[@]}" -gt 0 ]]; then
99 echo "preflight: ${#failed[@]} check(s) failed. Fix, commit the result, and re-run:" >&2
100 for line in "${failed[@]}"; do
101 echo " - ${line}" >&2
102 done
103 exit 1
104 fi
105 if [[ "${mode}" == "write" ]] && ! git diff --quiet -- crates/tui/CHANGELOG.md; then
106 echo "preflight: OK, and crates/tui/CHANGELOG.md was regenerated -- commit it."
107 else
108 echo "preflight: OK"
109 fi
110
110 lines BASH