Skip to content

Commit

Permalink
feat(changelog): allow adding custom context (#613)
Browse files Browse the repository at this point in the history
* feat: allow adding custom context

* chore: add test

* fix: lint

* fix: lint

* fix: lint

* docs: contributing

* chore: polish implementation

---------

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
  • Loading branch information
MarcoIeni and orhun authored Apr 21, 2024
1 parent ade9eae commit 522bd53
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 9 deletions.
8 changes: 7 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ cargo build
cargo test
```

6. Make sure [rustfmt](https://github.com/rust-lang/rustfmt) and [clippy](https://github.com/rust-lang/rust-clippy) don't complain about your changes.
6. If needed, update the snapshot tests (i.e. tests using `expect_test`):

```sh
env UPDATE_EXPECT=1 cargo test
```

7. Make sure [rustfmt](https://github.com/rust-lang/rustfmt) and [clippy](https://github.com/rust-lang/rust-clippy) don't complain about your changes.

We use the `nightly` channel for `rustfmt` so please set the appropriate settings for your editor/IDE for that.

Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions git-cliff-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ features = ["debug-embed", "compression"]

[dev-dependencies]
pretty_assertions = "1.4.0"
expect-test = "1.5.0"

[package.metadata.docs.rs]
all-features = true
Expand Down
117 changes: 111 additions & 6 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ use std::time::{
#[derive(Debug)]
pub struct Changelog<'a> {
/// Releases that the changelog will contain.
pub releases: Vec<Release<'a>>,
body_template: Template,
footer_template: Option<Template>,
config: &'a Config,
pub releases: Vec<Release<'a>>,
body_template: Template,
footer_template: Option<Template>,
config: &'a Config,
additional_context: HashMap<String, serde_json::Value>,
}

impl<'a> Changelog<'a> {
Expand All @@ -54,12 +55,30 @@ impl<'a> Changelog<'a> {
None => None,
},
config,
additional_context: HashMap::new(),
};
changelog.process_commits();
changelog.process_releases();
Ok(changelog)
}

/// Adds a key value pair to the template context.
///
/// These values will be used when generating the changelog.
///
/// # Errors
///
/// This operation fails if the deserialization fails.
pub fn add_context(
&mut self,
key: impl Into<String>,
value: impl serde::Serialize,
) -> Result<()> {
self.additional_context
.insert(key.into(), serde_json::to_value(value)?);
Ok(())
}

/// Processes a single commit and returns/logs the result.
fn process_commit(
commit: Commit<'a>,
Expand Down Expand Up @@ -232,8 +251,11 @@ impl<'a> Changelog<'a> {
/// Generates the changelog and writes it to the given output.
pub fn generate<W: Write>(&self, out: &mut W) -> Result<()> {
debug!("Generating changelog...");
let mut additional_context = HashMap::new();
additional_context.insert("remote", self.config.remote.clone());
let mut additional_context = self.additional_context.clone();
additional_context.insert(
"remote".to_string(),
serde_json::to_value(self.config.remote.clone())?,
);
#[cfg(feature = "github")]
let (github_commits, github_pull_requests) = self.get_github_metadata()?;
let postprocessors = self
Expand Down Expand Up @@ -818,4 +840,87 @@ chore(deps): fix broken deps
);
Ok(())
}

#[test]
fn changelog_adds_additional_context() -> Result<()> {
let (mut config, releases) = get_test_data();
// add `{{ custom_field }}` to the template
config.changelog.body = Some(
r#"{% if version %}
## {{ custom_field }} [{{ version }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% if commit_id %}({{ commit_id }}){% endif %}{% else %}
## Unreleased{% endif %}
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group }}{% for group, commits in commits | group_by(attribute="scope") %}
#### {{ group }}{% for commit in commits %}
- {{ commit.message }}{% endfor %}
{% endfor %}{% endfor %}"#
.to_string(),
);
let mut changelog = Changelog::new(releases, &config)?;
changelog.add_context("custom_field", "Hello")?;
let mut out = Vec::new();
changelog.generate(&mut out)?;
expect_test::expect![[r#"
# Changelog
## Unreleased
### Bug Fixes
#### app
- fix abc
### New features
#### app
- add xyz
### Other
#### app
- document zyx
#### ui
- do exciting stuff
## Hello [v1.0.0] - 1971-08-02
(0bc123)
### Bug Fixes
#### ui
- fix more stuff
### Documentation
#### documentation
- update docs
- add some documentation
### I love tea
#### app
- damn right
### Matched (group)
#### group
- support regex-replace for groups
### New features
#### app
- add cool features
#### other
- support unscoped commits
- support breaking commits
### Other
#### app
- do nothing
#### other
- support unconventional commits
- this commit is preprocessed
#### ui
- make good stuff
-- total releases: 2 --
"#]]
.assert_eq(str::from_utf8(&out).unwrap_or_default());
Ok(())
}
}
4 changes: 2 additions & 2 deletions git-cliff-core/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl Template {
}

/// Renders the template.
pub fn render<C: Serialize, T: Serialize, S: Into<String> + Copy>(
pub fn render<C: Serialize, T: Serialize, S: Into<String> + Clone>(
&self,
context: &C,
additional_context: Option<&HashMap<S, T>>,
Expand All @@ -152,7 +152,7 @@ impl Template {
let mut context = TeraContext::from_serialize(context)?;
if let Some(additional_context) = additional_context {
for (key, value) in additional_context {
context.insert(*key, &value);
context.insert(key.clone(), &value);
}
}
match self.tera.render("template", &context) {
Expand Down

0 comments on commit 522bd53

Please sign in to comment.