use fancy_regex::Regex;
use crate::{cli::options::ChangenogOptions, utils::run};
use super::tag::GitTag;
#[derive(Debug, Clone)]
pub struct GitCommit {
pub hash: String,
pub subject: String,
}
impl GitCommit {
pub fn get_all_for_tag(
tag: &GitTag,
prev_tag_name: &Option<String>,
opts: &ChangenogOptions,
) -> Vec<GitCommit> {
let tag_range = if prev_tag_name.is_some() {
&format!("{}..{}", prev_tag_name.as_ref().unwrap(), tag.name)
} else {
&tag.name
};
let log_args = vec![
"log",
tag_range,
"--pretty=%H %s",
"--",
opts.root.to_str().unwrap(), ];
let cmd_output = run("git", &log_args).unwrap();
let raw_commits = cmd_output.lines().collect::<Vec<&str>>();
raw_commits
.iter()
.map(|l| GitCommit::from_raw(l))
.collect::<Vec<GitCommit>>()
}
pub fn from_raw(raw_commit: &str) -> Self {
let (hash, subject) = raw_commit.split_once(" ").unwrap();
Self {
hash: hash.to_string(),
subject: subject.to_string(),
}
}
pub fn apply_filters(commits: &[GitCommit], commit_filters: &[Regex]) -> Vec<GitCommit> {
commits
.iter()
.filter_map(|c| {
let all_filters_matched = commit_filters
.iter()
.all(|f| f.is_match(&c.subject).unwrap());
if all_filters_matched {
Some(c.clone())
} else {
None
}
})
.collect::<Vec<GitCommit>>()
}
}