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

Implement INSTA_GLOB_FILTER #276

Merged
merged 2 commits into from Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cargo-insta/integration-tests/Cargo.toml
Expand Up @@ -8,6 +8,6 @@ edition = "2018"

[dependencies]
dircpy = "0.3.4"
insta = { version = "1.1.0", path = "../..", features = ["json", "yaml", "redactions", "glob"] }
insta = { path = "../..", features = ["json", "yaml", "redactions", "glob"] }
walkdir = "2.3.1"
serde = { version = "1.0.117", features = ["derive"] }
19 changes: 19 additions & 0 deletions cargo-insta/src/cli.rs
Expand Up @@ -140,6 +140,9 @@ pub struct TestCommand {
/// Delete unreferenced snapshots after the test run.
#[structopt(long)]
pub delete_unreferenced_snapshots: bool,
/// Filters to apply to the insta glob feature.
#[structopt(long)]
pub glob_filter: Vec<String>,
/// Do not pass the quiet flag (`-q`) to tests.
#[structopt(short = "Q", long)]
pub no_quiet: bool,
Expand Down Expand Up @@ -558,6 +561,22 @@ fn test_run(mut cmd: TestCommand, color: &str) -> Result<(), Box<dyn Error>> {
if cmd.force_update_snapshots {
proc.env("INSTA_FORCE_UPDATE_SNAPSHOTS", "1");
}

let glob_filter =
cmd.glob_filter
.iter()
.map(|x| x.as_str())
.fold(String::new(), |mut s, item| {
if !s.is_empty() {
s.push(';');
}
s.push_str(item);
s
});
if !glob_filter.is_empty() {
proc.env("INSTA_GLOB_FILTER", glob_filter);
}

if cmd.release {
proc.arg("--release");
}
Expand Down
28 changes: 26 additions & 2 deletions src/glob.rs
@@ -1,10 +1,27 @@
use std::env;
use std::path::Path;

use globset::GlobBuilder;
use globset::{GlobBuilder, GlobMatcher};
use once_cell::sync::Lazy;
use walkdir::WalkDir;

use crate::settings::Settings;

static GLOB_FILTER: Lazy<Vec<GlobMatcher>> = Lazy::new(|| {
env::var("INSTA_GLOB_FILTER")
.unwrap_or_default()
.split(';')
.filter(|x| !x.is_empty())
.filter_map(|filter| {
GlobBuilder::new(filter)
.case_insensitive(true)
.build()
.ok()
.map(|x| x.compile_matcher())
})
.collect()
});

pub fn glob_exec<F: FnMut(&Path)>(base: &Path, pattern: &str, mut f: F) {
let glob = GlobBuilder::new(pattern)
.case_insensitive(true)
Expand All @@ -25,10 +42,17 @@ pub fn glob_exec<F: FnMut(&Path)>(base: &Path, pattern: &str, mut f: F) {
continue;
}

glob_found_matches = true;

// if there is a glob filter, skip if it does not match this path
if !GLOB_FILTER.is_empty() && !GLOB_FILTER.iter().any(|x| x.is_match(stripped_path)) {
eprintln!("Skipping {} due to glob filter", stripped_path.display());
continue;
}

settings.set_input_file(&path);
settings.set_snapshot_suffix(path.file_name().unwrap().to_str().unwrap());

glob_found_matches = true;
settings.bind(|| {
f(path);
});
Expand Down
22 changes: 21 additions & 1 deletion src/macros.rs
Expand Up @@ -467,7 +467,27 @@ macro_rules! with_settings {

/// Executes a closure for all input files matching a glob.
///
/// The closure is passed the path to the file.
/// The closure is passed the path to the file. You can use [`std::fs::read_to_string`]
/// or similar functions to load the file and process it.
///
/// ```
/// # use insta::{assert_snapshot, glob, Settings};
/// # let mut settings = Settings::clone_current();
/// # settings.set_allow_empty_glob(true);
/// # let _dropguard = settings.bind_to_scope();
/// use std::fs;
///
/// glob!("inputs/*.txt", |path| {
/// let input = fs::read_to_string(path).unwrap();
/// assert_snapshot!(input.to_uppercase());
/// });
/// ```
///
/// The `INSTA_GLOB_FILTER` environment variable can be set to only execute certain files.
/// The format of the filter is a semicolon separated filter. For instance by setting
/// `INSTA_GLOB_FILTER` to `foo-*txt;bar-*.txt` only files starting with `foo-` or `bar-`
/// end ending in `.txt` will be executed. When using `cargo-insta` the `--glob-filter`
/// option can be used instead.
#[cfg(feature = "glob")]
#[cfg_attr(docsrs, doc(cfg(feature = "glob")))]
#[macro_export]
Expand Down