use regex::{escape, Regex};
use crate::helpers::{read_file, Result};
pub fn check_contains_regex(
path: &str,
template: &str,
pkg_name: &str,
pkg_version: &str,
) -> Result<()> {
let orig_regex = template
.replace("{name}", &escape(pkg_name))
.replace("{version}", &escape(pkg_version));
let re = match Regex::new(&orig_regex) {
Ok(_) => {
let regex = String::from("(?m)") + &orig_regex;
Regex::new(®ex).unwrap()
}
Err(err) => return Err(format!("could not parse template: {}", err)),
};
let text = read_file(path).map_err(|err| format!("could not read {}: {}", path, err))?;
println!("Searching for \"{}\" in {}...", orig_regex, path);
match re.find(&text) {
Some(m) => {
let line_no = text[..m.start()].lines().count();
println!("{} (line {}) ... ok", path, line_no + 1);
Ok(())
}
None => Err(format!("could not find \"{}\" in {}", orig_regex, path)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bad_regex() {
assert_eq!(
check_contains_regex("README.md", "Version {version} [ups", "foobar", "1.2.3"),
Err(String::from(
[
r"could not parse template: regex parse error:",
r" Version 1\.2\.3 [ups",
r" ^",
r"error: unclosed character class"
]
.join("\n")
))
)
}
#[test]
fn not_found() {
assert_eq!(
check_contains_regex("README.md", "should not be found", "foobar", "1.2.3"),
Err(String::from(
"could not find \"should not be found\" in README.md"
))
)
}
#[test]
fn escaping() {
assert_eq!(
check_contains_regex(
"README.md",
"escaped: {name}-{version}, not escaped: foo*bar-1.2.3",
"foo*bar",
"1.2.3"
),
Err(String::from(
[
r#"could not find "escaped: foo\*bar-1\.2\.3,"#,
r#"not escaped: foo*bar-1.2.3" in README.md"#
]
.join(" ")
))
)
}
#[test]
fn good_pattern() {
assert_eq!(
check_contains_regex("README.md", "{name}", "version-sync", "1.2.3"),
Ok(())
)
}
}