mfgames-conventional-commit-rs/src/tags.rs

86 lines
2.7 KiB
Rust

use anyhow::Result;
use git2::{Oid, Repository};
use semver::Version;
use slog::{debug, info, warn};
use std::cmp::Ordering;
use std::collections::HashMap;
pub fn get_tag_map<'a>(
log: &slog::Logger,
repo: &Repository,
tag_prefix: &str,
) -> Result<HashMap<Oid, Version>> {
let tag_name_list = &repo.tag_names(Some(tag_prefix))?;
let mut tag_map: HashMap<Oid, Version> = HashMap::new();
info!(log, "looking for {}", tag_prefix);
for name in tag_name_list.into_iter() {
// Get the object that we're pointing to.
let name = name.unwrap();
let obj = repo.revparse_single(&name)?;
if let Some(_tag) = obj.as_tag() {
warn!(log, "cannot handle a tag pointing to another tag");
} else if let Some(commit) = obj.as_commit() {
// Keep the OID since that is how we will look up the commits.
let oid = commit.id();
// Strip off the version and convert it into a semver.
let version = name.chars();
let version = version.skip(tag_prefix.len() - 1);
let version: String = version.collect();
// Try to convert the results into a semver.
let semver = Version::parse(&version);
if semver.is_err() {
warn!(log, "cannot parse {:?} from commit {}", version, oid);
continue;
}
let new_version = semver.unwrap();
if let Some(old_version) = tag_map.get(&oid) {
if new_version.cmp(old_version) == Ordering::Greater {
debug!(
log,
"updating version for {:?}: {} + {} -> {}",
oid,
old_version,
new_version,
new_version
);
tag_map.insert(oid, new_version);
} else {
debug!(
log,
"updating version for {:?}: {} + {} -> {}",
oid,
old_version,
new_version,
old_version
);
}
} else {
debug!(log, "setting version for {:?}: {}", oid, new_version);
tag_map.insert(oid, new_version);
}
} else {
warn!(
log,
"cannot handle a tag pointing to something other than a commit"
);
}
}
let tag_map_len = &tag_map.len();
info!(
log,
"loaded in {:?} tags matching {:?}", tag_map_len, tag_prefix
);
Ok(tag_map)
}