use crate::tera::{render_template, tera_context};
use anyhow::Context as _;
use regex::Regex;
pub(crate) fn get_release_regex(template: &str, package_name: &str) -> anyhow::Result<Regex> {
const VERSION_PLACEHOLDER: &str = "0.0.0-VERSION-PLACEHOLDER";
let context = tera_context(package_name, VERSION_PLACEHOLDER);
let rendered = render_template(template, &context, "release_tag_name")
.context("failed to render release tag name template")?;
let escaped = regex::escape(&rendered);
let pattern = escaped.replace(®ex::escape(VERSION_PLACEHOLDER), r"(\d+\.\d+\.\d+)");
let full_regex = format!(r"^{pattern}$");
Regex::new(&full_regex).context("build release tag regex")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn release_regex_version_only_template() {
let regex = get_release_regex("v{{ version }}", "ignored").unwrap();
assert!(regex.is_match("v1.2.3"));
assert!(regex.is_match("v0.0.1"));
assert!(!regex.is_match("1.2.3")); assert!(!regex.is_match("v1.2")); assert!(!regex.is_match("v1.2.3.4"));
let captures = regex.captures("v1.2.3").unwrap();
assert_eq!(captures.get(1).unwrap().as_str(), "1.2.3");
}
#[test]
fn release_regex_package_and_version_template() {
let regex = get_release_regex("{{ package }}-v{{ version }}", "mylib").unwrap();
assert!(regex.is_match("mylib-v1.2.3"));
assert!(!regex.is_match("otherlib-v1.2.3"));
assert!(!regex.is_match("mylib-1.2.3")); assert!(!regex.is_match("v1.2.3"));
let captures = regex.captures("mylib-v4.5.6").unwrap();
assert_eq!(captures.get(1).unwrap().as_str(), "4.5.6");
}
#[test]
fn release_regex_custom_template() {
let regex = get_release_regex("release-{{ version }}-prod", "ignored").unwrap();
assert!(regex.is_match("release-1.2.3-prod"));
assert!(!regex.is_match("release-1.2.3"));
assert!(!regex.is_match("v1.2.3"));
let captures = regex.captures("release-0.1.0-prod").unwrap();
assert_eq!(captures.get(1).unwrap().as_str(), "0.1.0");
}
#[test]
fn release_regex_escapes_special_chars_in_template() {
let regex = get_release_regex("release.{{ version }}", "ignored").unwrap();
assert!(regex.is_match("release.1.2.3"));
assert!(!regex.is_match("releaseX1.2.3"));
}
#[test]
fn release_regex_escapes_special_chars_in_package_name() {
let regex = get_release_regex("{{ package }}-v{{ version }}", "my.package").unwrap();
assert!(regex.is_match("my.package-v1.2.3"));
assert!(!regex.is_match("myXpackage-v1.2.3"));
}
#[test]
fn release_regex_invalid_tera_syntax() {
let result = get_release_regex("{{ invalid syntax", "mylib");
assert!(result.is_err());
}
}