use super::common::{fail, hl, ok};
use crate::check::Outcome;
fn markers() -> [String; 3] {
["<", "=", ">"].map(|c| c.repeat(7))
}
fn is_own_test(file: &str, hook_name: &str) -> bool {
file.starts_with(&format!("tests/{hook_name}.test."))
}
pub fn run(hook_name: &str, _args: &[std::ffi::OsString]) -> Outcome {
let m = markers();
let staged = super::common::staged_files(&[]);
let flagged: Vec<String> = staged
.into_iter()
.filter(|f| !is_own_test(f, hook_name))
.filter(|file| {
crate::git::stdout(&["show", &format!(":{file}")])
.map(|c| m.iter().all(|mk| c.contains(mk.as_str())))
.unwrap_or(false)
})
.collect();
if !flagged.is_empty() {
fail(&format!(
"Merge conflict detected in {}",
hl(&flagged.join(", "))
));
return Outcome::Failed;
}
ok("No merge conflict detected");
Outcome::Passed
}
#[cfg(test)]
mod tests {
use super::markers;
#[test]
fn the_markers_are_the_real_seven_character_ones() {
let m = markers();
assert_eq!(m[0].len(), 7);
assert_eq!(m[0], "<".repeat(7));
assert_eq!(m[1], "=".repeat(7));
assert_eq!(m[2], ">".repeat(7));
}
#[test]
fn the_hooks_own_test_is_excluded() {
let n = "pre-commit-merge-conflict";
assert!(super::is_own_test(
"tests/pre-commit-merge-conflict.test.zsh",
n
));
assert!(!super::is_own_test(
"tests/pre-commit-ban-terms.test.zsh",
n
));
assert!(!super::is_own_test("src/main.rs", n));
}
#[test]
fn this_file_contains_no_literal_marker() {
let src = include_str!("merge_conflict.rs");
for m in markers() {
assert!(!src.contains(&m), "literal marker present in this file");
}
}
}