119 lines
3.2 KiB
Bash
Executable File
119 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# CHECK change-request-template-v1.0
|
|
# Verifies the draft artifact meets schema requirements.
|
|
# Exit 0 = PASS, 1 = FAIL, 2 = cannot grade (missing file).
|
|
|
|
set -euo pipefail
|
|
FILE="/root/troupe-standup/wizard-work/quill/change-request-template-v1.0.md"
|
|
|
|
if [ ! -f "$FILE" ]; then
|
|
echo "FAIL: artifact missing at $FILE"
|
|
exit 2
|
|
fi
|
|
|
|
FAIL=0
|
|
|
|
# 1. File size > 3000 bytes
|
|
BYTES=$(wc -c < "$FILE")
|
|
if [ "$BYTES" -lt 3000 ]; then
|
|
echo "FAIL: file too small ($BYTES bytes, minimum 3000)"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: size $BYTES bytes"
|
|
fi
|
|
|
|
# 2. Required top-level sections (1-7)
|
|
for i in 1 2 3 4 5 6 7; do
|
|
if ! grep -q "^## ${i}\. " "$FILE"; then
|
|
echo "FAIL: missing section '## ${i}. '"
|
|
FAIL=1
|
|
fi
|
|
done
|
|
grep -q "^## 1\. Purpose" "$FILE" && echo "PASS: section 1 present" || { echo "FAIL: section 1 missing"; FAIL=1; }
|
|
grep -q "^## 7\. Changelog" "$FILE" && echo "PASS: section 7 present" || { echo "FAIL: section 7 missing"; FAIL=1; }
|
|
|
|
# 3. Fenced template block exists
|
|
if ! grep -q '```markdown' "$FILE"; then
|
|
echo "FAIL: no fenced template block"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: fenced template block present"
|
|
fi
|
|
|
|
# 4. Required template fields present
|
|
for field in "Risk Level" "Window" "Summary" "Scope" "Validation" "Rollback" "Approval"; do
|
|
if ! grep -q "$field" "$FILE"; then
|
|
echo "FAIL: missing template field '$field'"
|
|
FAIL=1
|
|
fi
|
|
done
|
|
grep -q "Risk Level" "$FILE" && echo "PASS: Risk Level field present" || FAIL=1
|
|
grep -q "Low / Medium / High / Blocker" "$FILE" && echo "PASS: Risk Level enum defined" || FAIL=1
|
|
|
|
# 5. Example section present and free of unfilled placeholders
|
|
if ! grep -q "^## 6\. Example" "$FILE"; then
|
|
echo "FAIL: missing Example section"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: Example section present"
|
|
fi
|
|
|
|
# Extract example block content: find fenced code block within Example section
|
|
EXAMPLE_BLOCK=""
|
|
IN_EXAMPLE=0
|
|
IN_FENCE=0
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^##[[:space:]]+6\. ]]; then
|
|
IN_EXAMPLE=1
|
|
elif [ "$IN_EXAMPLE" -eq 1 ] && [[ "$line" =~ ^##[[:space:]]+[0-9] ]]; then
|
|
IN_EXAMPLE=0
|
|
fi
|
|
if [ "$IN_EXAMPLE" -eq 1 ] && [[ "$line" =~ ^\`\`\` ]]; then
|
|
if [ "$IN_FENCE" -eq 0 ]; then
|
|
IN_FENCE=1
|
|
else
|
|
IN_FENCE=0
|
|
break
|
|
fi
|
|
continue
|
|
fi
|
|
if [ "$IN_FENCE" -eq 1 ]; then
|
|
EXAMPLE_BLOCK="${EXAMPLE_BLOCK}${line}"$'\n'
|
|
fi
|
|
done < "$FILE"
|
|
|
|
if [ -n "$EXAMPLE_BLOCK" ]; then
|
|
if echo "$EXAMPLE_BLOCK" | grep -q '\[PROJECT\]'; then
|
|
echo "FAIL: example contains unfilled placeholder [PROJECT]"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: example free of [PROJECT]"
|
|
fi
|
|
if echo "$EXAMPLE_BLOCK" | grep -q '\[REQUESTOR\]'; then
|
|
echo "FAIL: example contains unfilled placeholder [REQUESTOR]"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: example free of [REQUESTOR]"
|
|
fi
|
|
else
|
|
echo "FAIL: could not extract example block"
|
|
FAIL=1
|
|
fi
|
|
|
|
# 6. Changelog table exists with v1.0 row
|
|
if ! grep -q "| v1.0 " "$FILE"; then
|
|
echo "FAIL: changelog missing v1.0 row"
|
|
FAIL=1
|
|
else
|
|
echo "PASS: changelog v1.0 row present"
|
|
fi
|
|
|
|
# Final
|
|
if [ "$FAIL" -eq 0 ]; then
|
|
echo "RESULT: PASS"
|
|
exit 0
|
|
else
|
|
echo "RESULT: FAIL ($FAIL checks failed)"
|
|
exit 1
|
|
fi
|