Skip to content

Commit

Permalink
feat(git): support preprocessing commit messages using regex (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
orhun committed Apr 6, 2022
1 parent a8efffc commit 64317f2
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .github/fixtures/test-commit-preprocessors/cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[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://tera.netlify.app/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% 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
"""
# remove the leading and trailing whitespaces from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""

[git]
# regex for preprocessing the commit messages
commit_preprocessors = [
{ pattern = '\(#([0-9]+)\)', replace = "([issue#${1}](https://github.com/orhun/git-cliff/issues/${1}))"},
{ pattern = " +", replace = " "}
]
8 changes: 8 additions & 0 deletions .github/fixtures/test-commit-preprocessors/commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e

GIT_COMMITTER_DATE="2022-04-06 01:25:08" git commit --allow-empty -m "Initial commit"
GIT_COMMITTER_DATE="2022-04-06 01:25:09" git commit --allow-empty -m "feat: add feature 1"
GIT_COMMITTER_DATE="2022-04-06 01:25:10" git commit --allow-empty -m "fix: fix feature 1 (#1)"
GIT_COMMITTER_DATE="2022-04-06 01:25:11" git commit --allow-empty -m "refactor: move classes"
git tag v0.1.0
19 changes: 19 additions & 0 deletions .github/fixtures/test-commit-preprocessors/expected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to this project will be documented in this file.

## [0.1.0] - 2022-04-05

### Feat

- Add feature 1

### Fix

- Fix feature 1 ([issue#1](https://github.com/orhun/git-cliff/issues/1))

### Refactor

- Move classes

<!-- generated by git-cliff -->
1 change: 1 addition & 0 deletions .github/workflows/test-fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
command: --latest --date-order
- fixtures-name: test-latest-with-one-tag
command: --latest
- fixtures-name: test-commit-preprocessors
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
- [git](#git)
- [conventional_commits](#conventional_commits)
- [filter_unconventional](#filter_unconventional)
- [commit_preprocessors](#commit_preprocessors)
- [commit_parsers](#commit_parsers)
- [filter_commits](#filter_commits)
- [tag_pattern](#tag_pattern)
Expand Down Expand Up @@ -496,6 +497,23 @@ conventional_commits = false
filter_unconventional = false
```

#### commit_preprocessors

An array of commit preprocessors for manipulating the commit messages before parsing/grouping them. These regex-based preprocessors can be used for removing or selecting certain parts of the commit message/body to be used in the following processes.

Examples:

- `{ pattern = "foo", replace = "bar"}`
- Replace text
- `{ pattern = 'Merged PR #[0-9]: (.*)', replace = "$1"}`
- Remove prefix
- `{ pattern = " +", replace = " "}`
- Replace multiple spaces with a single space
- `{ pattern = "\\(#([0-9]+)\\)", replace = "([#${1}](https://github.com/orhun/git-cliff/issues/${1}))"}`
- Replace the issue number with the link
- `{ pattern = "https://github.com/.*/issues/([0-9]+)", replace = "[Issue #${1}]"}`
- Replace the issue link with the number

#### commit_parsers

An array of commit parsers for determining the commit groups by using regex.
Expand Down
4 changes: 4 additions & 0 deletions config/cliff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ footer = """
conventional_commits = true
# filter out the commits that are not conventional
filter_unconventional = true
# regex for preprocessing the commit messages
commit_preprocessors = [
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/orhun/git-cliff/issues/${2}))"},
]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "Features"},
Expand Down
19 changes: 19 additions & 0 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::config::{
CommitParser,
CommitPreprocessor,
GitConfig,
LinkParser,
};
Expand Down Expand Up @@ -73,6 +74,9 @@ impl Commit<'_> {
/// * extacts links and generates URLs
pub fn process(&self, config: &GitConfig) -> Result<Self> {
let mut commit = self.clone();
if let Some(preprocessors) = &config.commit_preprocessors {
commit = commit.preprocess(preprocessors);
}
if config.conventional_commits.unwrap_or(true) {
if config.filter_unconventional.unwrap_or(true) {
commit = commit.into_conventional()?;
Expand Down Expand Up @@ -103,6 +107,21 @@ impl Commit<'_> {
}
}

/// Preprocesses the commit using [`CommitPreprocessor`]s.
///
/// Modifies the commit [`message`] using regex.
///
/// [`message`]: Commit::message
pub fn preprocess(mut self, preprocessors: &[CommitPreprocessor]) -> Self {
preprocessors.iter().for_each(|preprocessor| {
self.message = preprocessor
.pattern
.replace_all(&self.message, &preprocessor.replace)
.to_string();
});
self
}

/// Parses the commit using [`CommitParser`]s.
///
/// Sets the [`group`] and [`scope`] of the commit.
Expand Down
12 changes: 12 additions & 0 deletions git-cliff-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub struct GitConfig {
pub conventional_commits: Option<bool>,
/// Whether to filter out unconventional commits.
pub filter_unconventional: Option<bool>,
/// Git commit preprocessors.
pub commit_preprocessors: Option<Vec<CommitPreprocessor>>,
/// Git commit parsers.
pub commit_parsers: Option<Vec<CommitParser>>,
/// Link parsers.
Expand Down Expand Up @@ -79,6 +81,16 @@ pub struct CommitParser {
pub skip: Option<bool>,
}

/// Preprocessor for modifying commit messages.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CommitPreprocessor {
/// Regex for matching a text to replace.
#[serde(with = "serde_regex")]
pub pattern: Regex,
/// Replacement text.
pub replace: String,
}

/// Parser for extracting links in commits.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct LinkParser {
Expand Down
10 changes: 10 additions & 0 deletions git-cliff-core/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use git_cliff_core::commit::Commit;
use git_cliff_core::config::{
ChangelogConfig,
CommitParser,
CommitPreprocessor,
GitConfig,
LinkParser,
};
Expand Down Expand Up @@ -39,6 +40,10 @@ fn generate_changelog() -> Result<()> {
let git_config = GitConfig {
conventional_commits: Some(true),
filter_unconventional: Some(true),
commit_preprocessors: Some(vec![CommitPreprocessor {
pattern: Regex::new(r#"\(fixes (#[1-9]+)\)"#).unwrap(),
replace: String::from("[closes Issue${1}]"),
}]),
commit_parsers: Some(vec![
CommitParser {
message: Regex::new("^feat").ok(),
Expand Down Expand Up @@ -105,6 +110,10 @@ fn generate_changelog() -> Result<()> {
String::from("hjkl12"),
String::from("chore: do boring stuff"),
),
Commit::new(
String::from("1234"),
String::from("fix: support preprocessing (fixes #99)"),
),
]
.iter()
.filter_map(|c| c.process(&git_config).ok())
Expand Down Expand Up @@ -155,6 +164,7 @@ fn generate_changelog() -> Result<()> {
### fix bugs
- fix abc
- support preprocessing [closes Issue#99]
### shiny features
- add xyz
Expand Down
10 changes: 10 additions & 0 deletions git-cliff/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ mod test {
use git_cliff_core::config::{
ChangelogConfig,
CommitParser,
CommitPreprocessor,
GitConfig,
};
use git_cliff_core::regex::Regex;
Expand Down Expand Up @@ -190,6 +191,10 @@ mod test {
git: GitConfig {
conventional_commits: Some(true),
filter_unconventional: Some(false),
commit_preprocessors: Some(vec![CommitPreprocessor {
pattern: Regex::new("<preprocess>").unwrap(),
replace: String::from("this commit is preprocessed"),
}]),
commit_parsers: Some(vec![
CommitParser {
message: Regex::new("feat*").ok(),
Expand Down Expand Up @@ -256,6 +261,10 @@ mod test {
String::from("0jkl12"),
String::from("chore(app): do nothing"),
),
Commit::new(
String::from("qwerty"),
String::from("chore: <preprocess>"),
),
],
commit_id: Some(String::from("0bc123")),
timestamp: 50000000,
Expand Down Expand Up @@ -340,6 +349,7 @@ mod test {
#### other
- support unconventional commits
- this commit is preprocessed
#### ui
- make good stuff
Expand Down

0 comments on commit 64317f2

Please sign in to comment.