From cafe25e95dd42e20a44f5a9c8b1d02ad1ca04b08 Mon Sep 17 00:00:00 2001 From: Andre Lehmann Date: Sun, 2 May 2021 22:31:29 +0200 Subject: [PATCH 1/3] feat(changelog): add 'template' option to supply a custom changelog template The feature was requested in #132 --- commitizen/changelog.py | 18 +++++++++++++----- commitizen/cli.py | 1 + commitizen/commands/changelog.py | 5 ++++- .../templates/keep_a_changelog_template.j2 | 6 +++--- docs/changelog.md | 12 ++++++++++++ 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 7bb9007cdc..895add4958 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -161,11 +161,19 @@ def order_changelog_tree(tree: Iterable, change_type_order: List[str]) -> Iterab return sorted_tree -def render_changelog(tree: Iterable) -> str: - loader = PackageLoader("commitizen", "templates") - env = Environment(loader=loader, trim_blocks=True) - jinja_template = env.get_template("keep_a_changelog_template.j2") - changelog: str = jinja_template.render(tree=tree) +def render_changelog(releases: Iterable, template: str = None) -> str: + env = Environment(trim_blocks=True) + jinja_template = None + if template: + # load template from given path + with open(template, "r") as f: + template_content = f.read() + jinja_template = env.from_string(template_content) + else: + # load default template from package + env.loader = PackageLoader("commitizen", "templates") + jinja_template = env.get_template("keep_a_changelog_template.j2") + changelog: str = jinja_template.render(releases=releases) return changelog diff --git a/commitizen/cli.py b/commitizen/cli.py index a5c336f9fd..a4670c48a0 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -167,6 +167,7 @@ "name": "--file-name", "help": "file name of changelog (default: 'CHANGELOG.md')", }, + {"name": "--template", "help": "custom template to be used",}, { "name": "--unreleased-version", "help": ( diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 535632dfc0..7498172669 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -35,6 +35,9 @@ def __init__(self, config: BaseConfig, args): self.file_name = args.get("file_name") or self.config.settings.get( "changelog_file" ) + self.template = args.get("template") or self.config.settings.get( + "changelog_template" + ) self.incremental = args["incremental"] or self.config.settings.get( "changelog_incremental" ) @@ -114,7 +117,7 @@ def __call__(self): ) if self.change_type_order: tree = changelog.order_changelog_tree(tree, self.change_type_order) - changelog_out = changelog.render_changelog(tree) + changelog_out = changelog.render_changelog(tree, self.template) changelog_out = changelog_out.lstrip("\n") if self.dry_run: diff --git a/commitizen/templates/keep_a_changelog_template.j2 b/commitizen/templates/keep_a_changelog_template.j2 index de63880d66..4ce914dfa3 100644 --- a/commitizen/templates/keep_a_changelog_template.j2 +++ b/commitizen/templates/keep_a_changelog_template.j2 @@ -1,8 +1,8 @@ -{% for entry in tree %} +{% for release in releases %} -## {{ entry.version }}{% if entry.date %} ({{ entry.date }}){% endif %} +## {{ release.version }}{% if release.date %} ({{ release.date }}){% endif %} -{% for change_key, changes in entry.changes.items() %} +{% for change_key, changes in release.changes.items() %} {% if change_key %} ### {{ change_key }} diff --git a/docs/changelog.md b/docs/changelog.md index 41a5615d6c..54813a9a10 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,7 @@ This command will generate a changelog following the committing rules establishe ```bash $ cz changelog --help usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] + [--template TEMPLATE] [--unreleased-version UNRELEASED_VERSION] [--incremental] [--start-rev START_REV] @@ -15,6 +16,7 @@ optional arguments: --dry-run show changelog to stdout --file-name FILE_NAME file name of changelog (default: 'CHANGELOG.md') + --template TEMPLATE custom template to be used --unreleased-version UNRELEASED_VERSION set the value for the new version (use the tag value), instead of using unreleased @@ -112,6 +114,16 @@ Specify the name of the output file, remember that changelog only works with mar cz changelog --file-name="CHANGES.md" ``` +### `template` + +This value can be set in the `toml` file with the key `changelog_template` under `tools.commitizen` + +Specify a custom Jinja template to be used for the changelogs. Use the provided [default template](../commitizen/templates/keep_a_changelog_template.j2) as a reference for creating your own template. + +```bash +cz changelog --template="CHANGELOG.md.j2" +``` + ### `incremental` This flag can be set in the `toml` file with the key `changelog_incremental` under `tools.commitizen` From 8af61da05a4f531816f4b0dbe009024fc2c0b38e Mon Sep 17 00:00:00 2001 From: Andre Lehmann Date: Sun, 2 May 2021 22:37:53 +0200 Subject: [PATCH 2/3] test(changelog): add simple test for custom changelog template --- tests/test_changelog.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 055e4fc916..15383bad09 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -848,6 +848,14 @@ def test_render_changelog(gitcommits, tags, changelog_content): ) result = changelog.render_changelog(tree) assert result == changelog_content + # test with 'custom' template + tree = changelog.generate_tree_from_commits( + gitcommits, tags, parser, changelog_pattern + ) + result = changelog.render_changelog( + tree, "commitizen/templates/keep_a_changelog_template.j2" + ) + assert result == changelog_content def test_render_changelog_unreleased(gitcommits): From b246e846eaf47cfe363de1ed62b0dac0c3b87c7e Mon Sep 17 00:00:00 2001 From: Andre Lehmann Date: Mon, 3 May 2021 10:39:28 +0200 Subject: [PATCH 3/3] fix(bump): use configured changelog_incremental value when calling `cz bump --changelog` When using custom templates that include a header for example, then generating the changelog incrementally won't yield the desired result. Therefore the option changelog_incremental should also be honored when using `bump --changelog` to generate the new changelog. --- commitizen/commands/bump.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 4f2a0d3981..942f98bdf1 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -46,6 +46,9 @@ def __init__(self, config: BaseConfig, arguments: dict): self.changelog = arguments["changelog"] or self.config.settings.get( "update_changelog_on_bump" ) + self.changelog_incremental = self.config.settings.get( + "changelog_incremental", False + ) self.changelog_to_stdout = arguments["changelog_to_stdout"] self.no_verify = arguments["no_verify"] self.check_consistency = arguments["check_consistency"] @@ -189,7 +192,7 @@ def __call__(self): # noqa: C901 self.config, { "unreleased_version": new_tag_version, - "incremental": True, + "incremental": self.changelog_incremental, "dry_run": True, }, ) @@ -201,7 +204,7 @@ def __call__(self): # noqa: C901 self.config, { "unreleased_version": new_tag_version, - "incremental": True, + "incremental": self.changelog_incremental, "dry_run": dry_run, }, )