Skip to content

fix(test): drop serde_json dev-dependency to restore MSRV builds - #35

Open
JamBalaya56562 wants to merge 1 commit into
mitsuhiko:mainfrom
JamBalaya56562:claude/upstream-ci-failure-0gwde7
Open

fix(test): drop serde_json dev-dependency to restore MSRV builds#35
JamBalaya56562 wants to merge 1 commit into
mitsuhiko:mainfrom
JamBalaya56562:claude/upstream-ci-failure-0gwde7

Conversation

@JamBalaya56562

Copy link
Copy Markdown

Problem

The Tests workflow is red on main (d1356fd). Only the MSRV jobs fail; the latest-stable jobs pass:

Job Result
Test on Latest Linux
Test on Latest Windows
Test on 1.63.0 Linux ❌ exit 2
Test on 1.63.0 macOS ❌ exit 2
Test on 1.63.0 Windows ❌ exit 1

d1356fd ("fix(test): resolve example binaries from Cargo output") added a serde_json dev-dependency but did not update Cargo.lock.msrv. The MSRV jobs run cp Cargo.lock.msrv Cargo.lock and then cargo test --all, so cargo fills the gap by resolving the newest serde_json — 1.0.151, which declares rust-version = "1.71":

error: package `serde_json v1.0.151` cannot be built because it requires
       rustc 1.71 or newer, while the currently active rustc version is 1.63.0

Reproduced locally on Rust 1.63.0 with the CI's own recipe.

The same commit also introduced a let ... else, which is Rust 1.65 or later. That would have failed the MSRV jobs immediately after the serde_json problem was solved.

Fix

Pinning serde_json in Cargo.lock.msrv would work, but it means tracking the MSRV of serde_json plus itoa, ryu and serde from now on — the latest releases of all of those already require 1.68 or newer. Since the harness only needs three fields out of cargo's artifact messages, this scans them directly and drops the dependency again, leaving the crate with no dev-dependencies at all.

  • Cargo.toml: remove the [dev-dependencies] serde_json section.
  • tests/test_examples.rs: replace the serde_json::Value lookups with a small scanner (json_field / json_string / json_array_contains and a skip_* cursor) plus parse_example_artifact.

The behaviour d1356fd was after is preserved: example paths still come from cargo's --message-format=json-render-diagnostics output rather than being derived from the test executable's location, so custom build directories such as CARGO_BUILD_BUILD_DIR keep working. The cargo build --examples invocation, the BUILT_EXAMPLES cache, compile_example()'s signature and every existing test are untouched.

Two details the scanner gets right:

  • It tracks nesting depth and string literals, so json_field only ever matches a top-level key — a key of the same name deeper in the message is never mistaken for it.
  • It unescapes string values, which matters on Windows where executable arrives as "C:\\src\\target\\debug\\examples\\hello.exe".

Tests

Six unit tests are added for the scanner, covering a full real-world compiler-artifact line, escaped Windows paths, "executable":null and non-example targets, structural characters inside string values, malformed input, and the escape sequences (including \uXXXX surrogate pairs). They are pure functions, so they add no measurable runtime.

Verification

  • cargo test --all on stable — 13 tests + 5 doc-tests pass
  • make lint (cargo clippy --all -- -F clippy::dbg-macro -D warnings) — clean
  • make format-check — clean
  • ./demo.sh — exit 0
  • MSRV: cp Cargo.lock.msrv Cargo.lock && cargo test --all on Rust 1.63.0 — 13 tests + 5 doc-tests pass (fails before this change)
  • With serde_json gone, restoring Cargo.lock.msrv no longer pulls in anything new; the only remaining drift is the stale self-replace version entry (1.4.0 vs 1.5.0), which cargo rewrites harmlessly and which is left alone here.

Note

Unrelated to this change: test_self_delete_outside_path_force_exit is flaky on Linux, failing intermittently with ExecutableFileBusy ("Text file busy") when a copied example is executed while another test thread holds a write handle. This reproduces on unmodified d1356fd and is not addressed here.

The example test harness gained a `serde_json` dev-dependency, but
`Cargo.lock.msrv` was never updated to match.  The MSRV jobs restore that
lock file and let cargo fill in the gap, which resolves the newest
`serde_json` (1.0.151).  That release declares `rust-version = "1.71"`,
so all three 1.63.0 jobs failed with:

    error: package `serde_json v1.0.151` cannot be built because it
    requires rustc 1.71 or newer, while the currently active rustc
    version is 1.63.0

Pinning the dependency in `Cargo.lock.msrv` would work, but it also
means chasing the MSRV of `serde_json` and its transitive dependencies
(`itoa`, `ryu`, `serde`) from now on.  Since only three fields of
cargo's artifact messages are needed, scan them directly instead and
drop the dependency again.  The scanner tracks nesting and string
literals, so a key of the same name further down a message is never
mistaken for the one being looked for, and it unescapes string values so
that the backslashes in Windows executable paths survive.

The same commit also introduced a let-else, which is Rust 1.65 or later
and would have failed the MSRV jobs next; it is gone with the rewrite.

The new tests cover a real-world artifact message, escaped Windows
paths, structural characters inside string values, malformed input, the
escape sequences including surrogate pairs, and messages where the
fields exist but are shaped differently than cargo shapes them (a
`target` that is null, a string or an array, a non-array `kind`, and
non-string `name` and `executable` values).

Verified with the CI's own recipe (`cp Cargo.lock.msrv Cargo.lock` and
`cargo test --all`) on Rust 1.63.0, which now passes.  With
`serde_json` gone, restoring the MSRV lock leaves it fully in sync
again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CZz9vqNqNHujZgHxFMgPMy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants