Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use INSTA_UPDATE=force for forcing snapshot updates #482

Merged
merged 34 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8a33b66
Improve docs for snapshot updates
max-sixty May 2, 2024
642b6a4
max-sixty May 2, 2024
aeae8cb
.
max-sixty May 2, 2024
3527fa8
Use `INSTA_UPDATE=force` for forcing snapshot updates
max-sixty May 2, 2024
a280745
max-sixty May 2, 2024
0844f29
Merge branch 'snapshot-doc' into snapshot-force
max-sixty May 2, 2024
8595cd1
max-sixty May 2, 2024
e5437a1
max-sixty May 3, 2024
45236be
Merge branch 'master' into snapshot-force
max-sixty May 15, 2024
ea11073
Merge branch 'master' into snapshot-force
max-sixty Aug 4, 2024
4fde25c
Add integration tests for both pre & post 1.39
max-sixty Aug 4, 2024
1056bc4
max-sixty Aug 4, 2024
0aab8b7
max-sixty Aug 4, 2024
0e6fdfd
Merge branch 'master' into snapshot-force
max-sixty Aug 4, 2024
d5d1ab7
Make the deprecation warning logic clearer
max-sixty Aug 4, 2024
7c895b3
.
max-sixty Aug 5, 2024
d23a666
Use elog rather than eprint to get past cargo test filter
max-sixty Aug 5, 2024
c661164
Merge branch 'master' into snapshot-force
max-sixty Aug 6, 2024
4e73070
.
max-sixty Aug 6, 2024
a4c3b0c
max-sixty Aug 6, 2024
a8209a9
Merge branch 'master' into snapshot-force
max-sixty Aug 9, 2024
1d20e59
max-sixty Aug 9, 2024
e48e9ff
Merge branch 'master' into snapshot-force
max-sixty Aug 9, 2024
a7b7b3b
Merge branch 'master' into snapshot-force
max-sixty Aug 31, 2024
beb2c58
make inline snapshots work with the new `force`
max-sixty Aug 31, 2024
eb92ef4
max-sixty Aug 31, 2024
35b6321
max-sixty Aug 31, 2024
cdff50d
Add integration test for force updating
max-sixty Sep 1, 2024
dd4ad6f
Merge branch 'master' into snapshot-force
max-sixty Sep 1, 2024
6aca409
Merge branch 'master' into snapshot-force
max-sixty Sep 1, 2024
4c32289
Merge branch 'test-force-update' into snapshot-force
max-sixty Sep 1, 2024
e8df266
Merge branch 'master' into snapshot-force
max-sixty Sep 1, 2024
5ff1da6
Merge branch 'master' into snapshot-force
max-sixty Sep 7, 2024
2341f0d
missed release so bump versions
max-sixty Sep 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ inherits = "release"
lto = "thin"

[workspace.dependencies]
# Locking because of MSRV; wait for MSRV bump or msrv-resolver
# Needs pinning in Cargo.lock because of MSRV
clap = {version = "4.1", features = ["derive", "env"]}
17 changes: 9 additions & 8 deletions cargo-insta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-insta"
version = "1.40.0"
version = "1.41.0"
license = "Apache-2.0"
authors = ["Armin Ronacher <[email protected]>"]
description = "A review tool for the insta snapshot testing library for Rust"
Expand All @@ -11,24 +11,25 @@ keywords = ["snapshot", "testing", "jest"]
categories = ["development-tools::cargo-plugins"]
edition = "2021"
readme = "README.md"
rust-version = "1.64.0"
rust-version = "1.65.0"

[dependencies]
insta = { version = "=1.40.0", path = "../insta", features = ["json", "yaml", "redactions", "_cargo_insta_internal"] }
insta = { version = "=1.41.0", path = "../insta", features = ["json", "yaml", "redactions", "_cargo_insta_internal"] }
cargo_metadata = { version = "0.18.0", default-features = false }
console = "0.15.4"
serde = { version = "1.0.117", features = ["derive"] }
serde_json = "1.0.59"
proc-macro2 = { version = "1.0.60", features = ["span-locations"] }
# Pinned because of MSRV; wait for MSRV bump or msrv-resolver
# Needs pinning in Cargo.lock because of MSRV
syn = { version = "2.0.8", features = ["full", "visit", "extra-traits"] }
# Needs pinning in Cargo.lock because of MSRV
ignore = "0.4.17"
uuid = { version = "1.0.0", features = ["v4"] }
tempfile = "3.5.0"
# Not yet supported in our MSRV of 1.60.0
# clap = { workspace=true }
clap = {version = "4.1", features = ["derive", "env"]}

# Needs pinning in Cargo.lock because of MSRV
semver = {version = "1.0.7", features = ["serde"]}
lazy_static = "1.4.0"
clap = { workspace=true }

[dev-dependencies]
walkdir = "2.3.1"
Expand Down
32 changes: 24 additions & 8 deletions cargo-insta/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ use insta::Snapshot;
use insta::_cargo_insta_support::{
is_ci, SnapshotPrinter, SnapshotUpdate, TestRunner, ToolConfig, UnreferencedSnapshots,
};
use semver::Version;
use serde::Serialize;
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_snapshots, make_snapshot_walker, FindFlags};

Expand Down Expand Up @@ -592,6 +594,9 @@ fn test_run(mut cmd: TestCommand, color: ColorWhen) -> Result<(), Box<dyn Error>
cmd.accept = false;
}
}
SnapshotUpdate::Force => {
cmd.force_update_snapshots = true;
}
}

// --check always implies --no-force-pass as otherwise this command does not
Expand Down Expand Up @@ -943,16 +948,27 @@ fn prepare_test_runner<'snapshot_ref>(

proc.env(
"INSTA_UPDATE",
match (cmd.check, cmd.accept_unseen) {
(true, _) => "no",
(_, true) => "unseen",
(_, false) => "new",
},
// Don't set `INSTA_UPDATE=force` for `--force-update-snapshots` on
// older versions
if *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",
(false, false, false) => "new",
(false, _, true) => "force",
_ => return Err(err_msg(format!("invalid combination of flags: check={}, accept-unseen={}, force-update-snapshots={}", cmd.check, cmd.accept_unseen, cmd.force_update_snapshots))),
}
} else {
match (cmd.check, cmd.accept_unseen) {
(true, _) => "no",
(_, true) => "unseen",
(_, false) => "new",
}
}
);
if cmd.force_update_snapshots {
// for old versions of insta
if cmd.force_update_snapshots && *INSTA_VERSION < Version::new(1, 40, 0) {
// Currently compatible with older versions of insta.
proc.env("INSTA_FORCE_UPDATE_SNAPSHOTS", "1");
// for newer versions of insta
proc.env("INSTA_FORCE_UPDATE", "1");
}
if cmd.require_full_match {
Expand Down
20 changes: 20 additions & 0 deletions cargo-insta/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
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);
Expand Down Expand Up @@ -28,6 +32,22 @@ pub(crate) fn err_msg<S: Into<String>>(s: S) -> Box<dyn Error> {
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<Version, Box<dyn std::error::Error>> {
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
// We could put this in a lazy_static
pub(crate) fn cargo_insta_version() -> String {
Expand Down
20 changes: 7 additions & 13 deletions cargo-insta/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,12 +729,6 @@ fn test_virtual_manifest_single_crate() {

#[test]
fn test_force_update_snapshots() {
// We test with both 1.39 and `master`. These currently test the same code!
// But I copied the test from
// https://github.com/mitsuhiko/insta/pull/482/files where they'll test
// different code. If we don't end up merging that, we can remove one of the
// tests (but didn't think it was worthwhile to do the work to then undo it)

fn create_test_force_update_project(name: &str, insta_dependency: &str) -> TestProject {
TestFiles::new()
.add_file(
Expand Down Expand Up @@ -784,7 +778,7 @@ Hello, world!

let test_current_insta =
create_test_force_update_project("current", "{ path = '$PROJECT_PATH' }");
let test_insta_1_39_0 = create_test_force_update_project("1_39_0", "\"1.39.0\"");
let test_insta_1_40_0 = create_test_force_update_project("1_40_0", "\"1.40.0\"");

// Test with current insta version
let output_current = test_current_insta
Expand All @@ -795,14 +789,14 @@ Hello, world!

assert_success(&output_current);

// Test with insta 1.39.0
let output_1_39_0 = test_insta_1_39_0
// Test with insta 1.40.0
let output_1_40_0 = test_insta_1_40_0
.cmd()
.args(["test", "--accept", "--force-update-snapshots"])
.output()
.unwrap();

assert_success(&output_1_39_0);
assert_success(&output_1_40_0);

// Check that both versions updated the snapshot correctly
assert_snapshot!(test_current_insta.diff("src/snapshots/test_force_update_current__force_update.snap"), @r#"
Expand All @@ -820,9 +814,9 @@ Hello, world!
-
"#);

assert_snapshot!(test_insta_1_39_0.diff("src/snapshots/test_force_update_1_39_0__force_update.snap"), @r#"
--- Original: src/snapshots/test_force_update_1_39_0__force_update.snap
+++ Updated: src/snapshots/test_force_update_1_39_0__force_update.snap
assert_snapshot!(test_insta_1_40_0.diff("src/snapshots/test_force_update_1_40_0__force_update.snap"), @r#"
--- Original: src/snapshots/test_force_update_1_40_0__force_update.snap
+++ Updated: src/snapshots/test_force_update_1_40_0__force_update.snap
@@ -1,8 +1,5 @@
-
---
Expand Down
2 changes: 1 addition & 1 deletion insta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "insta"
version = "1.40.0"
version = "1.41.0"
license = "Apache-2.0"
authors = ["Armin Ronacher <[email protected]>"]
description = "A snapshot testing library for Rust"
Expand Down
74 changes: 50 additions & 24 deletions insta/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::{env, fmt, fs};

use crate::content::{yaml, Content};
use crate::utils::is_ci;
use crate::{
content::{yaml, Content},
elog,
};

lazy_static::lazy_static! {
static ref WORKSPACES: Mutex<BTreeMap<String, Arc<PathBuf>>> = Mutex::new(BTreeMap::new());
Expand Down Expand Up @@ -64,6 +67,7 @@ pub enum SnapshotUpdate {
Unseen,
New,
No,
Force,
}

#[derive(Debug)]
Expand Down Expand Up @@ -96,7 +100,6 @@ impl std::error::Error for Error {
/// Represents a tool configuration.
#[derive(Debug)]
pub struct ToolConfig {
force_update_snapshots: bool,
force_pass: bool,
require_full_match: bool,
output: OutputBehavior,
Expand Down Expand Up @@ -146,26 +149,44 @@ impl ToolConfig {
}
let cfg = cfg.unwrap_or_else(|| Content::Map(Default::default()));

// support for the deprecated environment variable. This is implemented in a way that
// cargo-insta can support older and newer insta versions alike. It will set both
// variables. However if only `INSTA_FORCE_UPDATE_SNAPSHOTS` is set, we will emit
// a deprecation warning.
if env::var("INSTA_FORCE_UPDATE").is_err() {
if let Ok("1") = env::var("INSTA_FORCE_UPDATE_SNAPSHOTS").as_deref() {
eprintln!("INSTA_FORCE_UPDATE_SNAPSHOTS is deprecated, use INSTA_FORCE_UPDATE");
env::set_var("INSTA_FORCE_UPDATE", "1");
}
// Support for the deprecated environment variables. This is
// implemented in a way that cargo-insta can support older and newer
// insta versions alike. Versions of `cargo-insta` <= 1.39 will set
// `INSTA_FORCE_UPDATE_SNAPSHOTS` & `INSTA_FORCE_UPDATE`.
//
// If `INSTA_FORCE_UPDATE_SNAPSHOTS` is the only env var present we emit
// a deprecation warning, later to be expanded to `INSTA_FORCE_UPDATE`.
//
// Another approach would be to pass the version of `cargo-insta` in a
// `INSTA_CARGO_INSTA_VERSION` env var, and then raise a warning unless
// running under cargo-insta <= 1.39. Though it would require adding a
// `semver` dependency to this crate or doing the version comparison
// ourselves (a tractable task...).
let force_update_old_env_vars = if let Ok("1") = env::var("INSTA_FORCE_UPDATE").as_deref() {
// Don't raise a warning yet, because recent versions of
// `cargo-insta` use this, so that it's compatible with older
// versions of `insta`.
//
// elog!("INSTA_FORCE_UPDATE is deprecated, use
// INSTA_UPDATE=force");
true
} else if let Ok("1") = env::var("INSTA_FORCE_UPDATE_SNAPSHOTS").as_deref() {
// Warn on an old envvar.
//
// There's some possibility that we're running from within an fairly
// old version of `cargo-insta` (before we added an
// `INSTA_CARGO_INSTA` env var, so we can't pick that up.) So offer
// a caveat in that case.
elog!("INSTA_FORCE_UPDATE_SNAPSHOTS is deprecated, use INSTA_UPDATE=force. (If running from `cargo insta`, no action is required; upgrading `cargo-insta` will silence this warning.)");
true
} else {
false
};
if force_update_old_env_vars {
env::set_var("INSTA_UPDATE", "force");
}

Ok(ToolConfig {
force_update_snapshots: match env::var("INSTA_FORCE_UPDATE").as_deref() {
Err(_) | Ok("") => resolve(&cfg, &["behavior", "force_update"])
.and_then(|x| x.as_bool())
.unwrap_or(false),
Ok("0") => false,
Ok("1") => true,
_ => return Err(Error::Env("INSTA_FORCE_UPDATE")),
},
require_full_match: match env::var("INSTA_REQUIRE_FULL_MATCH").as_deref() {
Err(_) | Ok("") => resolve(&cfg, &["behavior", "require_full_match"])
.and_then(|x| x.as_bool())
Expand Down Expand Up @@ -203,6 +224,14 @@ impl ToolConfig {
let val = match env_var.as_deref() {
Err(_) | Ok("") => resolve(&cfg, &["behavior", "update"])
.and_then(|x| x.as_str())
// Legacy support for the old force update config
.or(resolve(&cfg, &["behavior", "force_update"]).and_then(|x| {
elog!("`force_update: true` is deprecated in insta config files, use `update: force`");
match x.as_bool() {
Some(true) => Some("force"),
_ => None,
}
}))
.unwrap_or("auto"),
Ok(val) => val,
};
Expand All @@ -212,6 +241,7 @@ impl ToolConfig {
"new" => SnapshotUpdate::New,
"unseen" => SnapshotUpdate::Unseen,
"no" => SnapshotUpdate::No,
"force" => SnapshotUpdate::Force,
_ => return Err(Error::Env("INSTA_UPDATE")),
}
},
Expand Down Expand Up @@ -278,11 +308,6 @@ impl ToolConfig {

// TODO: Do we want all these methods, vs. just allowing access to the fields?

/// Is insta told to force update snapshots?
pub fn force_update_snapshots(&self) -> bool {
self.force_update_snapshots
}

/// Should we fail if metadata doesn't match?
pub fn require_full_match(&self) -> bool {
self.require_full_match
Expand Down Expand Up @@ -380,6 +405,7 @@ pub fn snapshot_update_behavior(tool_config: &ToolConfig, unseen: bool) -> Snaps
}
SnapshotUpdate::New => SnapshotUpdateBehavior::NewFile,
SnapshotUpdate::No => SnapshotUpdateBehavior::NoUpdate,
SnapshotUpdate::Force => SnapshotUpdateBehavior::InPlace,
}
}

Expand Down
5 changes: 2 additions & 3 deletions insta/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
//! - `unseen`: `always` for previously unseen snapshots or `new` for existing
//! snapshots
//! - `no`: does not write to snapshot files at all; just runs tests
//! - `force`: forcibly updates snapshot files, even if assertions pass
//!
//! When `new`, `auto` or `unseen` is used, the
//! [`cargo-insta`](https://crates.io/crates/cargo-insta) command can be used to
Expand Down Expand Up @@ -207,16 +208,14 @@
//!
//! ```yaml
//! behavior:
//! # also set by INSTA_FORCE_UPDATE
//! force_update: true/false
//! # also set by INSTA_REQUIRE_FULL_MATCH
//! require_full_match: true/false
//! # also set by INSTA_FORCE_PASS
//! force_pass: true/false
//! # also set by INSTA_OUTPUT
//! output: "diff" | "summary" | "minimal" | "none"
//! # also set by INSTA_UPDATE
//! update: "auto" | "always" | "new" | "unseen" | "no"
//! update: "auto" | "new" | "always" | "no" | "unseen" | "force"
//! # also set by INSTA_GLOB_FAIL_FAST
//! glob_fail_fast: true/false
//!
Expand Down
Loading
Loading