mirror of
https://github.com/orhun/git-cliff.git
synced 2024-10-26 07:49:41 +03:00
feat(changelog)!: support templating in the footer (#369)
* feat(changelog)!: support templating in the footer (#95) * test(fixture): run test-footer-template fixture
This commit is contained in:
parent
1e571c2f32
commit
0945fa806c
@ -19,9 +19,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
@ -19,9 +19,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
@ -22,9 +22,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
@ -19,12 +19,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespaces from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# regex for preprocessing the commit messages
|
||||
|
@ -22,12 +22,12 @@ body = """
|
||||
{% endfor %}\
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespaces from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# regex for parsing and grouping commits
|
||||
|
6
.github/fixtures/test-date-order/cliff.toml
vendored
6
.github/fixtures/test-date-order/cliff.toml
vendored
@ -19,9 +19,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
35
.github/fixtures/test-footer-template/cliff.toml
vendored
Normal file
35
.github/fixtures/test-footer-template/cliff.toml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
[changelog]
|
||||
# changelog header
|
||||
header = """
|
||||
# Changelog\n
|
||||
All notable changes to this project will be documented in this file.\n
|
||||
"""
|
||||
# template for the changelog body
|
||||
# https://keats.github.io/tera/docs/#introduction
|
||||
body = """
|
||||
{% if version %}\
|
||||
## [{{ version | trim_start_matches(pat="v") }}]
|
||||
{% else %}\
|
||||
## [unreleased]
|
||||
{% endif %}\
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | upper_first }}
|
||||
{% for commit in commits %}
|
||||
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
{% for release in releases %}\
|
||||
{% if release.version %}\
|
||||
{% if release.previous.version %}\
|
||||
<!--{{ release.previous.version }}..{{ release.version }}-->
|
||||
{% endif %}\
|
||||
{% else %}\
|
||||
<!--{{ release.previous.version }}..HEAD-->
|
||||
{% endif %}\
|
||||
{% endfor %}\
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
16
.github/fixtures/test-footer-template/commit.sh
vendored
Executable file
16
.github/fixtures/test-footer-template/commit.sh
vendored
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 1"
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 2"
|
||||
git tag v0.1.0
|
||||
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "fix: fix feature 1"
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "fix: fix feature 2"
|
||||
git tag v0.2.0
|
||||
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:47" git commit --allow-empty -m "feat: add footer"
|
||||
git tag v3.0.0
|
||||
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:47" git commit --allow-empty -m "test: footer"
|
||||
GIT_COMMITTER_DATE="2021-01-23 01:23:47" git commit --allow-empty -m "perf: footer"
|
38
.github/fixtures/test-footer-template/expected.md
vendored
Normal file
38
.github/fixtures/test-footer-template/expected.md
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [unreleased]
|
||||
|
||||
### Perf
|
||||
|
||||
- Footer
|
||||
|
||||
### Test
|
||||
|
||||
- Footer
|
||||
|
||||
## [3.0.0]
|
||||
|
||||
### Feat
|
||||
|
||||
- Add footer
|
||||
|
||||
## [0.2.0]
|
||||
|
||||
### Fix
|
||||
|
||||
- Fix feature 1
|
||||
- Fix feature 2
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
### Feat
|
||||
|
||||
- Add feature 1
|
||||
- Add feature 2
|
||||
|
||||
<!--v3.0.0..HEAD-->
|
||||
<!--v0.2.0..v3.0.0-->
|
||||
<!--v0.1.0..v0.2.0-->
|
||||
|
6
.github/fixtures/test-ignore-tags/cliff.toml
vendored
6
.github/fixtures/test-ignore-tags/cliff.toml
vendored
@ -19,12 +19,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# regex for skipping tags
|
||||
|
@ -38,12 +38,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
|
@ -19,9 +19,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespaces from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
@ -19,12 +19,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
limit_commits = 2
|
||||
|
@ -22,12 +22,12 @@ body = """
|
||||
{% endfor %}\
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespaces from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# regex for parsing and grouping commits
|
||||
|
@ -19,12 +19,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespaces from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# process each line of a commit as an individual commit
|
||||
|
@ -19,9 +19,9 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
6
.github/fixtures/test-topo-order/cliff.toml
vendored
6
.github/fixtures/test-topo-order/cliff.toml
vendored
@ -19,12 +19,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
topo_order = true
|
||||
|
1
.github/workflows/test-fixtures.yml
vendored
1
.github/workflows/test-fixtures.yml
vendored
@ -36,6 +36,7 @@ jobs:
|
||||
command: --bump
|
||||
- fixtures-name: test-bumped-version
|
||||
command: --bumped-version
|
||||
- fixtures-name: test-footer-template
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
@ -44,12 +44,12 @@ body = """
|
||||
{% endfor -%}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||
|
@ -26,12 +26,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing s
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||
|
@ -38,12 +38,12 @@ body = """
|
||||
{% endfor -%}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
{ pattern = '\$REPO', replace = "https://github.com/cocogitto/cocogitto" }, # replace repository URL
|
||||
|
@ -31,12 +31,12 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
|
@ -25,12 +25,26 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
{% for release in releases %}\
|
||||
{% if release.version %}\
|
||||
{% if release.previous.version %}\
|
||||
[{{ release.version | trim_start_matches(pat="v") }}]: <REPO>/compare/{{ release.previous.version }}..{{ release.version }}
|
||||
{% endif %}\
|
||||
{% else %}\
|
||||
[unreleased]: <REPO>/compare/{{ release.previous.version }}..HEAD
|
||||
{% endif %}\
|
||||
{% endfor %}
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
# replace repository URL
|
||||
{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" },
|
||||
]
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
@ -41,14 +55,14 @@ filter_unconventional = true
|
||||
split_commits = false
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
{ message = "^.*: add", group = "Added" },
|
||||
{ message = "^.*: support", group = "Added" },
|
||||
{ message = "^.*: remove", group = "Removed" },
|
||||
{ message = "^.*: delete", group = "Removed" },
|
||||
{ message = "^test", group = "Fixed" },
|
||||
{ message = "^fix", group = "Fixed" },
|
||||
{ message = "^.*: fix", group = "Fixed" },
|
||||
{ message = "^.*", group = "Changed" },
|
||||
{ message = "^.*: add", group = "Added" },
|
||||
{ message = "^.*: support", group = "Added" },
|
||||
{ message = "^.*: remove", group = "Removed" },
|
||||
{ message = "^.*: delete", group = "Removed" },
|
||||
{ message = "^test", group = "Fixed" },
|
||||
{ message = "^fix", group = "Fixed" },
|
||||
{ message = "^.*: fix", group = "Fixed" },
|
||||
{ message = "^.*", group = "Changed" },
|
||||
]
|
||||
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||
protect_breaking_commits = false
|
||||
|
@ -25,12 +25,12 @@ body = """
|
||||
{% endfor %}\
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
|
@ -38,12 +38,13 @@ body = """
|
||||
{% raw %}\n{% endraw %}\
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
|
@ -22,12 +22,13 @@ body = """
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the templates
|
||||
trim = true
|
||||
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
|
@ -11,30 +11,31 @@ use std::io::Write;
|
||||
/// Changelog generator.
|
||||
#[derive(Debug)]
|
||||
pub struct Changelog<'a> {
|
||||
releases: Vec<Release<'a>>,
|
||||
template: Template,
|
||||
config: &'a Config,
|
||||
releases: Vec<Release<'a>>,
|
||||
body_template: Template,
|
||||
footer_template: Option<Template>,
|
||||
config: &'a Config,
|
||||
}
|
||||
|
||||
impl<'a> Changelog<'a> {
|
||||
/// Constructs a new instance.
|
||||
pub fn new(releases: Vec<Release<'a>>, config: &'a Config) -> Result<Self> {
|
||||
let mut template = config
|
||||
.changelog
|
||||
.body
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
if config.changelog.trim.unwrap_or(true) {
|
||||
template = template
|
||||
.lines()
|
||||
.map(|v| v.trim())
|
||||
.collect::<Vec<&str>>()
|
||||
.join("\n")
|
||||
}
|
||||
let trim = config.changelog.trim.unwrap_or(true);
|
||||
let mut changelog = Self {
|
||||
releases,
|
||||
template: Template::new(template)?,
|
||||
body_template: Template::new(
|
||||
config
|
||||
.changelog
|
||||
.body
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
trim,
|
||||
)?,
|
||||
footer_template: match &config.changelog.footer {
|
||||
Some(footer) => Some(Template::new(footer.to_string(), trim)?),
|
||||
None => None,
|
||||
},
|
||||
config,
|
||||
};
|
||||
changelog.process_commits();
|
||||
@ -141,19 +142,30 @@ impl<'a> Changelog<'a> {
|
||||
if let Some(header) = &self.config.changelog.header {
|
||||
write!(out, "{header}")?;
|
||||
}
|
||||
let postprocessors = self
|
||||
.config
|
||||
.changelog
|
||||
.postprocessors
|
||||
.clone()
|
||||
.unwrap_or_default();
|
||||
for release in &self.releases {
|
||||
let mut rendered = self.template.render(release)?;
|
||||
if let Some(postprocessors) =
|
||||
self.config.changelog.postprocessors.as_ref()
|
||||
{
|
||||
for postprocessor in postprocessors {
|
||||
postprocessor.replace(&mut rendered, vec![])?;
|
||||
}
|
||||
}
|
||||
write!(out, "{}", rendered)?;
|
||||
write!(
|
||||
out,
|
||||
"{}",
|
||||
self.body_template.render(release, &postprocessors)?
|
||||
)?;
|
||||
}
|
||||
if let Some(footer) = &self.config.changelog.footer {
|
||||
write!(out, "{footer}")?;
|
||||
if let Some(footer_template) = &self.footer_template {
|
||||
writeln!(
|
||||
out,
|
||||
"{}",
|
||||
footer_template.render(
|
||||
&Releases {
|
||||
releases: &self.releases,
|
||||
},
|
||||
&postprocessors,
|
||||
)?
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -175,7 +187,10 @@ impl<'a> Changelog<'a> {
|
||||
|
||||
/// Prints the changelog context to the given output.
|
||||
pub fn write_context<W: Write>(&self, out: &mut W) -> Result<()> {
|
||||
let output = Releases(&self.releases).as_json()?;
|
||||
let output = Releases {
|
||||
releases: &self.releases,
|
||||
}
|
||||
.as_json()?;
|
||||
writeln!(out, "{output}")?;
|
||||
Ok(())
|
||||
}
|
||||
@ -209,7 +224,9 @@ mod test {
|
||||
- {{ commit.message }}{% endfor %}
|
||||
{% endfor %}{% endfor %}"#,
|
||||
)),
|
||||
footer: Some(String::from("------------")),
|
||||
footer: Some(String::from(
|
||||
r#"-- total releases: {{ releases | length }} --"#,
|
||||
)),
|
||||
trim: Some(true),
|
||||
postprocessors: Some(vec![TextProcessor {
|
||||
pattern: Regex::new("boring")
|
||||
@ -468,7 +485,8 @@ mod test {
|
||||
|
||||
#### ui
|
||||
- make good stuff
|
||||
------------"#
|
||||
-- total releases: 2 --
|
||||
"#
|
||||
)
|
||||
.replace(" ", ""),
|
||||
str::from_utf8(&out).unwrap_or_default()
|
||||
@ -583,7 +601,8 @@ chore(deps): fix broken deps
|
||||
|
||||
#### ui
|
||||
- make good stuff
|
||||
------------"#
|
||||
-- total releases: 2 --
|
||||
"#
|
||||
)
|
||||
.replace(" ", ""),
|
||||
str::from_utf8(&out).unwrap_or_default()
|
||||
|
@ -48,12 +48,16 @@ impl<'a> Release<'a> {
|
||||
}
|
||||
|
||||
/// Representation of a list of releases.
|
||||
pub struct Releases<'a>(pub &'a Vec<Release<'a>>);
|
||||
#[derive(Serialize)]
|
||||
pub struct Releases<'a> {
|
||||
/// Releases.
|
||||
pub releases: &'a Vec<Release<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Releases<'a> {
|
||||
/// Returns the list of releases as JSON.
|
||||
pub fn as_json(&self) -> Result<String> {
|
||||
Ok(serde_json::to_string(self.0)?)
|
||||
Ok(serde_json::to_string(self.releases)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
use crate::error::{
|
||||
Error,
|
||||
Result,
|
||||
use crate::{
|
||||
config::TextProcessor,
|
||||
error::{
|
||||
Error,
|
||||
Result,
|
||||
},
|
||||
};
|
||||
use crate::release::Release;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error as ErrorImpl;
|
||||
use tera::{
|
||||
@ -20,7 +23,14 @@ pub struct Template {
|
||||
|
||||
impl Template {
|
||||
/// Constructs a new instance.
|
||||
pub fn new(template: String) -> Result<Self> {
|
||||
pub fn new(mut template: String, trim: bool) -> Result<Self> {
|
||||
if trim {
|
||||
template = template
|
||||
.lines()
|
||||
.map(|v| v.trim())
|
||||
.collect::<Vec<&str>>()
|
||||
.join("\n")
|
||||
}
|
||||
let mut tera = Tera::default();
|
||||
if let Err(e) = tera.add_raw_template("template", &template) {
|
||||
return if let Some(error_source) = e.source() {
|
||||
@ -49,10 +59,19 @@ impl Template {
|
||||
}
|
||||
|
||||
/// Renders the template.
|
||||
pub fn render(&self, release: &Release) -> Result<String> {
|
||||
let context = TeraContext::from_serialize(release)?;
|
||||
pub fn render<T: Serialize>(
|
||||
&self,
|
||||
context: &T,
|
||||
postprocessors: &[TextProcessor],
|
||||
) -> Result<String> {
|
||||
let context = TeraContext::from_serialize(context)?;
|
||||
match self.tera.render("template", &context) {
|
||||
Ok(v) => Ok(v),
|
||||
Ok(mut v) => {
|
||||
for postprocessor in postprocessors {
|
||||
postprocessor.replace(&mut v, vec![])?;
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
Err(e) => {
|
||||
return if let Some(error_source) = e.source() {
|
||||
Err(Error::TemplateRenderError(error_source.to_string()))
|
||||
@ -68,19 +87,21 @@ impl Template {
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::commit::Commit;
|
||||
use crate::release::Release;
|
||||
use regex::Regex;
|
||||
|
||||
#[test]
|
||||
fn render_template() -> Result<()> {
|
||||
let template = r#"
|
||||
## {{ version }}
|
||||
## {{ version }} - <DATE>
|
||||
{% for commit in commits %}
|
||||
### {{ commit.group }}
|
||||
- {{ commit.message | upper_first }}
|
||||
{% endfor %}"#;
|
||||
let template = Template::new(template.to_string())?;
|
||||
let template = Template::new(template.to_string(), false)?;
|
||||
assert_eq!(
|
||||
r#"
|
||||
## 1.0
|
||||
## 1.0 - 2023
|
||||
|
||||
### feat
|
||||
- Add xyz
|
||||
@ -88,25 +109,33 @@ mod test {
|
||||
### fix
|
||||
- Fix abc
|
||||
"#,
|
||||
template.render(&Release {
|
||||
version: Some(String::from("1.0")),
|
||||
commits: vec![
|
||||
Commit::new(
|
||||
String::from("123123"),
|
||||
String::from("feat(xyz): add xyz"),
|
||||
),
|
||||
Commit::new(
|
||||
String::from("124124"),
|
||||
String::from("fix(abc): fix abc"),
|
||||
)
|
||||
]
|
||||
.into_iter()
|
||||
.filter_map(|c| c.into_conventional().ok())
|
||||
.collect(),
|
||||
commit_id: None,
|
||||
timestamp: 0,
|
||||
previous: None,
|
||||
})?
|
||||
template.render(
|
||||
&Release {
|
||||
version: Some(String::from("1.0")),
|
||||
commits: vec![
|
||||
Commit::new(
|
||||
String::from("123123"),
|
||||
String::from("feat(xyz): add xyz"),
|
||||
),
|
||||
Commit::new(
|
||||
String::from("124124"),
|
||||
String::from("fix(abc): fix abc"),
|
||||
)
|
||||
]
|
||||
.into_iter()
|
||||
.filter_map(|c| c.into_conventional().ok())
|
||||
.collect(),
|
||||
commit_id: None,
|
||||
timestamp: 0,
|
||||
previous: None,
|
||||
},
|
||||
&[TextProcessor {
|
||||
pattern: Regex::new("<DATE>")
|
||||
.expect("failed to compile regex"),
|
||||
replace: Some(String::from("2023")),
|
||||
replace_command: None,
|
||||
}]
|
||||
)?
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ fn generate_changelog() -> Result<()> {
|
||||
header: Some(String::from("this is a changelog")),
|
||||
body: Some(String::from(
|
||||
r#"
|
||||
## Release {{ version }}
|
||||
## Release {{ version }} - <DATE>
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group }}
|
||||
{% for commit in commits %}
|
||||
@ -199,18 +199,27 @@ fn generate_changelog() -> Result<()> {
|
||||
];
|
||||
|
||||
let out = &mut String::new();
|
||||
let template = Template::new(changelog_config.body.unwrap())?;
|
||||
let template = Template::new(changelog_config.body.unwrap(), false)?;
|
||||
|
||||
writeln!(out, "{}", changelog_config.header.unwrap()).unwrap();
|
||||
for release in releases {
|
||||
write!(out, "{}", template.render(&release)?).unwrap();
|
||||
write!(
|
||||
out,
|
||||
"{}",
|
||||
template.render(&release, &[TextProcessor {
|
||||
pattern: Regex::new("<DATE>").unwrap(),
|
||||
replace: Some(String::from("2023")),
|
||||
replace_command: None,
|
||||
}])?
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(out, "{}", changelog_config.footer.unwrap()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
r#"this is a changelog
|
||||
|
||||
## Release v2.0.0
|
||||
## Release v2.0.0 - 2023
|
||||
|
||||
### docs
|
||||
- *(cool)* testing author filtering
|
||||
@ -229,7 +238,7 @@ fn generate_changelog() -> Result<()> {
|
||||
### test
|
||||
- *(tests)* test some stuff
|
||||
|
||||
## Release v1.0.0
|
||||
## Release v1.0.0 - 2023
|
||||
|
||||
### chore
|
||||
- do nothing
|
||||
|
@ -47,16 +47,22 @@ Body template that represents a single release in the changelog.
|
||||
|
||||
See [templating](/docs/category/templating) for more detail.
|
||||
|
||||
### footer
|
||||
|
||||
Footer template that will be rendered and added to the end of the changelog.
|
||||
|
||||
The template context is the same as [`body`](#body) and contains all the releases instead of a single release.
|
||||
|
||||
For example, to get the list of releases, use the `{{ releases }}` variable in the template. To get information about a single release, iterate over this array and access the fields similar to [`body`](#body).
|
||||
|
||||
See [Keep a Changelog configuration](/docs/templating/examples#keep-a-changelog) for seeing the example of adding links to the end of the changelog.
|
||||
|
||||
### trim
|
||||
|
||||
If set to `true`, leading and trailing whitespace are removed from the [`body`](#body).
|
||||
|
||||
It is useful for adding indentation to the template for readability, as shown [in the example](#changelog).
|
||||
|
||||
### footer
|
||||
|
||||
Footer text that will be added to the end of the changelog.
|
||||
|
||||
### postprocessors
|
||||
|
||||
An array of commit postprocessors for manipulating the changelog before outputting.
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Context
|
||||
|
||||
Context is the model that holds the required data for a template rendering. The [JSON](https://en.wikipedia.org/wiki/JSON) format is used in the following examples for the representation of a context.
|
||||
|
@ -662,6 +662,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Rename help argument due to conflict
|
||||
|
||||
[unreleased]: https://github.com/orhun/git-cliff/compare/v1.0.1..HEAD
|
||||
[1.0.1]: https://github.com/orhun/git-cliff/compare/v1.0.0..v1.0.1
|
||||
|
||||
<!-- generated by git-cliff -->
|
||||
```
|
||||
|
||||
@ -709,6 +712,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Rename help argument due to conflict
|
||||
|
||||
[unreleased]: https://github.com/orhun/git-cliff/compare/v1.0.1..HEAD
|
||||
[1.0.1]: https://github.com/orhun/git-cliff/compare/v1.0.0..v1.0.1
|
||||
|
||||
<!-- generated by git-cliff -->
|
||||
|
||||
</details>
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "git-cliff-website",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
|
Loading…
Reference in New Issue
Block a user