Skip to content

Commit

Permalink
feat(args): allow returning the bumped version (#362)
Browse files Browse the repository at this point in the history
* feat: allow returning bumped version

* refactor(args): polish bumped-version implementation

---------

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
  • Loading branch information
nappa85 and orhun committed Dec 4, 2023
1 parent c94cb6a commit 5e01e4c
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 39 deletions.
27 changes: 27 additions & 0 deletions .github/fixtures/test-bumped-version/cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[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://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}]
{% 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 whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""
9 changes: 9 additions & 0 deletions .github/fixtures/test-bumped-version/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="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 1"
GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 2"
git tag v0.1.0

GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "fix: fix feature 1"
GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "fix: fix feature 2"
1 change: 1 addition & 0 deletions .github/fixtures/test-bumped-version/expected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.1
2 changes: 2 additions & 0 deletions .github/workflows/test-fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
- fixtures-name: test-keep-a-changelog-links
- fixtures-name: test-bump-version
command: --bump
- fixtures-name: test-bumped-version
command: --bumped-version
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
49 changes: 26 additions & 23 deletions git-cliff/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct Opt {
help = "Prints help information",
help_heading = "FLAGS"
)]
pub help: Option<bool>,
pub help: Option<bool>,
#[arg(
short = 'V',
long,
Expand All @@ -61,10 +61,10 @@ pub struct Opt {
help = "Prints version information",
help_heading = "FLAGS"
)]
pub version: Option<bool>,
pub version: Option<bool>,
/// Increases the logging verbosity.
#[arg(short, long, action = ArgAction::Count, alias = "debug", help_heading = Some("FLAGS"))]
pub verbose: u8,
pub verbose: u8,
/// Sets the configuration file.
#[arg(
short,
Expand All @@ -74,7 +74,7 @@ pub struct Opt {
default_value = DEFAULT_CONFIG,
value_parser = Opt::parse_dir
)]
pub config: PathBuf,
pub config: PathBuf,
/// Sets the working directory.
#[arg(
short,
Expand All @@ -83,7 +83,7 @@ pub struct Opt {
value_name = "PATH",
value_parser = Opt::parse_dir
)]
pub workdir: Option<PathBuf>,
pub workdir: Option<PathBuf>,
/// Sets the git repository.
#[arg(
short,
Expand All @@ -93,31 +93,31 @@ pub struct Opt {
num_args(1..),
value_parser = Opt::parse_dir
)]
pub repository: Option<Vec<PathBuf>>,
pub repository: Option<Vec<PathBuf>>,
/// Sets the path to include related commits.
#[arg(
long,
env = "GIT_CLIFF_INCLUDE_PATH",
value_name = "PATTERN",
num_args(1..)
)]
pub include_path: Option<Vec<Pattern>>,
pub include_path: Option<Vec<Pattern>>,
/// Sets the path to exclude related commits.
#[arg(
long,
env = "GIT_CLIFF_EXCLUDE_PATH",
value_name = "PATTERN",
num_args(1..)
)]
pub exclude_path: Option<Vec<Pattern>>,
pub exclude_path: Option<Vec<Pattern>>,
/// Sets custom commit messages to include in the changelog.
#[arg(
long,
env = "GIT_CLIFF_WITH_COMMIT",
value_name = "MSG",
num_args(1..)
)]
pub with_commit: Option<Vec<String>>,
pub with_commit: Option<Vec<String>>,
/// Prepends entries to the given changelog file.
#[arg(
short,
Expand All @@ -126,7 +126,7 @@ pub struct Opt {
value_name = "PATH",
value_parser = Opt::parse_dir
)]
pub prepend: Option<PathBuf>,
pub prepend: Option<PathBuf>,
/// Writes output to the given file.
#[arg(
short,
Expand All @@ -137,7 +137,7 @@ pub struct Opt {
num_args = 0..=1,
default_missing_value = DEFAULT_OUTPUT
)]
pub output: Option<PathBuf>,
pub output: Option<PathBuf>,
/// Sets the tag for the latest version.
#[arg(
short,
Expand All @@ -146,10 +146,13 @@ pub struct Opt {
value_name = "TAG",
allow_hyphen_values = true
)]
pub tag: Option<String>,
pub tag: Option<String>,
/// Bumps the version for unreleased changes.
#[arg(long, help_heading = Some("FLAGS"))]
pub bump: bool,
pub bump: bool,
/// Prints bumped version for unreleased changes.
#[arg(long, help_heading = Some("FLAGS"))]
pub bumped_version: bool,
/// Sets the template for the changelog body.
#[arg(
short,
Expand All @@ -158,38 +161,38 @@ pub struct Opt {
value_name = "TEMPLATE",
allow_hyphen_values = true
)]
pub body: Option<String>,
pub body: Option<String>,
/// Writes the default configuration file to cliff.toml
#[arg(short, long, help_heading = Some("FLAGS"))]
pub init: bool,
pub init: bool,
/// Processes the commits starting from the latest tag.
#[arg(short, long, help_heading = Some("FLAGS"))]
pub latest: bool,
pub latest: bool,
/// Processes the commits that belong to the current tag.
#[arg(long, help_heading = Some("FLAGS"))]
pub current: bool,
pub current: bool,
/// Processes the commits that do not belong to a tag.
#[arg(short, long, help_heading = Some("FLAGS"))]
pub unreleased: bool,
pub unreleased: bool,
/// Sorts the tags topologically.
#[arg(long, help_heading = Some("FLAGS"))]
pub topo_order: bool,
pub topo_order: bool,
/// Prints changelog context as JSON.
#[arg(long, help_heading = Some("FLAGS"))]
pub context: bool,
pub context: bool,
/// Strips the given parts from the changelog.
#[arg(short, long, value_name = "PART", value_enum)]
pub strip: Option<Strip>,
pub strip: Option<Strip>,
/// Sets sorting of the commits inside sections.
#[arg(
long,
value_enum,
default_value_t = Sort::Oldest
)]
pub sort: Sort,
pub sort: Sort,
/// Sets the commit range to process.
#[arg(value_name = "RANGE", help_heading = Some("ARGS"))]
pub range: Option<String>,
pub range: Option<String>,
}

impl Opt {
Expand Down
46 changes: 40 additions & 6 deletions git-cliff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use std::fs::{
self,
File,
};
use std::io;
use std::io::{
self,
Write,
};
use std::time::{
SystemTime,
UNIX_EPOCH,
Expand All @@ -59,6 +62,14 @@ fn check_new_version() {
}
}

/// Output of the `process_repository` call.
enum ProcessOutput<'a> {
/// List of releases.
Releases(Vec<Release<'a>>),
/// Semantic version.
Version(String),
}

/// Processes the tags and commits for creating release entries for the
/// changelog.
///
Expand All @@ -68,7 +79,7 @@ fn process_repository<'a>(
repository: &'static Repository,
config: Config,
args: &Opt,
) -> Result<Vec<Release<'a>>> {
) -> Result<ProcessOutput<'a>> {
let mut tags = repository.tags(&config.git.tag_pattern, args.topo_order)?;
let skip_regex = config.git.skip_tags.as_ref();
let ignore_regex = config.git.ignore_tags.as_ref();
Expand Down Expand Up @@ -240,8 +251,14 @@ fn process_repository<'a>(
}

// Bump the version.
if args.bump && releases[release_index].version.is_none() {
if (args.bump || args.bumped_version) &&
releases[release_index].version.is_none()
{
let next_version = releases[release_index].calculate_next_version()?;
if args.bumped_version {
return Ok(ProcessOutput::Version(next_version));
}

debug!("Bumping the version to {next_version}");
releases[release_index].version = Some(next_version.to_string());
releases[release_index].timestamp = SystemTime::now()
Expand All @@ -250,7 +267,7 @@ fn process_repository<'a>(
.try_into()?;
}

Ok(releases)
Ok(ProcessOutput::Releases(releases))
}

/// Runs `git-cliff`.
Expand Down Expand Up @@ -350,16 +367,33 @@ pub fn run(mut args: Opt) -> Result<()> {
// Process the repository.
let repositories = args.repository.clone().unwrap_or(vec![env::current_dir()?]);
let mut releases = Vec::<Release>::new();
let mut versions = Vec::<String>::new();
for repository in repositories {
let repository = Repository::init(repository)?;
releases.extend(process_repository(
let process_output = process_repository(
Box::leak(Box::new(repository)),
config.clone(),
&args,
)?);
)?;

match process_output {
ProcessOutput::Releases(release) => releases.extend(release),
ProcessOutput::Version(version) => versions.push(version),
}
}

// Generate output.
if !versions.is_empty() {
let buf = versions.join("\n");
if let Some(path) = args.output {
let mut output = File::create(path)?;
output.write_all(buf.as_bytes())?;
} else {
println!("{buf}");
};
return Ok(());
}

let changelog = Changelog::new(releases, &config)?;
if args.context {
return if let Some(path) = args.output {
Expand Down
2 changes: 2 additions & 0 deletions website/docs/usage/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Calculate and set the next semantic version (i.e. _bump the version_) for the un
# Semver: {MAJOR}.{MINOR}.{PATCH}
# "fix:" increments PATCH, "feat:" increments MINOR and "scope!" (breaking changes) increments MAJOR
git cliff --bump
# Calculate and print the next semantic version to stdout
git cliff --bumped-version
```

Generate a changelog for a certain part of git history:
Expand Down
21 changes: 11 additions & 10 deletions website/docs/usage/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE]
## Flags

```
-h, --help Prints help information
-V, --version Prints version information
-v, --verbose... Increases the logging verbosity
--bump Bumps the version for unreleased changes
-i, --init Writes the default configuration file to cliff.toml
-l, --latest Processes the commits starting from the latest tag
--current Processes the commits that belong to the current tag
-u, --unreleased Processes the commits that do not belong to a tag
--topo-order Sorts the tags topologically
--context Prints changelog context as JSON
-h, --help Prints help information
-V, --version Prints version information
-v, --verbose... Increases the logging verbosity
--bump Bumps the version for unreleased changes
--bumped-version Prints bumped version for unreleased changes
-i, --init Writes the default configuration file to cliff.toml
-l, --latest Processes the commits starting from the latest tag
--current Processes the commits that belong to the current tag
-u, --unreleased Processes the commits that do not belong to a tag
--topo-order Sorts the tags topologically
--context Prints changelog context as JSON
```

## Options
Expand Down

0 comments on commit 5e01e4c

Please sign in to comment.