diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e9adc4d..f30be138 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,12 @@ cargo run -p cargo-insta -- test # (or `review` or whatever command you want to ...in contrast to running `cargo insta`, which invokes the installed version of `cargo-insta`, and so make iterating more difficult. +To run the version of `cargo-insta` in the working directory on another crate, run: + +```sh +cargo run -p cargo-insta -- test --manifest-path=../insta-bug-repro/Cargo.toml +``` + ## Writing tests If making non-trivial changes to `cargo-insta`, please add an integration test to diff --git a/cargo-insta/src/cli.rs b/cargo-insta/src/cli.rs index 9f840bc9..369486b8 100644 --- a/cargo-insta/src/cli.rs +++ b/cargo-insta/src/cli.rs @@ -18,7 +18,6 @@ use uuid::Uuid; use crate::cargo::{find_snapshot_roots, Package}; use crate::container::{Operation, SnapshotContainer}; use crate::utils::cargo_insta_version; -use crate::utils::INSTA_VERSION; use crate::utils::{err_msg, QuietExit}; use crate::walk::{find_pending_snapshots, make_snapshot_walker, FindFlags}; @@ -395,6 +394,9 @@ struct LocationInfo<'a> { packages: Vec, exts: Vec<&'a str>, find_flags: FindFlags, + /// The insta version in the current workspace (i.e. not the `cargo-insta` + /// binary that's running). + insta_version: Version, } fn get_find_flags(tool_config: &ToolConfig, target_args: &TargetArgs) -> FindFlags { @@ -439,7 +441,7 @@ fn handle_target_args<'a>( (None, None) => {} }; - let metadata = cmd.no_deps().exec()?; + let metadata = cmd.exec()?; let workspace_root = metadata.workspace_root.as_std_path().to_path_buf(); let tool_config = ToolConfig::from_workspace(&workspace_root)?; @@ -462,6 +464,13 @@ fn handle_target_args<'a>( } else { vec![metadata.root_package().unwrap().clone()] }; + let insta_version = metadata + .packages + .iter() + .find(|package| package.name == "insta") + .map(|package| package.version.clone()) + .ok_or_else(|| eprintln!("insta not found in cargo metadata; defaulting to 1.0.0")) + .unwrap_or(Version::new(1, 0, 0)); Ok(LocationInfo { workspace_root, @@ -478,6 +487,7 @@ fn handle_target_args<'a>( .collect(), find_flags: get_find_flags(&tool_config, target_args), tool_config, + insta_version }) } @@ -693,6 +703,7 @@ fn test_run(mut cmd: TestCommand, color: ColorWhen) -> Result<(), Box color, &[], None, + &loc, )?; if !cmd.keep_pending { @@ -717,6 +728,7 @@ fn test_run(mut cmd: TestCommand, color: ColorWhen) -> Result<(), Box color, &["--doc"], snapshot_ref_file.as_deref(), + &loc, )?; success = success && proc.status()?.success(); } @@ -892,7 +904,9 @@ fn handle_unreferenced_snapshots( } /// Create and setup a `Command`, translating our configs into env vars & cli options +// TODO: possibly we can clean this function up a bit, reduce the number of args #[allow(clippy::type_complexity)] +#[allow(clippy::too_many_arguments)] fn prepare_test_runner<'snapshot_ref>( test_runner: TestRunner, test_runner_fallback: bool, @@ -901,6 +915,7 @@ fn prepare_test_runner<'snapshot_ref>( color: ColorWhen, extra_args: &[&str], snapshot_ref_file: Option<&'snapshot_ref Path>, + loc: &LocationInfo, ) -> Result<(process::Command, Option>, bool), Box> { let cargo = env::var_os("CARGO"); let cargo = cargo @@ -910,7 +925,7 @@ fn prepare_test_runner<'snapshot_ref>( // `test_runner_fallback` is true let test_runner = if test_runner == TestRunner::Nextest && test_runner_fallback - && std::process::Command::new("cargo") + && std::process::Command::new(cargo) .arg("nextest") .arg("--version") .output() @@ -1006,7 +1021,7 @@ fn prepare_test_runner<'snapshot_ref>( "INSTA_UPDATE", // Don't set `INSTA_UPDATE=force` for `--force-update-snapshots` on // older versions - if *INSTA_VERSION >= Version::new(1,41,0) { + if loc.insta_version >= Version::new(1,41,0) { match (cmd.check, cmd.accept_unseen, cmd.force_update_snapshots) { (true, false, false) => "no", (false, true, false) => "unseen", @@ -1022,7 +1037,7 @@ fn prepare_test_runner<'snapshot_ref>( } } ); - if cmd.force_update_snapshots && *INSTA_VERSION < Version::new(1, 40, 0) { + if cmd.force_update_snapshots && loc.insta_version < Version::new(1, 40, 0) { // Currently compatible with older versions of insta. proc.env("INSTA_FORCE_UPDATE_SNAPSHOTS", "1"); proc.env("INSTA_FORCE_UPDATE", "1"); diff --git a/cargo-insta/src/utils.rs b/cargo-insta/src/utils.rs index 53d5b621..dc252b54 100644 --- a/cargo-insta/src/utils.rs +++ b/cargo-insta/src/utils.rs @@ -1,10 +1,6 @@ use std::error::Error; use std::fmt; -use cargo_metadata::MetadataCommand; -use lazy_static::lazy_static; -use semver::Version; - /// Close without message but exit code. #[derive(Debug)] pub(crate) struct QuietExit(pub(crate) i32); @@ -32,23 +28,7 @@ pub(crate) fn err_msg>(s: S) -> Box { Box::new(ErrMsg(s.into())) } -/// The insta version in the current workspace (i.e. not the `cargo-insta` -/// binary that's running). -fn read_insta_version() -> Result> { - MetadataCommand::new() - .exec()? - .packages - .iter() - .find(|package| package.name == "insta") - .map(|package| package.version.clone()) - .ok_or("insta not found in cargo metadata".into()) -} - -lazy_static! { - pub static ref INSTA_VERSION: Version = read_insta_version().unwrap(); -} - -/// `cargo-insta` version +/// `cargo-insta` version (i.e. the binary that's currently running). // We could put this in a lazy_static pub(crate) fn cargo_insta_version() -> String { env!("CARGO_PKG_VERSION").to_string() diff --git a/insta/src/env.rs b/insta/src/env.rs index eabd0833..327f7b8e 100644 --- a/insta/src/env.rs +++ b/insta/src/env.rs @@ -406,7 +406,9 @@ pub fn snapshot_update_behavior(tool_config: &ToolConfig, unseen: bool) -> Snaps } } -/// Returns the cargo workspace for a manifest +/// Returns the cargo workspace path for a crate manifest, like +/// `/Users/janedoe/projects/insta` when passed +/// `/Users/janedoe/projects/insta/insta/Cargo.toml`. pub fn get_cargo_workspace(manifest_dir: &str) -> Arc { // If INSTA_WORKSPACE_ROOT environment variable is set, use the value as-is. // This is useful where CARGO_MANIFEST_DIR at compilation points to some @@ -465,6 +467,13 @@ pub fn get_cargo_workspace(manifest_dir: &str) -> Arc { .clone() } +#[test] +fn test_get_cargo_workspace() { + let workspace = get_cargo_workspace(env!("CARGO_MANIFEST_DIR")); + // The absolute path of the workspace, like `/Users/janedoe/projects/insta` + assert!(workspace.ends_with("insta")); +} + #[cfg(feature = "_cargo_insta_internal")] impl std::str::FromStr for TestRunner { type Err = ();