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

Raise an error on sufficiently different insta vs cargo-insta versions #509

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Next Next commit
Raise an error on sufficiently different insta vs cargo-insta ver…
…sions

This has two purposes:
- By raising an error if major versions differ, it allows eventually upgrading to insta 2 without confusing breaks (we want to add this sufficiently before releasing v2)
- It potentially allows for making some changes before a big break, by warning when minor versions differ sufficiently. This could be upgraded to an error. Currently we have a few deprecated items; and I was thinking of trying to unify some of the pending / named snapshot handling, but it becomes burdensome if we need to support the existing approach forever.

WDYT?
max-sixty committed Jun 17, 2024
commit 0fc3c73bbcffd15edbf434d725c40d78c5a25ab0
2 changes: 2 additions & 0 deletions cargo-insta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -24,6 +24,8 @@ syn = { version = "1.0.50", features = ["full", "visit", "extra-traits"] }
ignore = "0.4.17"
uuid = { version = "1.0.0", features = ["v4"] }
tempfile = "3.5.0"
semver = {version = "1.0.23", features = ["serde"]}
lazy_static = "1.4.0"

[dev-dependencies]
walkdir = "2.3.1"
65 changes: 65 additions & 0 deletions cargo-insta/src/cli.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,10 @@ use insta::Snapshot;
use insta::_cargo_insta_support::{
is_ci, SnapshotPrinter, SnapshotUpdate, TestRunner, ToolConfig, UnreferencedSnapshots,
};
use lazy_static::lazy_static;
use semver::Version;
use serde::Serialize;
use serde_json::Value;
use structopt::clap::AppSettings;
use structopt::StructOpt;
use uuid::Uuid;
@@ -1094,6 +1097,8 @@ pub(crate) fn run() -> Result<(), Box<dyn Error>> {
args.remove(1);
}

check_insta_cargo_insta_compat()?;

let opts = Opts::from_iter(args);

let color = handle_color(opts.color.as_deref())?;
@@ -1116,3 +1121,63 @@ pub(crate) fn run() -> Result<(), Box<dyn Error>> {
Command::PendingSnapshots(cmd) => pending_snapshots_cmd(cmd),
}
}

fn check_insta_cargo_insta_compat() -> Result<(), Box<dyn std::error::Error>> {
let insta_version = read_insta_version()?;
if insta_version.major != CARGO_INSTA_VERSION.major {
eprintln!(
"{}: insta version mismatch: cargo-insta is {}, but insta is {}",
style("error").bold().red(),
*CARGO_INSTA_VERSION,
insta_version
);
return Err(QuietExit(1).into());
}

if (insta_version.minor).abs_diff(CARGO_INSTA_VERSION.minor) > 10 {
eprintln!(
"{}: insta version {} is very different from cargo-insta version {}. This may raise an error in the future.",
style("error").bold().red(),
*CARGO_INSTA_VERSION,
insta_version
);
}

Ok(())
}

lazy_static! {
static ref CARGO_INSTA_VERSION: Version =
Version::parse(env!("CARGO_PKG_VERSION")).expect("Invalid cargo-insta version number");
}

fn run_cargo_metadata() -> Result<String, Box<dyn std::error::Error>> {
let output = std::process::Command::new("cargo")
.arg("metadata")
.arg("--format-version")
.arg("1")
.arg("--locked")
.output()?;

Ok(String::from_utf8(output.stdout)?)
}

fn read_insta_version() -> Result<Version, Box<dyn std::error::Error>> {
let json_output = run_cargo_metadata()?;
let json_value: Value = serde_json::from_str(&json_output)?;

let packages = json_value["packages"]
.as_array()
.ok_or("Couldn't read packages array")?;

let insta_package = packages
.iter()
.find(|package| package["name"].as_str().unwrap() == "insta")
.ok_or("insta dependency not found")?;

let version_str = insta_package["version"]
.as_str()
.ok_or("Invalid insta version")?;

Ok(Version::parse(version_str)?)
}