From db480241f10be2794e369a23f53181f528c2f80a Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Sun, 4 Aug 2024 22:19:37 +0200 Subject: [PATCH 01/12] feat(cli): generate changelog from JSON context --- git-cliff-core/src/changelog.rs | 26 +++++++--- git-cliff-core/src/commit.rs | 4 +- git-cliff-core/src/release.rs | 2 +- git-cliff/src/args.rs | 9 ++++ git-cliff/src/lib.rs | 86 ++++++++++++++++++--------------- 5 files changed, 79 insertions(+), 48 deletions(-) diff --git a/git-cliff-core/src/changelog.rs b/git-cliff-core/src/changelog.rs index dd13670dbc..e3ebae41ee 100644 --- a/git-cliff-core/src/changelog.rs +++ b/git-cliff-core/src/changelog.rs @@ -18,7 +18,10 @@ use crate::remote::github::GitHubClient; use crate::remote::gitlab::GitLabClient; use crate::template::Template; use std::collections::HashMap; -use std::io::Write; +use std::io::{ + Read, + Write, +}; use std::time::{ SystemTime, UNIX_EPOCH, @@ -39,8 +42,16 @@ pub struct Changelog<'a> { impl<'a> Changelog<'a> { /// Constructs a new instance. pub fn new(releases: Vec>, config: &'a Config) -> Result { + let mut changelog = Changelog::build(releases, config)?; + changelog.process_commits(); + changelog.process_releases(); + changelog.add_remote_data()?; + Ok(changelog) + } + + fn build(releases: Vec>, config: &'a Config) -> Result { let trim = config.changelog.trim.unwrap_or(true); - let mut changelog = Self { + Ok(Self { releases, header_template: match &config.changelog.header { Some(header) => Some(Template::new(header.to_string(), trim)?), @@ -61,11 +72,12 @@ impl<'a> Changelog<'a> { }, config, additional_context: HashMap::new(), - }; - changelog.process_commits(); - changelog.process_releases(); - changelog.add_remote_data()?; - Ok(changelog) + }) + } + + /// Constructs an instance from a serialized context object. + pub fn from_context(input: &mut R, config: &'a Config) -> Result { + Changelog::build(serde_json::from_reader(input)?, config) } /// Adds a key value pair to the template context. diff --git a/git-cliff-core/src/commit.rs b/git-cliff-core/src/commit.rs index f60928492f..bfdd5decda 100644 --- a/git-cliff-core/src/commit.rs +++ b/git-cliff-core/src/commit.rs @@ -37,7 +37,7 @@ static SHA1_REGEX: Lazy = lazy_regex!(r#"^\b([a-f0-9]{40})\b (.*)$"#); /// Object representing a link #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all(serialize = "camelCase"))] pub struct Link { /// Text of the link. pub text: String, @@ -98,7 +98,7 @@ impl<'a> From> for Signature { /// Common commit object that is parsed from a repository. #[derive(Debug, Default, Clone, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all(serialize = "camelCase"))] pub struct Commit<'a> { /// Commit ID. pub id: String, diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs index 2e681bf51b..95b7b98fc9 100644 --- a/git-cliff-core/src/release.rs +++ b/git-cliff-core/src/release.rs @@ -24,7 +24,7 @@ use serde::{ /// Representation of a release. #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all(serialize = "camelCase"))] pub struct Release<'a> { /// Release version, git tag. pub version: Option, diff --git a/git-cliff/src/args.rs b/git-cliff/src/args.rs index f0decb7944..0ecdc78af2 100644 --- a/git-cliff/src/args.rs +++ b/git-cliff/src/args.rs @@ -231,6 +231,15 @@ pub struct Opt { /// Prints changelog context as JSON. #[arg(short = 'x', long, help_heading = Some("FLAGS"))] pub context: bool, + /// Generates changelog from a JSON context. + #[arg( + long, + help_heading = Some("FLAGS"), + value_name = "PATH", + value_parser = Opt::parse_dir, + num_args = 0..=1, + )] + pub from_context: Option, /// Strips the given parts from the changelog. #[arg(short, long, value_name = "PART", value_enum)] pub strip: Option, diff --git a/git-cliff/src/lib.rs b/git-cliff/src/lib.rs index 8627cc25e5..278cbcd82d 100644 --- a/git-cliff/src/lib.rs +++ b/git-cliff/src/lib.rs @@ -496,49 +496,59 @@ pub fn run(mut args: Opt) -> Result<()> { if args.ignore_tags.is_some() { config.git.ignore_tags.clone_from(&args.ignore_tags); } - // Process the repositories. - let repositories = args.repository.clone().unwrap_or(vec![env::current_dir()?]); - let mut releases = Vec::::new(); - for repository in repositories { - // Skip commits - let mut skip_list = Vec::new(); - let ignore_file = repository.join(IGNORE_FILE); - if ignore_file.exists() { - let contents = fs::read_to_string(ignore_file)?; - let commits = contents - .lines() - .filter(|v| !(v.starts_with('#') || v.trim().is_empty())) - .map(|v| String::from(v.trim())) - .collect::>(); - skip_list.extend(commits); - } - if let Some(ref skip_commit) = args.skip_commit { - skip_list.extend(skip_commit.clone()); - } - if let Some(commit_parsers) = config.git.commit_parsers.as_mut() { - for sha1 in skip_list { - commit_parsers.insert(0, CommitParser { - sha: Some(sha1.to_string()), - skip: Some(true), - ..Default::default() - }) - } - } - - // Process the repository. - let repository = Repository::init(repository)?; - releases.extend(process_repository( - Box::leak(Box::new(repository)), - &mut config, - &args, - )?); - } // Process commits and releases for the changelog. if let Some(BumpOption::Specific(bump_type)) = args.bump { config.bump.bump_type = Some(bump_type) } - let mut changelog = Changelog::new(releases, &config)?; + + let mut changelog: Changelog = if let Some(context_path) = args.from_context { + if context_path == Path::new("-") { + Changelog::from_context(&mut io::stdin(), &config)? + } else { + Changelog::from_context(&mut File::open(context_path)?, &config)? + } + } else { + // Process the repositories. + let repositories = + args.repository.clone().unwrap_or(vec![env::current_dir()?]); + let mut releases = Vec::::new(); + for repository in repositories { + // Skip commits + let mut skip_list = Vec::new(); + let ignore_file = repository.join(IGNORE_FILE); + if ignore_file.exists() { + let contents = fs::read_to_string(ignore_file)?; + let commits = contents + .lines() + .filter(|v| !(v.starts_with('#') || v.trim().is_empty())) + .map(|v| String::from(v.trim())) + .collect::>(); + skip_list.extend(commits); + } + if let Some(ref skip_commit) = args.skip_commit { + skip_list.extend(skip_commit.clone()); + } + if let Some(commit_parsers) = config.git.commit_parsers.as_mut() { + for sha1 in skip_list { + commit_parsers.insert(0, CommitParser { + sha: Some(sha1.to_string()), + skip: Some(true), + ..Default::default() + }) + } + } + + // Process the repository. + let repository = Repository::init(repository)?; + releases.extend(process_repository( + Box::leak(Box::new(repository)), + &mut config, + &args, + )?); + } + Changelog::new(releases, &config)? + }; // Print the result. let mut out: Box = if let Some(path) = &args.output { From 95e7e9e973f4b7a5053d2f6ad6a68c4fa22bd221 Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 15 Aug 2024 15:40:52 +0200 Subject: [PATCH 02/12] Add 'extra' field to releases and commits --- git-cliff-core/src/commit.rs | 3 +++ git-cliff-core/src/release.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/git-cliff-core/src/commit.rs b/git-cliff-core/src/commit.rs index bfdd5decda..da752d5edb 100644 --- a/git-cliff-core/src/commit.rs +++ b/git-cliff-core/src/commit.rs @@ -30,6 +30,7 @@ use serde::{ Deserialize, Serialize, }; +use serde_json::value::Value; /// Regular expression for matching SHA1 and a following commit message /// separated by a whitespace. @@ -122,6 +123,8 @@ pub struct Commit<'a> { pub committer: Signature, /// Whether if the commit has two or more parents. pub merge_commit: bool, + /// Arbitrary data to be used with the `--from-context` CLI option. + pub extra: Option, /// GitHub metadata of the commit. #[cfg(feature = "github")] pub github: crate::remote::RemoteContributor, diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs index 95b7b98fc9..72cd580016 100644 --- a/git-cliff-core/src/release.rs +++ b/git-cliff-core/src/release.rs @@ -21,6 +21,7 @@ use serde::{ Deserialize, Serialize, }; +use serde_json::value::Value; /// Representation of a release. #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -41,6 +42,8 @@ pub struct Release<'a> { pub previous: Option>>, /// Repository path. pub repository: Option, + /// Arbitrary data to be used with the `--from-context` CLI option. + pub extra: Option, /// Contributors. #[cfg(feature = "github")] pub github: RemoteReleaseMetadata, From 7f2323cb5b32f9fa81271387e3fd4c7d113cf0f9 Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 15 Aug 2024 16:24:26 +0200 Subject: [PATCH 03/12] Add fixture test --- .github/fixtures/test-from-context/cliff.toml | 34 + .github/fixtures/test-from-context/commit.sh | 11 + .../fixtures/test-from-context/context.json | 626 ++++++++++++++++++ .../fixtures/test-from-context/expected.md | 31 + .github/workflows/test-fixtures.yml | 2 + 5 files changed, 704 insertions(+) create mode 100644 .github/fixtures/test-from-context/cliff.toml create mode 100755 .github/fixtures/test-from-context/commit.sh create mode 100644 .github/fixtures/test-from-context/context.json create mode 100644 .github/fixtures/test-from-context/expected.md diff --git a/.github/fixtures/test-from-context/cliff.toml b/.github/fixtures/test-from-context/cliff.toml new file mode 100644 index 0000000000..c533b79632 --- /dev/null +++ b/.github/fixtures/test-from-context/cliff.toml @@ -0,0 +1,34 @@ +[changelog] +# template for the changelog footer +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") }}] - {{ timestamp | date(format="%Y-%m-%d") }}{% if extra.note %} - {{ extra.note }}{% endif %} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {{ commit.message | upper_first }}{% if commit.extra.note %} ({{ commit.extra.note }}){% endif %}\ + {% endfor %} +{% endfor %}\n +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailing whitespace from the templates +trim = true + +[git] +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "Features", default_scope = "app" }, + { message = "^fix", group = "Bug Fixes", scope = "cli" }, +] diff --git a/.github/fixtures/test-from-context/commit.sh b/.github/fixtures/test-from-context/commit.sh new file mode 100755 index 0000000000..86dc2c57eb --- /dev/null +++ b/.github/fixtures/test-from-context/commit.sh @@ -0,0 +1,11 @@ +#!/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 tag v0.1.0 +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 SHOULD NOT BE IN THE CHANGELOG" +git tag v0.2.0 +GIT_COMMITTER_DATE="2022-04-06 01:25:13" git commit --allow-empty -m "test: add tests" diff --git a/.github/fixtures/test-from-context/context.json b/.github/fixtures/test-from-context/context.json new file mode 100644 index 0000000000..5dee19a9f8 --- /dev/null +++ b/.github/fixtures/test-from-context/context.json @@ -0,0 +1,626 @@ +[ + { + "version": null, + "message": null, + "commits": [ + { + "id": "c7541276668616c136d12a9ccd87087314d66fb6", + "message": "add tests", + "body": null, + "footers": [], + "group": "test", + "breaking_description": null, + "breaking": false, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201113 + }, + "conventional": true, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + } + ], + "commit_id": null, + "timestamp": 0, + "previous": { + "version": "v0.2.0", + "message": null, + "commits": [ + { + "id": "ce8cecc9834e5cbdb5b4e79c8260cace3c0dd949", + "message": "feat(gui): add feature 2\n", + "group": null, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201111 + }, + "conventional": false, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + }, + { + "id": "5061081d6272b1da2146fab49d803c193db309d9", + "message": "fix(gui): fix feature 2\n", + "group": null, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201112 + }, + "conventional": false, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + } + ], + "commit_id": "5061081d6272b1da2146fab49d803c193db309d9", + "timestamp": 1649201112, + "previous": null, + "repository": "/home/johndoe/repo/", + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + }, + "repository": "/home/johndoe/repo/", + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + }, + { + "version": "v0.2.0", + "message": null, + "commits": [ + { + "id": "ce8cecc9834e5cbdb5b4e79c8260cace3c0dd949", + "message": "add feature 2", + "body": null, + "footers": [], + "group": "Features", + "breaking_description": null, + "breaking": false, + "scope": "gui", + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201111 + }, + "conventional": true, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + }, + { + "id": "5061081d6272b1da2146fab49d803c193db309d9", + "message": "fix feature 2", + "body": null, + "footers": [], + "group": "Bug Fixes", + "breaking_description": null, + "breaking": false, + "scope": "cli", + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201112 + }, + "conventional": true, + "merge_commit": false, + "extra": { + "note": "that was a tough one" + }, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + } + ], + "commit_id": "5061081d6272b1da2146fab49d803c193db309d9", + "timestamp": 1649201112, + "previous": { + "version": "v0.1.0", + "message": null, + "commits": [ + { + "id": "c6ba7fe73c3b639ff2f934f3f98e5f50350ab463", + "message": "Initial commit\n", + "group": null, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201108 + }, + "conventional": false, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + }, + { + "id": "9c10e506bf103998e303d8164c7b4a1a841e2471", + "message": "feat: add feature 1\n", + "group": null, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201109 + }, + "conventional": false, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + }, + { + "id": "98b1464c2f99a0c6812ce6d3ea4a5b953dd35fe2", + "message": "fix: fix feature 1\n", + "group": null, + "scope": null, + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201110 + }, + "conventional": false, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + } + ], + "commit_id": "98b1464c2f99a0c6812ce6d3ea4a5b953dd35fe2", + "timestamp": 1649201110, + "previous": null, + "repository": "/home/johndoe/repo/", + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + }, + "extra": { + "note": "This is so awesome!" + }, + "repository": "/home/johndoe/repo/", + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + }, + { + "version": "v0.1.0", + "message": null, + "commits": [ + { + "id": "9c10e506bf103998e303d8164c7b4a1a841e2471", + "message": "add feature 1", + "body": null, + "footers": [], + "group": "Features", + "breaking_description": null, + "breaking": false, + "scope": "app", + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201109 + }, + "conventional": true, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + }, + { + "id": "98b1464c2f99a0c6812ce6d3ea4a5b953dd35fe2", + "message": "fix feature 1", + "body": null, + "footers": [], + "group": "Bug Fixes", + "breaking_description": null, + "breaking": false, + "scope": "cli", + "links": [], + "author": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1723730666 + }, + "committer": { + "name": "John Doe", + "email": "john@doe.com", + "timestamp": 1649201110 + }, + "conventional": true, + "merge_commit": false, + "github": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitlab": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "gitea": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + }, + "bitbucket": { + "username": null, + "pr_title": null, + "pr_number": null, + "pr_labels": [], + "is_first_time": false + } + } + ], + "commit_id": "98b1464c2f99a0c6812ce6d3ea4a5b953dd35fe2", + "timestamp": 1649201110, + "previous": { + "version": null, + "message": null, + "commits": [], + "commit_id": null, + "timestamp": 0, + "previous": null, + "repository": null, + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + }, + "repository": "/home/johndoe/repo/", + "github": { + "contributors": [] + }, + "gitlab": { + "contributors": [] + }, + "gitea": { + "contributors": [] + }, + "bitbucket": { + "contributors": [] + } + } +] diff --git a/.github/fixtures/test-from-context/expected.md b/.github/fixtures/test-from-context/expected.md new file mode 100644 index 0000000000..a0b0a247bd --- /dev/null +++ b/.github/fixtures/test-from-context/expected.md @@ -0,0 +1,31 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [unreleased] + +### Test + +- Add tests + +## [0.2.0] - 2022-04-06 - This is so awesome! + +### Bug Fixes + +- Fix feature 2 (that was a tough one) + +### Features + +- Add feature 2 + +## [0.1.0] - 2022-04-06 + +### Bug Fixes + +- Fix feature 1 + +### Features + +- Add feature 1 + + diff --git a/.github/workflows/test-fixtures.yml b/.github/workflows/test-fixtures.yml index ba9daa2f4a..69b74e2f9a 100644 --- a/.github/workflows/test-fixtures.yml +++ b/.github/workflows/test-fixtures.yml @@ -91,6 +91,8 @@ jobs: - fixtures-name: test-tag-message - fixtures-name: test-bump-unreleased-with-tag-message-arg command: --bump --unreleased --with-tag-message "Some text" + - fixtures-name: test-from-context + command: --from-context context.json steps: - name: Checkout From ad78a6b590175d4f28a5b8dc0078c7280187e805 Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 22 Aug 2024 10:10:01 +0200 Subject: [PATCH 04/12] Serialize extra field for commits --- git-cliff-core/src/commit.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/git-cliff-core/src/commit.rs b/git-cliff-core/src/commit.rs index 8b84b65310..799c5ac056 100644 --- a/git-cliff-core/src/commit.rs +++ b/git-cliff-core/src/commit.rs @@ -457,6 +457,7 @@ impl Serialize for Commit<'_> { commit.serialize_field("committer", &self.committer)?; commit.serialize_field("conventional", &self.conv.is_some())?; commit.serialize_field("merge_commit", &self.merge_commit)?; + commit.serialize_field("extra", &self.extra)?; #[cfg(feature = "github")] commit.serialize_field("github", &self.github)?; #[cfg(feature = "gitlab")] From 9ad063b9fed45d2c30103dd1be49e6dd09500dbd Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 22 Aug 2024 10:13:32 +0200 Subject: [PATCH 05/12] Format --- git-cliff-core/src/commit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-cliff-core/src/commit.rs b/git-cliff-core/src/commit.rs index 799c5ac056..ba5139695d 100644 --- a/git-cliff-core/src/commit.rs +++ b/git-cliff-core/src/commit.rs @@ -457,7 +457,7 @@ impl Serialize for Commit<'_> { commit.serialize_field("committer", &self.committer)?; commit.serialize_field("conventional", &self.conv.is_some())?; commit.serialize_field("merge_commit", &self.merge_commit)?; - commit.serialize_field("extra", &self.extra)?; + commit.serialize_field("extra", &self.extra)?; #[cfg(feature = "github")] commit.serialize_field("github", &self.github)?; #[cfg(feature = "gitlab")] From 76a430ae09a205e65dba5dfff04a9b6a734638f9 Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 22 Aug 2024 10:41:14 +0200 Subject: [PATCH 06/12] Adjust test expectations --- .github/fixtures/test-from-context/expected.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/fixtures/test-from-context/expected.md b/.github/fixtures/test-from-context/expected.md index a0b0a247bd..5e0ff03ca1 100644 --- a/.github/fixtures/test-from-context/expected.md +++ b/.github/fixtures/test-from-context/expected.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - Add tests -## [0.2.0] - 2022-04-06 - This is so awesome! +## [0.2.0] - 2022-04-05 - This is so awesome! ### Bug Fixes @@ -18,7 +18,7 @@ All notable changes to this project will be documented in this file. - Add feature 2 -## [0.1.0] - 2022-04-06 +## [0.1.0] - 2022-04-05 ### Bug Fixes From 6191cd89864e5058cde913cb4247e82f7e95b625 Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 22 Aug 2024 22:43:46 +0200 Subject: [PATCH 07/12] Add missing fields in tests --- git-cliff-core/src/changelog.rs | 2 ++ git-cliff-core/src/release.rs | 4 ++++ git-cliff-core/src/template.rs | 1 + git-cliff-core/tests/integration_test.rs | 2 ++ 4 files changed, 9 insertions(+) diff --git a/git-cliff-core/src/changelog.rs b/git-cliff-core/src/changelog.rs index e71cd85eda..de8cbd8cd4 100644 --- a/git-cliff-core/src/changelog.rs +++ b/git-cliff-core/src/changelog.rs @@ -833,6 +833,7 @@ mod test { let test_release = Release { version: Some(String::from("v1.0.0")), message: None, + extra: None, commits: vec![ Commit::new( String::from("coffee"), @@ -929,6 +930,7 @@ mod test { Release { version: None, message: None, + extra: None, commits: vec![ Commit::new( String::from("abc123"), diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs index 72cd580016..56fb8967a5 100644 --- a/git-cliff-core/src/release.rs +++ b/git-cliff-core/src/release.rs @@ -197,6 +197,7 @@ mod test { Release { version: None, message: None, + extra: None, commits: commits .iter() .map(|v| Commit::from(v.to_string())) @@ -392,6 +393,7 @@ mod test { let mut release = Release { version: None, message: None, + extra: None, commits: vec![ Commit::from(String::from( "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \ @@ -679,6 +681,7 @@ mod test { let mut release = Release { version: None, message: None, + extra: None, commits: vec![ Commit::from(String::from( "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \ @@ -1024,6 +1027,7 @@ mod test { let mut release = Release { version: None, message: None, + extra: None, commits: vec![ Commit::from(String::from( "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \ diff --git a/git-cliff-core/src/template.rs b/git-cliff-core/src/template.rs index 6d2e611805..d9ced84abf 100644 --- a/git-cliff-core/src/template.rs +++ b/git-cliff-core/src/template.rs @@ -190,6 +190,7 @@ mod test { Release { version: Some(String::from("1.0")), message: None, + extra: None, commits: vec![ Commit::new( String::from("123123"), diff --git a/git-cliff-core/tests/integration_test.rs b/git-cliff-core/tests/integration_test.rs index 355dd11526..58141a93b3 100644 --- a/git-cliff-core/tests/integration_test.rs +++ b/git-cliff-core/tests/integration_test.rs @@ -151,6 +151,7 @@ fn generate_changelog() -> Result<()> { Release { version: Some(String::from("v2.0.0")), message: None, + extra: None, commits: vec![ Commit::new( @@ -216,6 +217,7 @@ fn generate_changelog() -> Result<()> { Release { version: Some(String::from("v1.0.0")), message: None, + extra: None, commits: vec![ Commit::new( String::from("0bc123"), From 8b3ca6c77b4ff71fcc6b62654dc6b6427c8badca Mon Sep 17 00:00:00 2001 From: Jan Buchar Date: Thu, 22 Aug 2024 23:15:58 +0200 Subject: [PATCH 08/12] Add usage page --- website/docs/usage/load-context.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 website/docs/usage/load-context.md diff --git a/website/docs/usage/load-context.md b/website/docs/usage/load-context.md new file mode 100644 index 0000000000..cf607f91c6 --- /dev/null +++ b/website/docs/usage/load-context.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 11 +--- + +# Load context + +To load a context from a file and output the generated changelog: + +```bash +# process context loaded from stdin +git cliff --from-context - + +# process context loaded from a file +git cliff --from-context context.json +``` + +This is useful if you want to [print context](/docs/usage/print-context), modify it with an external tool and then "pipe" it back into git cliff. Free-form metadata can be added to release objects and commit objects in the context using the `extra` field. From 146c8b6173337ecaf5c5b8c6983bccd1cf2efa7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orhun=20Parmaks=C4=B1z?= Date: Fri, 23 Aug 2024 15:18:13 +0300 Subject: [PATCH 09/12] refactor(arg): update from-context argument details --- git-cliff/src/args.rs | 3 +-- website/docs/usage/args.md | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/git-cliff/src/args.rs b/git-cliff/src/args.rs index 6ee8860a5a..1b8beb6a30 100644 --- a/git-cliff/src/args.rs +++ b/git-cliff/src/args.rs @@ -237,10 +237,9 @@ pub struct Opt { /// Generates changelog from a JSON context. #[arg( long, - help_heading = Some("FLAGS"), value_name = "PATH", value_parser = Opt::parse_dir, - num_args = 0..=1, + env = "GIT_CLIFF_CONTEXT", )] pub from_context: Option, /// Strips the given parts from the changelog. diff --git a/website/docs/usage/args.md b/website/docs/usage/args.md index 9c500952a7..6b3f6570a4 100644 --- a/website/docs/usage/args.md +++ b/website/docs/usage/args.md @@ -43,6 +43,7 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE] -o, --output [] Writes output to the given file [env: GIT_CLIFF_OUTPUT=] -t, --tag Sets the tag for the latest version [env: GIT_CLIFF_TAG=] -b, --body