- The import-key sweep and migrate-to-seed flows set several user-visible status/error strings (shown via sweep_status_ / seed_migration_status_ / rescan_status) as bare English; routed them through TR() with additive keys. - Extended scripts/check-source-hygiene.sh with two low-false-positive content guards so this debt can't regrow: a bare-English migrate/sweep status assignment, and a Tactile button sized with a raw (unscaled) pixel literal. Passes clean on the tree (362 files); the dev sweep harness is allowlisted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
3.7 KiB
Bash
Executable File
87 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Source-tree hygiene guard.
|
|
#
|
|
# Blocks two failure modes that an AI coding session previously introduced in
|
|
# src/wallet/ (the lite-wallet "_plan"/"_batch" churn): pathologically long
|
|
# filenames (which also break the Windows MAX_PATH 260-char limit during the
|
|
# cross-build) and the runaway "receipt/custody/handoff/stewardship" naming
|
|
# explosion where each session wrapped the previous artifact in one more layer.
|
|
#
|
|
# Usage:
|
|
# scripts/check-source-hygiene.sh # check working-tree src/
|
|
# scripts/check-source-hygiene.sh --staged # check staged files (pre-commit)
|
|
#
|
|
# Install as a git pre-commit hook:
|
|
# ln -sf ../../scripts/check-source-hygiene.sh .git/hooks/pre-commit
|
|
# # (the hook invokes it with --staged automatically when named pre-commit)
|
|
|
|
set -euo pipefail
|
|
|
|
MAX_LEN=80
|
|
# Naming-explosion tokens. Two or more chained in one basename is the smell.
|
|
CHURN_RE='receipt|custody|handoff|stewardship|promotion_activation|acceptance_confirmation|archive_handoff|post_closure'
|
|
|
|
mode="${1:-}"
|
|
if [[ "$mode" == "--staged" || "$(basename "$0")" == "pre-commit" ]]; then
|
|
mapfile -t files < <(git diff --cached --name-only --diff-filter=AR | grep -E '\.(cpp|h|hpp|cc)$' || true)
|
|
else
|
|
mapfile -t files < <(git ls-files 'src/**/*.cpp' 'src/**/*.h' 2>/dev/null; \
|
|
find src -type f \( -name '*.cpp' -o -name '*.h' \) 2>/dev/null)
|
|
# de-dup
|
|
mapfile -t files < <(printf '%s\n' "${files[@]}" | sort -u)
|
|
fi
|
|
|
|
fail=0
|
|
for f in "${files[@]}"; do
|
|
[[ -z "$f" ]] && continue
|
|
base="$(basename "$f")"
|
|
len=${#base}
|
|
if (( len > MAX_LEN )); then
|
|
echo "✗ filename too long ($len > $MAX_LEN chars): $f" >&2
|
|
fail=1
|
|
fi
|
|
# count distinct churn tokens in the basename ( || true: grep exits 1 on no match)
|
|
n=$(printf '%s' "$base" | grep -oE "$CHURN_RE" | sort -u | wc -l || true)
|
|
if (( n >= 2 )); then
|
|
echo "✗ runaway naming pattern ($n churn tokens) — refactor in place, don't add a layer: $f" >&2
|
|
fail=1
|
|
fi
|
|
done
|
|
|
|
# ── Content guards (UX-hygiene threads) ──────────────────────────────────────
|
|
# Low-false-positive regression checks for debt the UX audit cleared, so it can't
|
|
# silently regrow. Each is deliberately narrow; widen only with an allowlist.
|
|
for f in "${files[@]}"; do
|
|
[[ "$f" == *.cpp ]] || continue
|
|
[[ -f "$f" ]] || continue
|
|
# app_sweep.cpp is the dev screenshot-sweep harness: its fixture strings are never shipped UI.
|
|
[[ "$(basename "$f")" == "app_sweep.cpp" ]] && continue
|
|
|
|
# (1) Tactile button sized with a raw multi-digit pixel literal that ignores HiDPI.
|
|
# Real sizes multiply by ui::Layout::dpiScale() / dp / hScale, or come from schema.
|
|
if hits=$(grep -nE 'Tactile(Small)?Button\([^;]*ImVec2\([1-9][0-9]+(\.[0-9]+f?)?,' "$f" \
|
|
| grep -vE 'dpiScale|\* *dp\b|\* *hdpi|hScale|schema|Scale\('); then
|
|
while IFS= read -r line; do
|
|
echo "✗ unscaled button size (multiply the px by ui::Layout::dpiScale()): $f:$line" >&2
|
|
fail=1
|
|
done <<< "$hits"
|
|
fi
|
|
|
|
# (2) User-visible migrate/sweep status assigned a bare English literal instead of TR(...).
|
|
# "__SENTINEL__" comparisons and empty strings are fine.
|
|
if hits=$(grep -nE '(sweep_status_|seed_migration_status_)[[:space:]]*=[[:space:]]*"[A-Za-z]' "$f" \
|
|
| grep -vE 'TR\(|"__'); then
|
|
while IFS= read -r line; do
|
|
echo "✗ untranslated status string (route through TR(...)): $f:$line" >&2
|
|
fail=1
|
|
done <<< "$hits"
|
|
fi
|
|
done
|
|
|
|
if (( fail )); then
|
|
echo "" >&2
|
|
echo "Source hygiene check failed. See docs in scripts/check-source-hygiene.sh." >&2
|
|
exit 1
|
|
fi
|
|
echo "source hygiene OK (${#files[@]} files checked)"
|