-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathzone_check.sh
More file actions
executable file
·138 lines (119 loc) · 4.23 KB
/
zone_check.sh
File metadata and controls
executable file
·138 lines (119 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/bash
# Zone Check Script for ClojureWasm (Phase 97, D109)
# Counts cross-zone @import violations in the 4-zone architecture.
# Skips test-only imports (after the first `test "..."` block in each file).
#
# Post-R8 zone mapping:
# Layer 0: src/runtime/, src/regex/
# Layer 1: src/engine/
# Layer 2: src/lang/
# Layer 3: src/app/
#
# Usage:
# bash scripts/zone_check.sh # Show violations (informational)
# bash scripts/zone_check.sh --strict # Exit 1 if any violations
# bash scripts/zone_check.sh --gate # Exit 1 if violations > baseline (commit gate)
set -euo pipefail
cd "$(git rev-parse --show-toplevel)"
# Baseline: known violation count. Update when violations are fixed.
# History: 134 (R0) -> 126 (R9) -> 118 (Z1) -> 30 (Z2) -> 16 (Z3) -> 12 (vtable)
BASELINE=0
MODE="info"
if [[ "${1:-}" == "--strict" ]]; then
MODE="strict"
elif [[ "${1:-}" == "--gate" ]]; then
MODE="gate"
fi
ZONE_NAMES=("runtime" "engine" "lang" "app")
# Classify file path (relative to repo root) into zone 0-3
get_zone() {
local file="$1"
case "$file" in
src/runtime/*|src/regex/*) echo 0 ;;
src/engine/*) echo 1 ;;
src/lang/*) echo 2 ;;
src/app/*) echo 3 ;;
*) echo 3 ;;
esac
}
# Extract non-test @import paths from a Zig file.
# Stops collecting imports once the first `test "..."` block is encountered,
# since everything after it is test infrastructure.
extract_non_test_imports() {
awk '
BEGIN { in_test_section = 0 }
/^[[:space:]]*test[[:space:]]+"/ {
in_test_section = 1
}
!in_test_section && /@import\("/ {
line = $0
while (match(line, /@import\("([^"]+\.zig)"/, arr)) {
print arr[1]
line = substr(line, RSTART + RLENGTH)
}
}
' "$1"
}
total_violations=0
declare -A bucket # bucket["0->2"]=count
# Scan all .zig files under src/
while IFS= read -r src_file; do
src_zone=$(get_zone "$src_file")
src_dir=$(dirname "$src_file")
# Extract @import("...") paths from non-test code
while IFS= read -r import_path; do
[[ -z "$import_path" ]] && continue
# Resolve to repo-relative path
target=$(realpath -m --relative-to=. "$src_dir/$import_path" 2>/dev/null) || continue
[[ "$target" != src/* ]] && continue
[[ ! -f "$target" ]] && continue
tgt_zone=$(get_zone "$target")
# Violation: importing from a higher layer
if (( tgt_zone > src_zone )); then
key="${src_zone}->${tgt_zone}"
bucket["$key"]=$(( ${bucket["$key"]:-0} + 1 ))
total_violations=$((total_violations + 1))
echo " VIOLATION: ${ZONE_NAMES[$src_zone]}($src_zone) -> ${ZONE_NAMES[$tgt_zone]}($tgt_zone): $src_file -> $import_path"
fi
done < <(extract_non_test_imports "$src_file")
done < <(find src/ -name '*.zig' -type f | sort)
echo ""
echo "=== Zone Violation Summary ==="
echo ""
if (( total_violations == 0 )); then
echo "No violations found!"
else
# Print buckets sorted
for key in $(echo "${!bucket[@]}" | tr ' ' '\n' | sort); do
src_z="${key%%->*}"
tgt_z="${key##*->}"
echo " ${ZONE_NAMES[$src_z]}(L$src_z) -> ${ZONE_NAMES[$tgt_z]}(L$tgt_z): ${bucket[$key]} imports"
done
echo ""
echo "Total violations: $total_violations (baseline: $BASELINE)"
fi
case "$MODE" in
strict)
if (( total_violations > 0 )); then
echo ""
echo "FAIL: Zone violations detected (--strict mode)"
exit 1
fi
;;
gate)
if (( total_violations > BASELINE )); then
echo ""
echo "FAIL: Zone violations increased ($total_violations > baseline $BASELINE)"
echo "New upward imports are not allowed. Fix or use vtable pattern."
exit 1
elif (( total_violations < BASELINE )); then
echo ""
echo "Zone violations decreased ($total_violations < baseline $BASELINE)."
echo "Update BASELINE in scripts/zone_check.sh to $total_violations."
else
echo ""
echo "OK: Zone violations at baseline ($total_violations == $BASELINE)"
fi
;;
esac
exit 0