From 345c410a6239df1c1c7e99864c7e5f220722e5e4 Mon Sep 17 00:00:00 2001 From: orhun Date: Tue, 1 Jun 2021 22:47:30 +0300 Subject: [PATCH] refactor(bin): add changelog module --- git-cliff-core/src/template.rs | 4 +- git-cliff/src/changelog.rs | 91 ++++++++++++++++++++++++++++++++++ git-cliff/src/main.rs | 63 ++--------------------- 3 files changed, 97 insertions(+), 61 deletions(-) create mode 100644 git-cliff/src/changelog.rs diff --git a/git-cliff-core/src/template.rs b/git-cliff-core/src/template.rs index 4888193..3a58234 100644 --- a/git-cliff-core/src/template.rs +++ b/git-cliff-core/src/template.rs @@ -39,10 +39,10 @@ impl Template { } /// Renders the template. - pub fn render(&self, release: Release) -> Result { + pub fn render(&self, release: &Release) -> Result { Ok(self .tera - .render("template", &TeraContext::from_serialize(&release)?)?) + .render("template", &TeraContext::from_serialize(release)?)?) } } diff --git a/git-cliff/src/changelog.rs b/git-cliff/src/changelog.rs new file mode 100644 index 00000000..d9eec71 --- /dev/null +++ b/git-cliff/src/changelog.rs @@ -0,0 +1,91 @@ +use git_cliff_core::commit::Commit; +use git_cliff_core::config::ChangelogConfig as Config; +use git_cliff_core::error::Result; +use git_cliff_core::release::ReleaseRoot; +use git_cliff_core::template::Template; +use std::io::Write; + +/// Changelog generator. +#[derive(Debug)] +pub struct Changelog<'a> { + release_root: ReleaseRoot<'a>, + template: Template, + config: &'a Config, +} + +impl<'a> Changelog<'a> { + /// Constructs a new instance. + pub fn new(release_root: ReleaseRoot<'a>, config: &'a Config) -> Result { + let mut changelog = Self { + release_root, + template: Template::new(config.body.to_string())?, + config, + }; + changelog.process_commits(); + changelog.process_releases(); + Ok(changelog) + } + + /// Processes the commits and omits the ones that doesn't match the + /// criteria set by configuration file. + fn process_commits(&mut self) { + let config = &self.config; + self.release_root.releases.iter_mut().for_each(|release| { + release.commits = release + .commits + .iter() + .filter_map(|commit| { + match commit.process(&config.commit_parsers, config.filter_group) + { + Ok(commit) => Some(commit), + Err(e) => { + debug!("Cannot process commit: {} ({})", commit.id, e); + None + } + } + }) + .collect::>(); + }); + } + + /// Processes the releases and filters them out based on the configuration. + fn process_releases(&mut self) { + self.release_root.releases = self + .release_root + .releases + .clone() + .into_iter() + .rev() + .filter(|release| { + if release.commits.is_empty() { + debug!( + "Release {} doesn't have any commits", + release + .version + .as_ref() + .cloned() + .unwrap_or_else(|| String::from("[?]")) + ); + false + } else if let Some(version) = &release.version { + !self.config.skip_tags_regex.is_match(version) + } else { + true + } + }) + .collect(); + } + + pub fn generate(&self, out: &mut W) -> Result<()> { + if !self.config.header.is_empty() { + writeln!(out, "{}", self.config.header)?; + } + for release in &self.release_root.releases { + write!(out, "{}", self.template.render(release)?)?; + } + if !self.config.footer.is_empty() { + writeln!(out, "{}", self.config.footer)?; + } + Ok(()) + } +} diff --git a/git-cliff/src/main.rs b/git-cliff/src/main.rs index 0ce336c..3b043e6 100644 --- a/git-cliff/src/main.rs +++ b/git-cliff/src/main.rs @@ -1,6 +1,8 @@ mod args; +mod changelog; use args::Opt; +use changelog::Changelog; use git_cliff_core::commit::Commit; use git_cliff_core::config::Config; use git_cliff_core::error::Result; @@ -9,12 +11,8 @@ use git_cliff_core::release::{ ReleaseRoot, }; use git_cliff_core::repo::Repository; -use git_cliff_core::template::Template; use std::env; -use std::io::{ - self, - Write, -}; +use std::io; use structopt::StructOpt; #[macro_use] extern crate log; @@ -64,58 +62,5 @@ fn main() -> Result<()> { } } - release_root.releases.iter_mut().for_each(|release| { - release.commits = release - .commits - .iter() - .filter_map(|commit| { - match commit.process( - &config.changelog.commit_parsers, - config.changelog.filter_group, - ) { - Ok(commit) => Some(commit), - Err(e) => { - debug!("Cannot process commit: {} ({})", commit.id, e); - None - } - } - }) - .collect::>(); - }); - release_root.releases = release_root - .releases - .into_iter() - .rev() - .filter(|release| { - if release.commits.is_empty() { - debug!( - "Release {} doesn't have any commits", - release - .version - .as_ref() - .cloned() - .unwrap_or_else(|| String::from("[?]")) - ); - false - } else if let Some(version) = &release.version { - !config.changelog.skip_tags_regex.is_match(version) - } else { - true - } - }) - .collect(); - - let stdout = &mut io::stdout(); - let template = Template::new(config.changelog.body)?; - if !config.changelog.header.is_empty() { - writeln!(stdout, "{}", config.changelog.header)?; - } - for release in release_root.releases { - write!(stdout, "{}", template.render(release)?)?; - } - if !config.changelog.footer.is_empty() { - writeln!(stdout, "{}", config.changelog.footer)?; - } - - Ok(()) + Changelog::new(release_root, &config.changelog)?.generate(&mut io::stdout()) }