Skip to content
Open
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
35 changes: 34 additions & 1 deletion git-cliff/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,18 @@ pub struct Opt {
long,
env = "GIT_CLIFF_TEMPLATE",
value_name = "TEMPLATE",
allow_hyphen_values = true
allow_hyphen_values = true,
conflicts_with = "body_file"
)]
pub body: Option<String>,
/// Sets the template for the changelog body from a file.
#[arg(
long,
env = "GIT_CLIFF_TEMPLATE_FILE",
value_name = "PATH",
value_parser = Opt::parse_dir
)]
pub body_file: Option<PathBuf>,
/// Processes the commits starting from the latest tag.
#[arg(short, long, help_heading = Some("FLAGS"))]
pub latest: bool,
Expand Down Expand Up @@ -585,6 +594,30 @@ mod tests {
Ok(())
}

#[test]
fn body_file_is_parsed_as_path() -> Result<(), Box<dyn std::error::Error>> {
let opt = Opt::try_parse_from(["git-cliff", "--body-file", "template.tera"])?;
assert_eq!(Some(PathBuf::from("template.tera")), opt.body_file);
assert_eq!(None, opt.body);
Ok(())
}

#[test]
fn body_and_body_file_conflict() {
let result = Opt::try_parse_from([
"git-cliff",
"--body",
"{{ version }}",
"--body-file",
"template.tera",
]);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().kind(),
clap::error::ErrorKind::ArgumentConflict
);
}

// Environment variables are process-global, so tests that modify them must run exclusively and
// restore the original state after execution. For this reason, we use the `serial` macro
// from the `serial_test` crate to guarantee exclusive execution. See: https://crates.io/crates/serial_test
Expand Down
2 changes: 2 additions & 0 deletions git-cliff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ pub fn run_with_changelog_modifier<'a>(
}
if let Some(body) = args.body.clone() {
config.changelog.body = body;
} else if let Some(body_file) = args.body_file.clone() {
config.changelog.body = fs::read_to_string(&body_file)?;
}
if args.sort == Sort::Oldest {
args.sort = Sort::from_str(&config.git.sort_commits, true)
Expand Down
1 change: 1 addition & 0 deletions website/docs/usage/args.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE]
-o, --output [<PATH>] Writes output to the given file [env: GIT_CLIFF_OUTPUT=]
-t, --tag <TAG> Sets the tag for the latest version [env: GIT_CLIFF_TAG=]
-b, --body <TEMPLATE> Sets the template for the changelog body [env: GIT_CLIFF_TEMPLATE=]
--body-file <PATH> Sets the template for the changelog body from a file [env: GIT_CLIFF_TEMPLATE_FILE=]
--from-context <PATH> Generates changelog from a JSON context [env: GIT_CLIFF_CONTEXT=]
-s, --strip <PART> Strips the given parts from the changelog [possible values: header, footer, all]
--sort <SORT> Sets sorting of the commits inside sections [default: oldest] [possible values: oldest, newest]
Expand Down
6 changes: 6 additions & 0 deletions website/docs/usage/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ Set/remove the changelog parts:
git cliff --body $template --strip footer
```

Read the body template from a file (useful for multiline templates):

```bash
git cliff --body-file template.tera
```

Skip running the commands defined in [pre](/docs/configuration/git#commit_preprocessors)/[postprocessors](/docs/configuration/changelog#postprocessors).

```bash
Expand Down
Loading