Skip to content

Commit

Permalink
feat: add postprocessors to changelog
Browse files Browse the repository at this point in the history
This will enable things like replacing usernames with github usernames #132
  • Loading branch information
PSeitz committed Apr 20, 2023
1 parent 2d72125 commit e5fd555
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 27 deletions.
47 changes: 38 additions & 9 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::command;
use crate::commit::Commit;
use crate::config::Config;
use crate::error::Result;
Expand Down Expand Up @@ -142,7 +143,29 @@ impl<'a> Changelog<'a> {
write!(out, "{header}")?;
}
for release in &self.releases {
write!(out, "{}", self.template.render(release)?)?;
let mut rendered = self.template.render(release)?;
if let Some(preprocessors) =
self.config.changelog.postprocessors.as_ref()
{
for preprocessor in preprocessors {
if let Some(text) = &preprocessor.replace {
rendered = preprocessor
.pattern
.replace_all(&rendered, text)
.to_string();
} else if let Some(command) = &preprocessor.replace_command {
if preprocessor.pattern.is_match(&rendered) {
rendered = command::run(
command,
Some(rendered.to_string()),
vec![],
)?;
}
}
}
}

write!(out, "{}", rendered)?;
}
if let Some(footer) = &self.config.changelog.footer {
write!(out, "{footer}")?;
Expand Down Expand Up @@ -179,8 +202,8 @@ mod test {
use crate::config::{
ChangelogConfig,
CommitParser,
CommitPreprocessor,
GitConfig,
TextProcessor,
};
use pretty_assertions::assert_eq;
use regex::Regex;
Expand All @@ -189,8 +212,8 @@ mod test {
fn get_test_data() -> (Config, Vec<Release<'static>>) {
let config = Config {
changelog: ChangelogConfig {
header: Some(String::from("# Changelog")),
body: Some(String::from(
header: Some(String::from("# Changelog")),
body: Some(String::from(
r#"{% if version %}
## Release [{{ version }}] - {{ timestamp | date(format="%Y-%m-%d") }}
({{ commit_id }}){% else %}
Expand All @@ -201,14 +224,20 @@ mod test {
- {{ commit.message }}{% endfor %}
{% endfor %}{% endfor %}"#,
)),
footer: Some(String::from("------------")),
trim: Some(true),
footer: Some(String::from("------------")),
trim: Some(true),
postprocessors: Some(vec![TextProcessor {
pattern: Regex::new("boring")
.expect("failed to compile regex"),
replace: Some(String::from("exciting")),
replace_command: None,
}]),
},
git: GitConfig {
conventional_commits: Some(true),
filter_unconventional: Some(false),
split_commits: Some(false),
commit_preprocessors: Some(vec![CommitPreprocessor {
commit_preprocessors: Some(vec![TextProcessor {
pattern: Regex::new("<preprocess>")
.expect("failed to compile regex"),
replace: Some(String::from(
Expand Down Expand Up @@ -392,7 +421,7 @@ mod test {
- document zyx
#### ui
- do boring stuff
- do exciting stuff
## Release [v1.0.0] - 1971-08-02
(0bc123)
Expand Down Expand Up @@ -494,7 +523,7 @@ chore(deps): fix broken deps
- fix broken deps
#### ui
- do boring stuff
- do exciting stuff
### feat
#### app
Expand Down
7 changes: 2 additions & 5 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::command;
use crate::config::{
CommitParser,
CommitPreprocessor,
GitConfig,
LinkParser,
TextProcessor,
};
use crate::error::{
Error as AppError,
Expand Down Expand Up @@ -212,10 +212,7 @@ impl Commit<'_> {
/// Modifies the commit [`message`] using regex or custom OS command.
///
/// [`message`]: Commit::message
pub fn preprocess(
mut self,
preprocessors: &[CommitPreprocessor],
) -> Result<Self> {
pub fn preprocess(mut self, preprocessors: &[TextProcessor]) -> Result<Self> {
preprocessors.iter().try_for_each(|preprocessor| {
if let Some(text) = &preprocessor.replace {
self.message = preprocessor
Expand Down
16 changes: 9 additions & 7 deletions git-cliff-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ pub struct Config {
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
pub struct ChangelogConfig {
/// Changelog header.
pub header: Option<String>,
pub header: Option<String>,
/// Changelog body, template.
pub body: Option<String>,
pub body: Option<String>,
/// Changelog footer.
pub footer: Option<String>,
pub footer: Option<String>,
/// Trim the template.
pub trim: Option<bool>,
pub trim: Option<bool>,
/// Changelog postrocessors.
pub postprocessors: Option<Vec<TextProcessor>>,
}

/// Git configuration
Expand All @@ -50,7 +52,7 @@ pub struct GitConfig {
pub split_commits: Option<bool>,

/// Git commit preprocessors.
pub commit_preprocessors: Option<Vec<CommitPreprocessor>>,
pub commit_preprocessors: Option<Vec<TextProcessor>>,
/// Git commit parsers.
pub commit_parsers: Option<Vec<CommitParser>>,
/// Whether to protect all breaking changes from being skipped by a commit
Expand Down Expand Up @@ -95,9 +97,9 @@ pub struct CommitParser {
pub skip: Option<bool>,
}

/// Preprocessor for modifying commit messages.
/// TextProcessor, e.g. for modifying commit messages.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CommitPreprocessor {
pub struct TextProcessor {
/// Regex for matching a text to replace.
#[serde(with = "serde_regex")]
pub pattern: Regex,
Expand Down
13 changes: 7 additions & 6 deletions git-cliff-core/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use git_cliff_core::commit::Commit;
use git_cliff_core::config::{
ChangelogConfig,
CommitParser,
CommitPreprocessor,
GitConfig,
LinkParser,
TextProcessor,
};
use git_cliff_core::error::Result;
use git_cliff_core::release::*;
Expand All @@ -16,8 +16,8 @@ use std::fmt::Write;
#[test]
fn generate_changelog() -> Result<()> {
let changelog_config = ChangelogConfig {
header: Some(String::from("this is a changelog")),
body: Some(String::from(
header: Some(String::from("this is a changelog")),
body: Some(String::from(
r#"
## Release {{ version }}
{% for group, commits in commits | group_by(attribute="group") %}
Expand All @@ -34,14 +34,15 @@ fn generate_changelog() -> Result<()> {
{% endfor -%}
{% endfor %}"#,
)),
footer: Some(String::from("eoc - end of changelog")),
trim: None,
footer: Some(String::from("eoc - end of changelog")),
trim: None,
postprocessors: None,
};
let git_config = GitConfig {
conventional_commits: Some(true),
filter_unconventional: Some(true),
split_commits: Some(false),
commit_preprocessors: Some(vec![CommitPreprocessor {
commit_preprocessors: Some(vec![TextProcessor {
pattern: Regex::new(r#"\(fixes (#[1-9]+)\)"#).unwrap(),
replace: Some(String::from("[closes Issue${1}]")),
replace_command: None,
Expand Down
7 changes: 7 additions & 0 deletions website/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ body = """
"""
trim = true
footer = "<!-- generated by git-cliff -->"
postprocessors = [{ pattern = "foo", replace = "bar"}]
```

<!-- {% endraw %} -->
Expand All @@ -56,6 +57,12 @@ It is useful for adding indentation to the template for readability, as shown [i

Footer text that will be added to the end of the changelog.

### postprocessors

An array of commit preprocessors for manipulating the changelog before outputting.
Can e.g. be used for replacing commit author with github user names.
See [commit_preprocessors](#commit_preprocessors) for more detail and examples, it uses the same syntax.

## `git`

This section contains the parsing and git related configuration options.
Expand Down

0 comments on commit e5fd555

Please sign in to comment.