Repository: mitsuhiko/insta (language: rust)

Issue:
Allowing customization of `cargo nextest` command
First of all, thanks for maintaining the project, I appreciate !

In our CI, we are using Nix for reproducible environment. And in this context when issuing a `cargo-insta`, it points to `/nix/store/[hash]-cargo-insta/bin`.

And when using nextest as the runner, `cargo-insta` [expends the command](https://github.com/mitsuhiko/insta/blob/17bd8abea293bc148702a1c9e75d05c7251b6f05/cargo-insta/src/cli.rs#L941-L948) to `cargo nextest run` with `nextest` not in our `~/.cargo/bin`.

I think it makes complete sense to use the same `cargo` that started the `cargo insta` command. But in our case, we would like `cargo-nextest` to be invoked instead of `cargo nextest`.

Would it make sense to be able to replace it? Or is it too niche?
Or is there any other solutions I am not seeing with rust to make `cargo nextest` points to `cargo-nextest`?

I'm a bit of a newbie to Rust and rust toolchain, so my assumptions might be wrong, don't hesitate to double check them :) 

Edit: Obviously, if this is doable and makes sense to integrate here. I will implement the feature !


Discussion / hints:
I'm open to it; I also don't know enough about how `cargo` & paths work to be able to assess whether it's always OK to defer to `cargo-nextest`. Is it right to think that it could be different from `cargo nextest` when:
- there's a `cargo-nextest` in the system path before `cargo`
- it points to something different to the `cargo-nextest` in the default `~/.cargo/bin`
?

A couple options:
- We could add a "test runner path" config
- Or possibly attempt to identify when a path is passed to `--test-runner` and use that. The latter would require you to pass a path rather than just `cargo-nextest`, and we'd need to consider how to handle not knowing whether `nextest` is being called (we currently do a couple of things slightly differently)
- I tried to see whether there was an env var you could pass to get `cargo test` to invoke a different binary, but couldn't [find one](https://doc.rust-lang.org/cargo/reference/environment-variables.html)
> there's a cargo-nextest in the system path before cargo
From what I've read in cargo so far, even if `cargo-next` is in the path before `cargo`, the `cargo-nextest` called is the one cargo decides (usually `~/.cargo/cargo-nextest`.
> it points to something different to the cargo-nextest in the default ~/.cargo/bin
Completely true :+1:

I kinda like the first option, (I didn't know there could be a config, I was thinking about an env var at first). This would avoid adding a confusing command line that 99% of the callers won't care about.

For the second option, I am afraid end-user will get confused wether to use a path or an enum for the same argument.

So I would go for the first option. WDYT?


OK great!

Assuming it's consistent with the existing configs + we add a bullet to the docs, I'm good to merge an env var...
Awesome !
I'll give it a try using a config first. Seems cleaner and I don't think
there are other features using env Var.

I'll ping you once I have something I am happy with. Thanks for your time :)

Le ven. 7 févr. 2025, 23:18, Maximilian Roos ***@***.***> a
écrit :

> OK great!
>
> Assuming it's consistent with the existing configs + we add a bullet to
> the docs, I'm good to merge an env var...
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/mitsuhiko/insta/issues/718#issuecomment-2644230803>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AEHWBOLNO5UBHS7VD2BIX6D2OUWMBAVCNFSM6AAAAABWTSKBNCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMNBUGIZTAOBQGM>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>

(FYI there are lots of features using an env var! Search for `INSTA_`, lmk if you need more info)

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a20e5857..57f1e9a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 All notable changes to insta and cargo-insta are documented here.
 
+- Support specifying `cargo-nextest` bin with `INSTA_CARGO_NEXTEST_BIN`.  #721 (Louis Fruleux)
+
 ## 1.42.3
 
 - Support other indention characters than spaces in inline snapshots.  #679
diff --git a/Makefile b/Makefile
index 0cb26419..6af335fa 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,6 @@ test: cargotest
 
 cargotest:
 	@echo "CARGO TESTS"
-	@rustup component add rustfmt 2> /dev/null
 	@cargo test -p insta
 	@cargo test -p insta --all-features
 	@cargo test -p insta --no-default-features
diff --git a/cargo-insta/src/cli.rs b/cargo-insta/src/cli.rs
index bc78b378..7d3e18db 100644
--- a/cargo-insta/src/cli.rs
+++ b/cargo-insta/src/cli.rs
@@ -937,14 +937,16 @@ fn prepare_test_runner<'snapshot_ref>(
     snapshot_ref_file: Option<&'snapshot_ref Path>,
     loc: &LocationInfo,
 ) -> Result<(process::Command, Option<Cow<'snapshot_ref, Path>>, bool), Box<dyn Error>> {
-    let mut proc = process::Command::new(get_cargo());
-    match test_runner {
+    let mut proc = match test_runner {
         TestRunner::CargoTest | TestRunner::Auto => {
+            let mut proc = process::Command::new(get_cargo());
             proc.arg("test");
+            proc
         }
         TestRunner::Nextest => {
-            proc.arg("nextest");
+            let mut proc = get_cargo_nextest_command();
             proc.arg("run");
+            proc
         }
     };
 
@@ -1111,6 +1113,18 @@ fn prepare_test_runner<'snapshot_ref>(
     Ok((proc, snapshot_ref_file, prevents_doc_run))
 }
 
+fn get_cargo_nextest_command() -> std::process::Command {
+    let cargo_nextest = env::var_os("INSTA_CARGO_NEXTEST_BIN");
+    match cargo_nextest.as_deref() {
+        Some(cargo_nextest_bin_path) => process::Command::new(cargo_nextest_bin_path),
+        None => {
+            let mut proc = process::Command::new(get_cargo());
+            proc.arg("nextest");
+            proc
+        }
+    }
+}
+
 fn show_cmd(cmd: ShowCommand) -> Result<(), Box<dyn Error>> {
     let loc = handle_target_args(&cmd.target_args, &[])?;
     let snapshot = Snapshot::from_file(&cmd.path)?;
@@ -1280,3 +1294,30 @@ pub(crate) fn run() -> Result<(), Box<dyn Error>> {
         Command::PendingSnapshots(cmd) => pending_snapshots_cmd(cmd),
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn get_cargo_nextest_command_from_env_variables() {
+        env::set_var("INSTA_CARGO_NEXTEST_BIN", "/a/custom/path/to/cargo-nextest");
+        let command = get_cargo_nextest_command();
+        assert_eq!(
+            command.get_program().to_string_lossy(),
+            "/a/custom/path/to/cargo-nextest"
+        );
+        assert_eq!(command.get_args().len(), 0);
+        env::remove_var("INSTA_CARGO_NEXTEST_BIN");
+
+        env::set_var("CARGO", "/a/path/to/cargo");
+        let command = get_cargo_nextest_command();
+        assert_eq!(command.get_program().to_string_lossy(), "/a/path/to/cargo");
+        let args: Vec<String> = command
+            .get_args()
+            .map(|arg| arg.to_string_lossy().to_string())
+            .collect();
+        assert_eq!(args, vec!["nextest"]);
+        env::remove_var("CARGO");
+    }
+}
diff --git a/insta/src/lib.rs b/insta/src/lib.rs
index b143dad3..12d4cd66 100644
--- a/insta/src/lib.rs
+++ b/insta/src/lib.rs
@@ -227,6 +227,7 @@
 //! # these are used by cargo insta test
 //! test:
 //!   # also set by INSTA_TEST_RUNNER
+//!   # cargo-nextest binary path can be explicitly set by INSTA_CARGO_NEXTEST_BIN
 //!   runner: "auto" | "cargo-test" | "nextest"
 //!   # whether to fallback to `cargo-test` if `nextest` is not available,
 //!   # also set by INSTA_TEST_RUNNER_FALLBACK, default false


Test patch: