use indexmap::IndexMap;
use crate::change::get_changes;
use crate::change::Change;
use crate::config::Config;
use crate::version::Version;
use askama::{Error, Template};
use chrono::Local;
use serde::{Deserialize, Serialize};
#[derive(Template)]
#[template(path = "changelog.md.j2")]
struct MarkdownChangelog {
version: String,
date: String,
changes: IndexMap<String, ChangeTypeMap>,
}
#[derive(Template)]
#[template(path = "quasarChangelog.vue.j2")]
struct VueQuasarChangelog {
version: String,
date: String,
changes: IndexMap<String, ChangeTypeMap>,
}
#[derive(Clone, Debug)]
pub struct ChangeTypeMap {
pub features: Vec<Change>,
pub fixes: Vec<Change>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum TemplateOption {
Markdown,
VueQuasar,
}
impl TemplateOption {
pub fn values() -> Vec<Self> {
vec![Self::Markdown, Self::VueQuasar] }
}
impl std::fmt::Display for TemplateOption {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
TemplateOption::Markdown => write!(f, "Markdown"),
TemplateOption::VueQuasar => write!(f, "VueQuasar"),
}
}
}
pub fn generate_and_insert_changelogs(
version: &Version,
config: &Config,
) -> Result<Vec<String>, Error> {
let changes = get_changes(&config, &version);
let mut results = vec![];
config
.changelog_output_selections
.iter()
.for_each(|output_selection| match output_selection.template_option {
TemplateOption::Markdown => {
let changelog = MarkdownChangelog {
version: version.to_string(),
date: Local::now().format("%Y-%m-%d").to_string(),
changes: changes.clone(),
};
let rendered_log = changelog.render().expect("Failed to render changelog");
insert_changelog(&output_selection.output_filepath, &rendered_log);
results.push(format!(
" - Generated {} changelog at {}",
output_selection.template_option, output_selection.output_filepath
));
}
TemplateOption::VueQuasar => {
let changelog = VueQuasarChangelog {
version: version.to_string(),
date: Local::now().format("%Y-%m-%d").to_string(),
changes: changes.clone(),
};
let rendered_log = changelog.render().expect("Failed to render changelog");
insert_changelog(&output_selection.output_filepath, &rendered_log);
results.push(format!(
" - Generated {} changelog at {}",
output_selection.template_option, output_selection.output_filepath
));
}
});
Ok(results)
}
pub fn insert_changelog(output_filepath: &str, changelog: &str) {
std::fs::write(output_filepath, changelog).expect("Failed to write to file");
}