Adopt the rules-swift pin-and-codify strategy in snapshot mode (third_party/rules-swift @97dc70f + sha256), add codified gates, a conformance audit ledger, and .github/workflows/rules-swift.yml (corpus-pin integrity required, full gate report mode). Remove the docs/rules mirror it supersedes (repo-specific files kept under docs/). Style and leak gates exclude the vendored corpus.
88 lines
3.4 KiB
Bash
Executable File
88 lines
3.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# Ensures the pinned rules-swift corpus is present at its recorded version and that
|
|
# the audit names every public rules-swift source file.
|
|
#
|
|
# Two pin mechanisms are supported (auto-detected):
|
|
# submodule mode: the corpus is a git submodule at third_party/rules-swift; the
|
|
# submodule commit IS the pin (preferred for tool repos).
|
|
# snapshot mode: the corpus is a plain vendored copy at third_party/rules-swift,
|
|
# pinned by docs/rules-swift-corpus.sha256 (preferred for source-published repos
|
|
# that must avoid `--recursive` clones).
|
|
# Override RULES_SWIFT_DIR to audit against a live local checkout during dev.
|
|
set -eu
|
|
|
|
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
cd "$ROOT"
|
|
|
|
RULES_SWIFT_DIR=${RULES_SWIFT_DIR:-"$ROOT/third_party/rules-swift"}
|
|
AUDIT=docs/rules-swift-audit.md
|
|
MANIFEST=docs/rules-swift-corpus.sha256
|
|
fail=0
|
|
file_count=0
|
|
pin_mode="none"
|
|
|
|
fail_check() {
|
|
echo "RULE FAIL: $1" >&2
|
|
fail=1
|
|
}
|
|
|
|
if [ ! -f "$AUDIT" ]; then
|
|
fail_check "missing rules-swift audit: $AUDIT"
|
|
elif [ ! -d "$RULES_SWIFT_DIR" ] || [ -z "$(ls -A "$RULES_SWIFT_DIR" 2>/dev/null)" ]; then
|
|
fail_check "rules-swift corpus absent at $RULES_SWIFT_DIR (run: git submodule update --init --recursive, or restore the vendored snapshot)"
|
|
else
|
|
# --- Pin verification: submodule status, else snapshot digest. ---
|
|
if [ -f .gitmodules ] && grep -q 'third_party/rules-swift' .gitmodules; then
|
|
pin_mode="submodule"
|
|
status=$(git submodule status third_party/rules-swift 2>/dev/null || echo "?unknown")
|
|
# A '+' or '-' prefix means the working submodule drifted off the recorded commit.
|
|
case "$status" in
|
|
[-+]*) fail_check "rules-swift submodule not at pinned commit ($status); run: git submodule update --init --recursive" ;;
|
|
esac
|
|
elif [ -f "$MANIFEST" ]; then
|
|
pin_mode="snapshot"
|
|
actual=$(mktemp "${TMPDIR:-/tmp}/rules-swift-corpus.XXXXXX")
|
|
(
|
|
cd "$RULES_SWIFT_DIR"
|
|
find . -type f \( -name '*.md' -o -name '*.sh' \) -not -path '*/.git/*' -print0 \
|
|
| sort -z \
|
|
| xargs -0 shasum -a 256 \
|
|
| sed 's| ./| |'
|
|
) > "$actual"
|
|
if ! cmp -s "$actual" "$MANIFEST"; then
|
|
echo "RULE FAIL: rules-swift snapshot digest changed; update $MANIFEST and $AUDIT together" >&2
|
|
diff -u "$MANIFEST" "$actual" >&2 || true
|
|
fail=1
|
|
fi
|
|
rm -f "$actual"
|
|
else
|
|
fail_check "no corpus pin found: add a git submodule (third_party/rules-swift) or a snapshot digest ($MANIFEST)"
|
|
fi
|
|
|
|
file_count=$(
|
|
find "$RULES_SWIFT_DIR" -type f \( -name '*.md' -o -name '*.sh' \) \
|
|
-not -path '*/.git/*' | wc -l | tr -d ' '
|
|
)
|
|
|
|
if ! grep -Fq "Rules corpus file count: $file_count" "$AUDIT"; then
|
|
fail_check "rules-swift audit must record current corpus file count: $file_count"
|
|
fi
|
|
|
|
missing=$(
|
|
find "$RULES_SWIFT_DIR" -type f \( -name '*.md' -o -name '*.sh' \) -not -path '*/.git/*' \
|
|
| sed "s|^$RULES_SWIFT_DIR/||" \
|
|
| sort \
|
|
| while IFS= read -r rel; do
|
|
grep -Fq "\`$rel\`" "$AUDIT" || echo "$rel"
|
|
done
|
|
)
|
|
if [ -n "$missing" ]; then
|
|
echo "RULE FAIL: rules-swift audit missing corpus files:" >&2
|
|
echo "$missing" | sed 's/^/ /' >&2
|
|
fail=1
|
|
fi
|
|
fi
|
|
|
|
[ "$fail" = 0 ] || exit 1
|
|
echo "rules-swift corpus coverage clean ($file_count files, pinned via $pin_mode)"
|