use crate::config::Config;
use crate::error::{Result, TagVerError};
use crate::version::Version;
use std::collections::HashMap;
pub type TagMap = HashMap<gix::ObjectId, Vec<VersionTag>>;
#[derive(Debug, Clone)]
pub struct VersionTag {
pub version: Version,
pub tag_name: String,
}
pub fn parse_tags(repo: &gix::Repository, config: &Config) -> Result<(TagMap, Vec<String>)> {
let mut tag_map: TagMap = HashMap::new();
let mut invalid_tags: Vec<String> = Vec::new();
let refs = repo
.references()
.map_err(|e| TagVerError::Other(format!("Failed to get references: {}", e)))?;
let tag_refs = refs
.tags()
.map_err(|e| TagVerError::Other(format!("Failed to get tags: {}", e)))?;
for mut tag_ref in tag_refs.flatten() {
let tag_name = tag_ref.name().shorten().to_string();
let version_str = if config.tag_prefix.is_empty() {
tag_name.clone()
} else if tag_name.starts_with(&config.tag_prefix) {
tag_name[config.tag_prefix.len()..].to_string()
} else {
continue; };
match version_str.parse::<semver::Version>() {
Ok(semver) => {
let target_id = match tag_ref.peel_to_id() {
Ok(id) => id.detach(),
Err(_) => continue, };
let version = Version::from_semver_full(&semver);
let version_tag = VersionTag {
version,
tag_name: tag_name.clone(),
};
tag_map.entry(target_id).or_default().push(version_tag);
}
Err(_) => {
invalid_tags.push(tag_name);
}
}
}
for tags in tag_map.values_mut() {
tags.sort_by(|a, b| b.version.cmp(&a.version));
}
Ok((tag_map, invalid_tags))
}