808cbb7d92
The fixture loop covers every package the fixture has; this covers every package the tree has. The review's skip-the-root rival now fails the real repo's own gate (exit 2 naming Cargo.toml), not only the test suite. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
218 lines
7.9 KiB
Bash
Executable File
218 lines
7.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# check_the_checker for scripts/fmt-workspaces.sh. Every case MAKES the checked-
|
|
# for condition happen: a real misformatted file in a real nested workspace,
|
|
# which is what the documented `-p` spelling could never report (improvise-b4ks).
|
|
set -uo pipefail
|
|
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
RUN="$here/fmt-workspaces.sh"
|
|
work="$(mktemp -d)"
|
|
trap 'rm -rf "$work"' EXIT
|
|
|
|
pass=0; fail=0
|
|
ok() { printf ' ok %s\n' "$1"; pass=$((pass+1)); }
|
|
bad() { printf ' FAIL %s\n %s\n' "$1" "$2"; fail=$((fail+1)); }
|
|
|
|
CLEAN='pub fn probe() -> u32 {
|
|
1
|
|
}
|
|
'
|
|
DIRTY='pub fn probe( ) ->u32{ 1 }
|
|
'
|
|
|
|
# Two workspace roots, exactly as this repo has: an outer one with a member
|
|
# crate, and `nested/` carrying its own [workspace] plus a PATH DEPENDENCY back
|
|
# into the outer tree -- which is what makes `--all` leak (harness/opfs-contract
|
|
# depends on improvise-io the same way, and `--all` formats path deps too).
|
|
scaffold() {
|
|
rm -rf "$work/repo"
|
|
mkdir -p "$work/repo/src" "$work/repo/a/src" "$work/repo/nested/src"
|
|
cat > "$work/repo/Cargo.toml" <<'EOF'
|
|
[workspace]
|
|
members = ["a"]
|
|
resolver = "2"
|
|
|
|
[package]
|
|
name = "root-pkg"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
cat > "$work/repo/a/Cargo.toml" <<'EOF'
|
|
[package]
|
|
name = "outer-pkg"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
cat > "$work/repo/nested/Cargo.toml" <<'EOF'
|
|
[workspace]
|
|
|
|
[package]
|
|
name = "inner-pkg"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
outer-pkg = { path = "../a" }
|
|
EOF
|
|
printf '%s' "$CLEAN" > "$work/repo/src/lib.rs"
|
|
printf '%s' "$CLEAN" > "$work/repo/a/src/lib.rs"
|
|
printf '%s' "$CLEAN" > "$work/repo/nested/src/lib.rs"
|
|
}
|
|
|
|
# $1 name, $2 expected exit, rest: args. Captures stdout+stderr into $OUT.
|
|
OUT=""
|
|
run_case() {
|
|
local name="$1" want="$2"; shift 2
|
|
OUT="$("$RUN" "$@" 2>&1)"
|
|
local got=$?
|
|
if [ "$got" != "$want" ]; then
|
|
bad "$name" "exit $got, wanted $want; output: ${OUT:0:300}"
|
|
return 1
|
|
fi
|
|
ok "$name"
|
|
return 0
|
|
}
|
|
|
|
scaffold
|
|
run_case "both workspaces clean is a pass" 0 "$work/repo"
|
|
|
|
# One fault case PER PACKAGE, enumerated from the fixture rather than
|
|
# hand-picked: three hand-picked shapes each missed a rival, and the fourth
|
|
# missed the root package itself (improvise-90ea). Reasoning:
|
|
# context/test-evidence/tooling.md. The enumeration is a find over
|
|
# `[package]` manifests, deliberately NOT the script's own `[workspace]` +
|
|
# `cargo metadata` discovery, which is the thing under test.
|
|
scaffold
|
|
pkg_manifests=()
|
|
while IFS= read -r m; do pkg_manifests+=("$m"); done < <(
|
|
cd "$work/repo" && grep -rl --include=Cargo.toml '^\[package\]' . | sort)
|
|
# An empty or shrunken enumeration would make the loop below vacuous.
|
|
if [ "${#pkg_manifests[@]}" = 3 ]; then
|
|
ok "the fixture enumerates all three packages (root, member, nested)"
|
|
else
|
|
bad "the fixture enumerates all three packages" "found: ${pkg_manifests[*]:-none}"
|
|
fi
|
|
for m in "${pkg_manifests[@]}"; do
|
|
rel="$(dirname "${m#./}")/src/lib.rs"; rel="${rel#./}"
|
|
scaffold
|
|
printf '%s' "$DIRTY" > "$work/repo/$rel"
|
|
if run_case "a fault in $rel is reported" 1 "$work/repo"; then
|
|
# Counting, not matching: `--all` for `-p` walks PAST the nested boundary
|
|
# (measured) and names an outer file a second time under the inner root.
|
|
n="$(printf '%s\n' "$OUT" | grep -cF "$work/repo/$rel")"
|
|
if [ "$n" = 1 ]; then
|
|
ok " and $rel is named exactly once"
|
|
else
|
|
bad " and $rel is named exactly once" "named $n times; output: ${OUT:0:300}"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# A usage error must NOT wear a formatting failure's exit code. This is the
|
|
# whole ticket: `cargo fmt -p opfs-contract` from the repo root exits 1.
|
|
scaffold
|
|
run_case "an unknown option is a usage error, not a verdict" 2 "$work/repo" --nope
|
|
run_case "a second repo-root is a usage error" 2 "$work/repo" "$work/repo"
|
|
run_case "a directory that does not exist is a usage error" 2 "$work/nowhere"
|
|
|
|
# "Nothing to check" must not read as "everything is clean": a find that matches
|
|
# nothing is how a moved directory turns this gate off silently.
|
|
mkdir -p "$work/empty"
|
|
run_case "a tree with no workspace root is a usage error, not a pass" 2 "$work/empty"
|
|
|
|
run_case "--help is a usage error, so a typo cannot pass" 2 "$work/repo" --help
|
|
|
|
# The loop above covers every package the FIXTURE has; this covers every
|
|
# package the TREE has. A package no root lists is checked by nothing, so the
|
|
# gate must refuse a verdict -- and name the package -- rather than pass.
|
|
scaffold
|
|
mkdir -p "$work/repo/orphan/src"
|
|
printf '[package]\nname = "orphan-pkg"\nversion = "0.1.0"\nedition = "2021"\n' \
|
|
> "$work/repo/orphan/Cargo.toml"
|
|
printf '%s' "$DIRTY" > "$work/repo/orphan/src/lib.rs"
|
|
cat > "$work/repo/Cargo.toml" <<'EOF'
|
|
[workspace]
|
|
members = ["a"]
|
|
exclude = ["orphan"]
|
|
resolver = "2"
|
|
|
|
[package]
|
|
name = "root-pkg"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
if run_case "a package no workspace root reaches is exit 2, not a pass" 2 "$work/repo"; then
|
|
case "$OUT" in
|
|
*"no workspace root reaches"*orphan/Cargo.toml*) ok " and the unreached package is named" ;;
|
|
*) bad " and the unreached package is named" "output: ${OUT:0:300}" ;;
|
|
esac
|
|
fi
|
|
|
|
# The narrowed contract, pinned so it is not merely prose (ChatGPT Codex on
|
|
# PR #159). rustfmt exits 1 for a source it cannot parse, exactly as for a
|
|
# diff -- so exit 1 is "rustfmt did not certify this root clean", and what
|
|
# earns exit 2 is only that the gate never ran. A file must still be NAMED.
|
|
scaffold
|
|
printf 'pub fn a( {{{\n' > "$work/repo/nested/src/lib.rs"
|
|
if run_case "a source rustfmt cannot parse is a verdict, not a usage error" 1 "$work/repo"; then
|
|
case "$OUT" in
|
|
*nested/src/lib.rs*) ok " and the unparseable file is still named" ;;
|
|
*) bad " and the unparseable file is still named" "output: ${OUT:0:300}" ;;
|
|
esac
|
|
fi
|
|
|
|
# The other half of the same contract: a cause that produces NO verdict and
|
|
# names NO file must be 2. A formatter stub that refuses to run is the honest
|
|
# injection -- `cargo` resolves, so this is not the `command -v` arm, and it
|
|
# reaches the `cargo fmt --version` probe the way a missing rustfmt component
|
|
# would. Note the stub dir cannot simply REPLACE PATH: the shebang resolves
|
|
# `bash` through it, so an empty PATH exits 127 before the script starts.
|
|
scaffold
|
|
mkdir -p "$work/stub"
|
|
printf '#!/usr/bin/env bash\nexit 1\n' > "$work/stub/cargo"
|
|
chmod +x "$work/stub/cargo"
|
|
PATH="$work/stub:$PATH" "$RUN" "$work/repo" >/dev/null 2>&1
|
|
rc=$?
|
|
if [ "$rc" = 2 ]; then
|
|
ok "a cargo that cannot run at all is exit 2, not a verdict"
|
|
else
|
|
bad "a cargo that cannot run at all is exit 2" "exit $rc"
|
|
fi
|
|
|
|
# That case alone is NOT enough, and injecting a rival proved it: a wholly
|
|
# broken cargo also breaks `cargo metadata`, so it exits 2 on the metadata arm
|
|
# and the rustfmt probe could be deleted with the suite still green. A MISSING
|
|
# RUSTFMT COMPONENT is the case the probe exists for -- metadata succeeds and
|
|
# only `cargo fmt` fails -- so the stub has to delegate everything else.
|
|
real_cargo="$(command -v cargo)"
|
|
scaffold
|
|
mkdir -p "$work/stub2"
|
|
{
|
|
printf '#!/usr/bin/env bash\n'
|
|
printf 'if [ "${1:-}" = fmt ]; then echo "error: no such command: \`fmt\`" >&2; exit 101; fi\n'
|
|
printf 'exec %s "$@"\n' "$real_cargo"
|
|
} > "$work/stub2/cargo"
|
|
chmod +x "$work/stub2/cargo"
|
|
PATH="$work/stub2:$PATH" "$RUN" "$work/repo" >/dev/null 2>&1
|
|
rc=$?
|
|
if [ "$rc" = 2 ]; then
|
|
ok "a missing rustfmt component is exit 2, not \"your code is misformatted\""
|
|
else
|
|
bad "a missing rustfmt component is exit 2" "exit $rc -- the probe is gone or unreached"
|
|
fi
|
|
|
|
# --fix must actually rewrite, or the gate has a repair path that does nothing.
|
|
scaffold
|
|
printf '%s' "$DIRTY" > "$work/repo/nested/src/lib.rs"
|
|
if run_case "--fix rewrites a nested file" 0 "$work/repo" --fix; then
|
|
printf '%s' "$CLEAN" > "$work/want.rs"
|
|
if cmp -s "$work/want.rs" "$work/repo/nested/src/lib.rs"; then
|
|
ok " and the file now matches rustfmt"
|
|
else
|
|
bad " and the file now matches rustfmt" "still: $(cat "$work/repo/nested/src/lib.rs")"
|
|
fi
|
|
fi
|
|
|
|
printf '\nfmt-workspaces-test: %d passed, %d failed\n' "$pass" "$fail"
|
|
[ "$fail" -eq 0 ]
|