use crate::{
cli::options::ChangenogOptions,
git::{commit::GitCommit, tag::GitTag},
};
#[derive(Debug, Clone)]
pub struct ReleaseEntry {
pub tags: Vec<GitTag>,
pub commits: Vec<GitCommit>,
}
#[derive(Debug, Clone)]
pub struct ReleaseCollection(pub Vec<ReleaseEntry>);
impl ReleaseEntry {
fn new() -> ReleaseEntry {
ReleaseEntry {
tags: vec![],
commits: vec![],
}
}
}
impl ReleaseCollection {
pub fn from(
tags: &[GitTag],
prev_entry_tag: &Option<String>,
opts: &ChangenogOptions,
) -> ReleaseCollection {
let mut collection = ReleaseCollection(vec![]);
let mut entry = ReleaseEntry::new();
for i in 0..tags.len() {
if collection.0.len() >= opts.max_entries {
break;
}
let curr_tag = &tags[i];
let prev_tag_name = tags
.get(i + 1)
.map(|t| t.name.clone())
.or(prev_entry_tag.clone());
let commits = GitCommit::get_all_for_tag(curr_tag, &prev_tag_name, opts);
let filtered_commits = GitCommit::apply_filters(&commits, &opts.commit_filters);
if curr_tag.passes_filters(&opts.tag_filters) {
entry.tags.push(curr_tag.clone());
}
if filtered_commits.is_empty() {
continue;
}
if entry.tags.is_empty() {
if let Some(prev_entry) = collection.0.last_mut() {
prev_entry.commits.extend(filtered_commits);
}
} else {
entry.tags.sort_by(|a, b| a.name.cmp(&b.name));
entry.commits.extend(filtered_commits);
collection.0.push(entry);
entry = ReleaseEntry::new();
}
}
collection
}
}