Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): support changing commit scope with commit_parsers #94

Merged
merged 8 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/fixtures/test-custom-scope/cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[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 group, commits in commits | group_by(attribute="scope") %}
#### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}\
{% endfor %}\n
"""
# remove the leading and trailing whitespaces from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""

[git]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "Features", default_scope = "app"},
{ message = "^fix", group = "Bug Fixes", scope = "cli"},
]
9 changes: 9 additions & 0 deletions .github/fixtures/test-custom-scope/commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/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"
GIT_COMMITTER_DATE="2022-04-06 01:25:11" git commit --allow-empty -m "feat(gui): add feature 2"
GIT_COMMITTER_DATE="2022-04-06 01:25:12" git commit --allow-empty -m "fix(gui): fix feature 2"
git tag v0.1.0
24 changes: 24 additions & 0 deletions .github/fixtures/test-custom-scope/expected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Changelog

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

## [0.1.0] - 2022-04-06

### Bug Fixes

#### Cli

- Fix feature 1
- Fix feature 2

### Features

#### App

- Add feature 1

#### Gui

- Add feature 2

<!-- generated by git-cliff -->
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@ Examples:
- Skip processing the commit if the commit message (description) starts with "revert".
- `{ message = "^doc", group = "Documentation", default_scope = "other"},`
- If the commit starts with "doc", group the commit as "Documentation" and set the default scope to "other". (e.g. `docs: xyz` will be processed as `docs(other): xyz`)

- `{ message = "(www)", scope = "Application"}`
- If the commit contains "(www)", override the scope with "Application". Scoping order is: scope specification, conventional commit's scope and default scope.
#### filter_commits

If set to `true`, commits that are not matched by [commit parsers](#commit_parsers) are filtered out.
Expand Down
35 changes: 24 additions & 11 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@ use serde::ser::{
#[serde(rename_all = "camelCase")]
pub struct Commit<'a> {
/// Commit ID.
pub id: String,
pub id: String,
/// Commit message including title, description and summary.
pub message: String,
pub message: String,
/// Conventional commit.
#[serde(skip_deserializing)]
pub conv: Option<ConventionalCommit<'a>>,
pub conv: Option<ConventionalCommit<'a>>,
/// Commit group based on a commit parser or its conventional type.
pub group: Option<String>,
/// Commit scope based on conventional type or a commit parser.
pub scope: Option<String>,
pub group: Option<String>,
/// Default commit scope based on (inherited from) conventional type or a
/// commit parser.
pub default_scope: Option<String>,
/// Commit scope for overriding the default one.
pub scope: Option<String>,
/// A list of links found in the commit
pub links: Vec<Link>,
pub links: Vec<Link>,
}

/// Object representing a link
Expand Down Expand Up @@ -63,6 +66,7 @@ impl Commit<'_> {
message,
conv: None,
group: None,
default_scope: None,
scope: None,
links: vec![],
}
Expand Down Expand Up @@ -159,7 +163,8 @@ impl Commit<'_> {
if regex.is_match(&text) {
if parser.skip != Some(true) {
self.group = parser.group.as_ref().cloned();
self.scope = parser.default_scope.as_ref().cloned();
self.scope = parser.scope.as_ref().cloned();
self.default_scope = parser.default_scope.as_ref().cloned();
return Ok(self);
} else {
return Err(AppError::GroupError(String::from(
Expand Down Expand Up @@ -236,13 +241,20 @@ impl Serialize for Commit<'_> {
commit.serialize_field("breaking", &conv.breaking())?;
commit.serialize_field(
"scope",
&conv.scope().map(|v| v.as_str()).or(self.scope.as_deref()),
&self
.scope
.as_deref()
.or_else(|| conv.scope().map(|v| v.as_str()))
.or(self.default_scope.as_deref()),
)?;
}
None => {
commit.serialize_field("message", &self.message)?;
commit.serialize_field("group", &self.group)?;
commit.serialize_field("scope", &self.scope)?;
commit.serialize_field(
"scope",
&self.scope.as_deref().or(self.default_scope.as_deref()),
)?;
}
}
commit.serialize_field("links", &self.links)?;
Expand Down Expand Up @@ -282,13 +294,14 @@ mod test {
body: None,
group: Some(String::from("test_group")),
default_scope: Some(String::from("test_scope")),
scope: None,
skip: None,
}],
false,
)
.unwrap();
assert_eq!(Some(String::from("test_group")), commit.group);
assert_eq!(Some(String::from("test_scope")), commit.scope);
assert_eq!(Some(String::from("test_scope")), commit.default_scope);
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion git-cliff-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ pub struct CommitParser {
pub body: Option<Regex>,
/// Group of the commit.
pub group: Option<String>,
/// Scope of the commit.
/// Default scope of the commit.
pub default_scope: Option<String>,
/// Commit scope for overriding the default scope.
pub scope: Option<String>,
/// Whether to skip this commit group.
pub skip: Option<bool>,
}
Expand Down
17 changes: 17 additions & 0 deletions git-cliff-core/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,23 @@ fn generate_changelog() -> Result<()> {
body: None,
group: Some(String::from("shiny features")),
default_scope: None,
scope: None,
skip: None,
},
CommitParser {
message: Regex::new("^fix").ok(),
body: None,
group: Some(String::from("fix bugs")),
default_scope: None,
scope: None,
skip: None,
},
CommitParser {
message: Regex::new("^test").ok(),
body: None,
group: None,
default_scope: None,
scope: Some(String::from("tests")),
skip: None,
},
]),
Expand Down Expand Up @@ -111,6 +121,10 @@ fn generate_changelog() -> Result<()> {
String::from("hjkl12"),
String::from("chore: do boring stuff"),
),
Commit::new(
String::from("hjkl13"),
String::from("test(x): test some stuff"),
),
Commit::new(
String::from("1234"),
String::from("fix: support preprocessing (fixes #99)"),
Expand Down Expand Up @@ -174,6 +188,9 @@ fn generate_changelog() -> Result<()> {
- *(big-feature)* this is a breaking change
- **BREAKING**: this is a breaking change

### test
- *(tests)* test some stuff

## Release v1.0.0

### chore
Expand Down
20 changes: 20 additions & 0 deletions git-cliff/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,27 +204,39 @@ mod test {
body: None,
group: Some(String::from("New features")),
default_scope: Some(String::from("other")),
scope: None,
skip: None,
},
CommitParser {
message: Regex::new("fix*").ok(),
body: None,
group: Some(String::from("Bug Fixes")),
default_scope: None,
scope: None,
skip: None,
},
CommitParser {
message: Regex::new("merge*").ok(),
body: None,
group: None,
default_scope: None,
scope: None,
skip: Some(true),
},
CommitParser {
message: Regex::new("doc:").ok(),
body: None,
group: Some(String::from("Documentation")),
default_scope: None,
scope: Some(String::from("documentation")),
skip: None,
},
CommitParser {
message: Regex::new(".*").ok(),
body: None,
group: Some(String::from("Other")),
default_scope: Some(String::from("other")),
scope: None,
skip: None,
},
]),
Expand Down Expand Up @@ -260,6 +272,10 @@ mod test {
String::from("0w3rty"),
String::from("fix(ui): fix more stuff"),
),
Commit::new(
String::from("qw3rty"),
String::from("doc: update docs"),
),
Commit::new(
String::from("0jkl12"),
String::from("chore(app): do nothing"),
Expand Down Expand Up @@ -339,6 +355,10 @@ mod test {
#### ui
- fix more stuff

### Documentation
#### documentation
- update docs

### New features
#### app
- add cool features
Expand Down