Split a fmt usage error from a fmt verdict across both workspace roots
improvise-b4ks. From the repo root `cargo fmt -p opfs-contract -- --check`
exits 1 with "package `opfs-contract` is not a member of the workspace" and
never runs --check, so a caller reading $? cannot tell "misformatted" from
"nothing was checked". Reproduced at 7cef9f8.
scripts/fmt-workspaces.sh discovers every [workspace] root and checks each
with `-p <member>` scoped by that root's own --manifest-path. Exit 2 is a
usage error or an unrunnable cargo; exit 1 is a formatting verdict.
Both obvious spellings were measured and both fail in the direction that
looks like success: `--all` crosses the boundary, because it formats local
path dependencies and harness/opfs-contract depends on improvise-io by path
(an injected fault in src/draw.rs was reported by the harness root); and the
bare --manifest-path form is blind to workspace members, because the repo
root is a package as well as a workspace (an injected fault in
crates/improvise-core exited 0).
scripts/fmt-workspaces-test.sh is the check_the_checker. Four rivals were
injected and each failed it. Its fixture had to be corrected twice -- a
missing path dependency and a virtual outer manifest -- and both vacuities
were found only by injecting the rival, never by reading.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
This commit is contained in:
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/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"
|
||||
|
||||
# The load-bearing case. `cargo fmt --all` at the outer root cannot reach this
|
||||
# file, and `cargo fmt -p inner-pkg` from the outer root exits 1 saying `not a
|
||||
# member of the workspace` -- the usage error this whole script exists to split
|
||||
# from a real verdict.
|
||||
scaffold
|
||||
printf '%s' "$DIRTY" > "$work/repo/nested/src/lib.rs"
|
||||
if run_case "a fault in the NESTED workspace is reported" 1 "$work/repo"; then
|
||||
case "$OUT" in
|
||||
*nested/src/lib.rs*) ok " and the nested file is named" ;;
|
||||
*) bad " and the nested file is named" "output did not name it: ${OUT:0:300}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
scaffold
|
||||
printf '%s' "$DIRTY" > "$work/repo/a/src/lib.rs"
|
||||
if run_case "a fault in the OUTER workspace is reported" 1 "$work/repo"; then
|
||||
case "$OUT" in
|
||||
*a/src/lib.rs*) ok " and the outer file is named" ;;
|
||||
*) bad " and the outer file is named" "output did not name it: ${OUT:0:300}" ;;
|
||||
esac
|
||||
# The rival: spelling the per-root check `--all` instead of `-p <members>`
|
||||
# walks PAST the nested workspace boundary (measured), so the OUTER file is
|
||||
# reported a second time under the inner root. Counting is what sees that.
|
||||
n="$(printf '%s\n' "$OUT" | grep -c 'a/src/lib.rs')"
|
||||
if [ "$n" = 1 ]; then
|
||||
ok " and it is named ONCE -- no root reaches past its own boundary"
|
||||
else
|
||||
bad " and it is named ONCE" "named $n times; a root is walking past its boundary"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# --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 ]
|
||||
Reference in New Issue
Block a user