1
1
mirror of https://github.com/orhun/git-cliff.git synced 2024-09-21 04:07:49 +03:00

refactor(bin): add changelog module

This commit is contained in:
orhun 2021-06-01 22:47:30 +03:00
parent 6b755cd82f
commit 345c410a62
No known key found for this signature in database
GPG Key ID: B928720AEC532117
3 changed files with 97 additions and 61 deletions

View File

@ -39,10 +39,10 @@ impl Template {
}
/// Renders the template.
pub fn render(&self, release: Release) -> Result<String> {
pub fn render(&self, release: &Release) -> Result<String> {
Ok(self
.tera
.render("template", &TeraContext::from_serialize(&release)?)?)
.render("template", &TeraContext::from_serialize(release)?)?)
}
}

View File

@ -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<Self> {
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::<Vec<Commit>>();
});
}
/// 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<W: Write>(&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(())
}
}

View File

@ -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::<Vec<Commit>>();
});
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())
}