Subject
assert_cmd is a test-helper crate for asserting on the behaviour of command-line programs. It wraps std::process::Command with conveniences for finding a Cargo crate's compiled binaries (via CARGO_BIN_EXE_*), piping stdin, applying a per-invocation timeout (via wait-timeout), and asserting on stdout/stderr/exit-code through the predicates ecosystem. The crate is intended to be used from #[cfg(test)] integration tests.
Methodology
The published crate contents were compared against the upstream Git repository tag assert_cmd-v2.2.2 (commit feece89) using diff -r. All published source files (src/lib.rs, src/assert.rs, src/cargo.rs, src/cmd.rs, src/color.rs, src/macros.rs, src/output.rs, src/bin/bin_fixture.rs, totalling ~3050 lines), the build.rs, the two examples, and the Cargo.toml/Cargo.toml.orig pair were read. Upstream-only files (CHANGELOG.md, CONTRIBUTING.md, tests/, CI configs) were inspected for integration-test coverage. unsafe and extern "C" were searched with grep -nE. Tools used: openvet 0.x, GNU diff, BSD grep, BSD wc, BSD find.
Results
All published source files match upstream byte-for-byte; Cargo.toml.orig matches the upstream Cargo.toml exactly. The published Cargo.toml differs only by cargo's standard publish-time normalisation. The crate publishes a deliberate include whitelist that excludes the upstream tests/, CI configs, and changelog, justifying the absence of those files from the audit workspace. No proc-macro, no binary artefacts, no install hook (justifying has-binaries, has-install-exec). No obfuscation or unexplained behaviour was observed (justifying is-benign).
The crate has no unsafe and no extern "C" declarations (justifying uses-unsafe). It uses no network, JIT, interpreter, or cryptography (justifying uses-network, uses-jit, uses-interpreter, uses-crypto). It does not implement a parser, interpreter, JIT, protocol, data structure, algorithm, concurrency primitive, or cryptographic primitive (justifying impl-crypto, impl-parser, impl-interpreter, impl-jit, impl-protocol, impl-datastructure, impl-algorithm, impl-concurrency).
build.rs (17 lines) writes the cargo $TARGET triple to $OUT_DIR/current_target.txt, which src/cargo.rs reads back via include_str! to construct the CARGO_TARGET_<TRIPLET>_RUNNER env-var lookup key. The build script does no network I/O, writes only inside OUT_DIR, and is a pure function of cargo-provided environment, justifying has-build-exec together with build-exec-safe, build-exec-deterministic, build-exec-no-network, build-exec-no-write-out, build-exec-minimal.
The crate's runtime surface is exactly what its purpose requires: it spawns child processes via std::process::Command in argv form (no shell), reads CARGO_BIN_EXE_*, CARGO_TARGET_*_RUNNER, and the env::current_exe() legacy fallback for binary discovery, and constructs paths from those env vars. Process invocation is argv-only, with arguments and program names supplied by the (trusted) test author; this justifies uses-exec, exec-safe, uses-filesystem, filesystem-safe, uses-environment, environment-safe. Command::output() spawns three short-lived std::thread workers to drive stdin/stdout/stderr while the child runs, and joins them before returning; an optional wait_timeout triggers child.kill() then child.wait() on expiry. This justifies uses-concurrency, concurrency-safe, concurrency-documented (the thread-safety contract is enforced by Send + 'static bounds on the API).
Inline unit tests exist in src/cargo.rs:298 (validating the panic message when CARGO_BIN_EXE_* is unset) and integration tests live in the upstream tests/ directory (excluded from the published crate by the include whitelist but present in the workspace and exercised by CI), justifying has-unit-tests and has-integration-tests. No fuzz or property tests are present, which is appropriate for a thin test-helper library, justifying has-fuzz-tests and has-property-tests.
No findings were recorded.
Conclusion
assert_cmd is a small, mature test-helper crate. The published source matches upstream, the build script is minimal and safe, there is no unsafe code, and every "uses-" claim (exec, filesystem, environment, concurrency) is paired with a documented, safe usage pattern. The crate is safe to use as a dev-dependencies entry.