use indexmap::IndexSet;
use std::collections::HashSet;
use std::path::PathBuf;
use xx::file::display_path;
use super::strip_orig_suffix;
use super::types::Step;
pub(crate) fn try_canonicalize(path: &PathBuf) -> PathBuf {
match path.canonicalize() {
Ok(p) => p,
Err(err) => {
warn!("failed to canonicalize file: {} {err}", display_path(path));
path.to_path_buf()
}
}
}
impl Step {
pub(crate) fn filter_files_from_check_list(
&self,
original_files: &[PathBuf],
stdout: &str,
) -> (Vec<PathBuf>, Vec<PathBuf>) {
let listed: HashSet<PathBuf> = stdout
.lines()
.map(|p| try_canonicalize(&PathBuf::from(p)))
.collect();
let files: IndexSet<PathBuf> = original_files
.iter()
.filter(|f| listed.contains(&try_canonicalize(f)))
.cloned()
.collect();
let canonicalized_files: IndexSet<PathBuf> = files.iter().map(try_canonicalize).collect();
let extras: Vec<PathBuf> = listed
.into_iter()
.filter(|f| !canonicalized_files.contains(f))
.collect();
(files.into_iter().collect(), extras)
}
pub(crate) fn filter_files_from_check_diff(
&self,
original_files: &[PathBuf],
stdout: &str,
) -> (Vec<PathBuf>, Vec<PathBuf>) {
let stdout = strip_orig_suffix(stdout);
let mut listed: HashSet<PathBuf> = HashSet::new();
let mut has_a_prefix = false;
let mut has_b_prefix = false;
for line in stdout.lines() {
if line.starts_with("--- a/") {
has_a_prefix = true;
} else if line.starts_with("+++ b/") {
has_b_prefix = true;
}
if has_a_prefix && has_b_prefix {
break;
}
}
let should_strip_prefixes = has_a_prefix && has_b_prefix;
for line in stdout.lines() {
if line.starts_with("--- ") {
if let Some(path_str) = line.strip_prefix("--- ") {
let path = if let Some((before_tab, _)) = path_str.split_once('\t') {
before_tab.trim()
} else {
path_str.trim()
};
let path = if should_strip_prefixes {
path.strip_prefix("a/")
.or_else(|| path.strip_prefix("b/"))
.unwrap_or(path)
} else {
path
};
listed.insert(try_canonicalize(&PathBuf::from(path)));
}
} else if line.starts_with("+++ ")
&& let Some(path_str) = line.strip_prefix("+++ ")
{
let path = if let Some((before_tab, _)) = path_str.split_once('\t') {
before_tab.trim()
} else {
path_str.trim()
};
let path = if should_strip_prefixes {
path.strip_prefix("a/")
.or_else(|| path.strip_prefix("b/"))
.unwrap_or(path)
} else {
path
};
listed.insert(try_canonicalize(&PathBuf::from(path)));
}
}
let files: IndexSet<PathBuf> = original_files
.iter()
.filter(|f| listed.contains(&try_canonicalize(f)))
.cloned()
.collect();
let canonicalized_files: IndexSet<PathBuf> = files.iter().map(try_canonicalize).collect();
let extras: Vec<PathBuf> = listed
.into_iter()
.filter(|f| !canonicalized_files.contains(f))
.collect();
(files.into_iter().collect(), extras)
}
}