-
-
Notifications
You must be signed in to change notification settings - Fork 92
/
glob.rs
103 lines (88 loc) · 3 KB
/
glob.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::env;
use std::path::Path;
use std::sync::Mutex;
use globset::{GlobBuilder, GlobMatcher};
use once_cell::sync::Lazy;
use walkdir::WalkDir;
use crate::settings::Settings;
use crate::utils::style;
pub(crate) struct GlobCollector {
pub(crate) fail_fast: bool,
pub(crate) failed: usize,
pub(crate) show_insta_hint: bool,
}
// the glob stack holds failure count + an indication if cargo insta review
// should be run.
pub(crate) static GLOB_STACK: Lazy<Mutex<Vec<GlobCollector>>> = Lazy::new(Mutex::default);
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)
.literal_separator(true)
.build()
.unwrap()
.compile_matcher();
let walker = WalkDir::new(base).follow_links(true);
let mut glob_found_matches = false;
let mut settings = Settings::clone_current();
GLOB_STACK.lock().unwrap().push(GlobCollector {
failed: 0,
show_insta_hint: false,
fail_fast: std::env::var("INSTA_GLOB_FAIL_FAST").as_deref() == Ok("1"),
});
for file in walker {
let file = file.unwrap();
let path = file.path();
let stripped_path = path.strip_prefix(base).unwrap_or(path);
if !glob.is_match(stripped_path) {
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());
settings.bind(|| {
f(path);
});
}
let top = GLOB_STACK.lock().unwrap().pop().unwrap();
if !glob_found_matches && !settings.allow_empty_glob() {
panic!("the glob! macro did not match any files.");
}
if top.failed > 0 {
if top.show_insta_hint {
println!(
"{hint}",
hint = style("To update snapshots run `cargo insta review`").dim(),
);
}
if top.failed > 1 {
println!(
"{hint}",
hint = style("To enable fast failing for glob! export INSTA_GLOB_FAIL_FAST=1 as environment variable.").dim()
);
}
panic!(
"glob! resulted in {} snapshot assertion failure{}s",
top.failed,
if top.failed == 1 { "" } else { "s" },
);
}
}