fix(lint): make the Vale prefilter work for external consumers
pre-commit prefixes only entry[0] with the hook-repo clone path (cmd = (prefix.path(cmd[0]), *cmd[1:])), so the --config argument in .pre-commit-hooks.yaml resolved against the *consuming* repo's root and hard-failed every external run with E100. Two of the three hooks ADR-0014 promises were unusable. vale-wrap.sh now self-locates its config from BASH_SOURCE when no --config is supplied; an explicit --config still wins in all three argv forms and stays cwd-relative. Both manifests drop the argument and are kept byte-identical: the local repo: local config resolved --config correctly only because the consuming repo *was* this repo, and that divergence is why three review rounds missed the defect. Also in the wrapper: - replace GNU-only `realpath -m` with a portable abspath helper; -m is load-bearing (dest does not exist yet), so BSD realpath aborted the script under set -e on macOS - walk directory arguments instead of passing them through unflattened, which reported a clean 0-error run for files that fail when named explicitly - read/write with errors='surrogateescape' so one non-UTF-8 .md under a directory argument cannot abort the hook New test-vale-hooks-consumer.sh builds the hook repo from the working tree and points a file:// consumer at it, covering the manifest as a hook repo for the first time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
This commit is contained in:
@@ -19,8 +19,8 @@ pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
||||
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
||||
|
||||
if ! command -v vale &>/dev/null; then
|
||||
echo "vale is not installed — skipping (matches skill-audit/agent-audit's own fallback behavior)"
|
||||
exit 0
|
||||
echo "SKIP: vale is not installed — skipping (matches skill-audit/agent-audit's own fallback behavior)"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
make_fixture() {
|
||||
@@ -345,6 +345,86 @@ else
|
||||
fail "wrapper altered output for a literal (|) block scalar description — should be left untouched"
|
||||
fi
|
||||
|
||||
# --- 12. With no --config at all, the wrapper falls back to its own sibling
|
||||
# assets/vale/.vale.ini. `.pre-commit-hooks.yaml` relies on this: pre-commit
|
||||
# prefixes only entry[0] with the hook-repo clone path, so a --config argument
|
||||
# there resolves against the consuming repo and hard-errors (E100) for every
|
||||
# external consumer.
|
||||
echo ""
|
||||
echo "--- defaults --config to the wrapper's own sibling assets/vale/.vale.ini ---"
|
||||
FIXTURE12="$(make_fixture 2)"
|
||||
trap 'rm -rf "$FIXTURE1" "$FIXTURE2" "$FIXTURE3" "$FIXTURE4" "$FIXTURE5" "$FIXTURE6" "$FIXTURE7" "$FIXTURE8" "$FIXTURE10" "$FIXTURE11" "$FIXTURE12"' EXIT
|
||||
OUT12=$(run_wrap "$FIXTURE12" plugins/testplugin/skills/zzzskill/SKILL.md)
|
||||
if echo "$OUT12" | grep -q "VagueWording"; then
|
||||
pass "a --config-less invocation uses the wrapper's bundled config"
|
||||
else
|
||||
fail "a --config-less invocation found no config — external pre-commit consumers get E100, the bug this test guards against"
|
||||
fi
|
||||
|
||||
# --- 13. No GNU-only `realpath -m`. macOS ships the BSD realpath, which has no
|
||||
# -m (canonicalize-missing) — and every scratch destination is a path that does
|
||||
# not exist yet, so a plain `realpath` exits 1 and set -e aborts the hook.
|
||||
echo ""
|
||||
echo "--- runs with a BSD realpath that has no -m option ---"
|
||||
STUB13="$(mktemp -d)"
|
||||
trap 'rm -rf "$FIXTURE1" "$FIXTURE2" "$FIXTURE3" "$FIXTURE4" "$FIXTURE5" "$FIXTURE6" "$FIXTURE7" "$FIXTURE8" "$FIXTURE10" "$FIXTURE11" "$FIXTURE12" "$STUB13"' EXIT
|
||||
REAL_REALPATH="$(command -v realpath || echo /bin/false)"
|
||||
cat > "$STUB13/realpath" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
for a in "\$@"; do
|
||||
case "\$a" in
|
||||
-m|--canonicalize-missing)
|
||||
echo "realpath: illegal option -- m" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
exec "$REAL_REALPATH" "\$@"
|
||||
EOF
|
||||
chmod +x "$STUB13/realpath"
|
||||
OUT13=$(cd "$FIXTURE12" && PATH="$STUB13:$PATH" bash "$SCRIPT" --config "$VALE_CONFIG" \
|
||||
plugins/testplugin/skills/zzzskill/SKILL.md 2>&1 || true)
|
||||
if echo "$OUT13" | grep -q "illegal option"; then
|
||||
fail "invoked realpath -m — fails on macOS's BSD realpath, the bug this test guards against"
|
||||
elif echo "$OUT13" | grep -q "VagueWording"; then
|
||||
pass "flattens and flags with no GNU realpath available"
|
||||
else
|
||||
fail "produced no alert under a BSD-style realpath: $OUT13"
|
||||
fi
|
||||
|
||||
# --- 14. A directory argument is walked and its files flattened. The classifier
|
||||
# used to accept only regular files, so a directory fell through to the vale
|
||||
# flag list, left the file list empty, and exec'd bare vale — silently skipping
|
||||
# the flattening. `lint`'s vale-run skill documents `vale <path-or-glob>` as
|
||||
# normal usage, so this is a reachable path.
|
||||
echo ""
|
||||
echo "--- flattens files reached through a directory argument ---"
|
||||
FIXTURE14="$(make_fixture 2)"
|
||||
trap 'rm -rf "$FIXTURE1" "$FIXTURE2" "$FIXTURE3" "$FIXTURE4" "$FIXTURE5" "$FIXTURE6" "$FIXTURE7" "$FIXTURE8" "$FIXTURE10" "$FIXTURE11" "$FIXTURE12" "$STUB13" "$FIXTURE14"' EXIT
|
||||
WRAPPED_DIR=$(run_wrap "$FIXTURE14" --config "$VALE_CONFIG" plugins)
|
||||
BARE_DIR=$(cd "$FIXTURE14" && vale --config "$VALE_CONFIG" plugins 2>&1 || true)
|
||||
if ! echo "$WRAPPED_DIR" | grep -q "VagueWording"; then
|
||||
fail "a directory argument produced no alert — flattening was silently skipped, the bug this test guards against"
|
||||
elif echo "$BARE_DIR" | grep -q "VagueWording"; then
|
||||
fail "bare vale already flags this fixture, so the test can't detect a silently-skipped flattening"
|
||||
else
|
||||
pass "a directory argument is walked and its files flattened"
|
||||
fi
|
||||
|
||||
# --- 15. Directory walking must survive paths with spaces ---
|
||||
echo ""
|
||||
echo "--- walks a directory containing a path with spaces ---"
|
||||
SPACED15="$FIXTURE14/plugins/testplugin/skills/zzz skill"
|
||||
mkdir -p "$SPACED15"
|
||||
cp "$FIXTURE14/plugins/testplugin/skills/zzzskill/SKILL.md" "$SPACED15/SKILL.md"
|
||||
rm -rf "$FIXTURE14/plugins/testplugin/skills/zzzskill"
|
||||
OUT15=$(run_wrap "$FIXTURE14" --config "$VALE_CONFIG" plugins/testplugin/skills)
|
||||
if echo "$OUT15" | grep -q "zzz skill" && echo "$OUT15" | grep -q "VagueWording"; then
|
||||
pass "a file under a directory whose name contains a space is walked and flattened"
|
||||
else
|
||||
fail "a path with a space was dropped from the directory walk"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
|
||||
Reference in New Issue
Block a user