Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6e8e37e

Browse files
noirbizarreEmilMagenta
authored andcommitted
feat(template): allow to override the template from cli, configuration and plugins
Fixes commitizen-tools#132 Fixes commitizen-tools#384 Fixes commitizen-tools#433 Closes commitizen-tools#376 Closes commitizen-tools#640
1 parent 8e2b6ff commit 6e8e37e

File tree

15 files changed

+614
-112
lines changed

15 files changed

+614
-112
lines changed

‎commitizen/changelog.py‎

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@
3232
from datetime import date
3333
from typing import TYPE_CHECKING, Callable, Iterable, Type, cast
3434

35-
from jinja2 import Environment, PackageLoader
35+
from jinja2 import (
36+
BaseLoader,
37+
ChoiceLoader,
38+
Environment,
39+
FileSystemLoader,
40+
PackageLoader,
41+
)
42+
from packaging.version import InvalidVersion
3643

3744
from commitizen import out
3845
from commitizen.bump import normalize_tag
@@ -49,6 +56,8 @@
4956
if TYPE_CHECKING:
5057
from commitizen.version_schemes import VersionScheme
5158

59+
DEFAULT_TEMPLATE = "keep_a_changelog_template.j2"
60+
5261

5362
def get_commit_tag(commit: GitCommit, tags: list[GitTag]) -> GitTag | None:
5463
return next((tag for tag in tags if tag.rev == commit.rev), None)
@@ -187,11 +196,18 @@ def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterab
187196
return sorted_tree
188197

189198

190-
def render_changelog(tree: Iterable) -> str:
191-
loader = PackageLoader("commitizen", "templates")
199+
def render_changelog(
200+
tree: Iterable,
201+
loader: BaseLoader | None = None,
202+
template: str | None = None,
203+
**kwargs,
204+
) -> str:
205+
loader = ChoiceLoader(
206+
[FileSystemLoader("."), loader or PackageLoader("commitizen", "templates")]
207+
)
192208
env = Environment(loader=loader, trim_blocks=True)
193-
jinja_template = env.get_template("keep_a_changelog_template.j2")
194-
changelog: str = jinja_template.render(tree=tree)
209+
jinja_template = env.get_template(templateorDEFAULT_TEMPLATE)
210+
changelog: str = jinja_template.render(tree=tree, **kwargs)
195211
return changelog
196212

197213

‎commitizen/cli.py‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import argparse
44
import logging
55
import sys
6+
from copy import deepcopy
67
from functools import partial
78
from pathlib import Path
89
from types import TracebackType
@@ -19,6 +20,51 @@
1920
)
2021

2122
logger = logging.getLogger(__name__)
23+
24+
25+
class ParseKwargs(argparse.Action):
26+
"""
27+
Parse arguments in the for `key=value`.
28+
29+
Quoted strings are automatically unquoted.
30+
Can be submitted multiple times:
31+
32+
ex:
33+
-k key=value -k double-quotes="value" -k single-quotes='value'
34+
35+
will result in
36+
37+
namespace["opt"] == {
38+
"key": "value",
39+
"double-quotes": "value",
40+
"single-quotes": "value",
41+
}
42+
"""
43+
44+
def __call__(self, parser, namespace, kwarg, option_string=None):
45+
kwargs = getattr(namespace, self.dest, None) or {}
46+
key, value = kwarg.split("=", 1)
47+
kwargs[key] = value.strip("'\"")
48+
setattr(namespace, self.dest, kwargs)
49+
50+
51+
tpl_arguments = (
52+
{
53+
"name": ["--template", "-t"],
54+
"help": (
55+
"changelog template file name "
56+
"(relative to the current working directory)"
57+
),
58+
},
59+
{
60+
"name": ["--extra", "-e"],
61+
"action": ParseKwargs,
62+
"dest": "extras",
63+
"metavar": "EXTRA",
64+
"help": "a changelog extra variable (in the form 'key=value')",
65+
},
66+
)
67+
2268
data = {
2369
"prog": "cz",
2470
"description": (
@@ -204,6 +250,7 @@
204250
"default": None,
205251
"help": "keep major version at zero, even for breaking changes",
206252
},
253+
*deepcopy(tpl_arguments),
207254
{
208255
"name": ["--prerelease-offset"],
209256
"type": int,
@@ -293,6 +340,7 @@
293340
"default": None,
294341
"choices": version_schemes.KNOWN_SCHEMES,
295342
},
343+
*deepcopy(tpl_arguments),
296344
],
297345
},
298346
{

‎commitizen/commands/bump.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def __init__(self, config: BaseConfig, arguments: dict):
5151
"annotated_tag",
5252
"major_version_zero",
5353
"prerelease_offset",
54+
"template",
5455
]
5556
if arguments[key] is not None
5657
},
@@ -77,6 +78,8 @@ def __init__(self, config: BaseConfig, arguments: dict):
7778
self.scheme = get_version_scheme(
7879
self.config, arguments["version_scheme"] or deprecated_version_type
7980
)
81+
self.template = arguments["template"] or self.config.settings.get("template")
82+
self.extras = arguments["extras"]
8083

8184
def is_initial_tag(self, current_tag_version: str, is_yes: bool = False) -> bool:
8285
"""Check if reading the whole git tree up to HEAD is needed."""
@@ -275,6 +278,8 @@ def __call__(self): # noqa: C901
275278
"unreleased_version": new_tag_version,
276279
"incremental": True,
277280
"dry_run": dry_run,
281+
"template": self.template,
282+
"extras": self.extras,
278283
},
279284
)
280285
changelog_cmd()

‎commitizen/commands/changelog.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ def __init__(self, config: BaseConfig, args):
6565
"merge_prerelease"
6666
) or self.config.settings.get("changelog_merge_prerelease")
6767

68+
self.template = args.get("template") or self.config.settings.get("template")
69+
self.extras = args.get("extras") or {}
70+
6871
def _find_incremental_rev(self, latest_version: str, tags: list[GitTag]) -> str:
6972
"""Try to find the 'start_rev'.
7073
@@ -183,7 +186,13 @@ def __call__(self):
183186
)
184187
if self.change_type_order:
185188
tree = changelog.order_changelog_tree(tree, self.change_type_order)
186-
changelog_out = changelog.render_changelog(tree)
189+
190+
extras = self.cz.template_extras.copy()
191+
extras.update(self.config.settings["extras"])
192+
extras.update(self.extras)
193+
changelog_out = changelog.render_changelog(
194+
tree, loader=self.cz.template_loader, template=self.template, **extras
195+
)
187196
changelog_out = changelog_out.lstrip("\n")
188197

189198
if self.dry_run:

‎commitizen/cz/base.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from __future__ import annotations
22

33
from abc import ABCMeta, abstractmethod
4-
from typing import Callable
4+
from typing import Any, Callable
55

6+
from jinja2 import BaseLoader
67
from prompt_toolkit.styles import Style, merge_styles
78

89
from commitizen import git
10+
from commitizen.changelog import DEFAULT_TEMPLATE
911
from commitizen.config.base_config import BaseConfig
1012
from commitizen.defaults import Questions
1113

@@ -43,6 +45,10 @@ class BaseCommitizen(metaclass=ABCMeta):
4345
# Executed only at the end of the changelog generation
4446
changelog_hook: Callable[[str, str | None], str] | None = None
4547

48+
template: str = DEFAULT_TEMPLATE
49+
template_loader: BaseLoader | None = None
50+
template_extras: dict[str, Any] = {}
51+
4652
def __init__(self, config: BaseConfig):
4753
self.config = config
4854
if not self.config.settings.get("style"):

‎commitizen/defaults.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Settings(TypedDict, total=False):
5656
post_bump_hooks: list[str] | None
5757
prerelease_offset: int
5858
encoding: str
59+
template: str | None
60+
extras: dict[str, Any]
5961

6062

6163
name: str = "cz_conventional_commits"
@@ -96,6 +98,8 @@ class Settings(TypedDict, total=False):
9698
"post_bump_hooks": [],
9799
"prerelease_offset": 0,
98100
"encoding": encoding,
101+
"template": None,
102+
"extras": {},
99103
}
100104

101105
MAJOR = "MAJOR"

‎docs/bump.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog]
5858
[--devrelease DEVRELEASE] [--increment {MAJOR,MINOR,PATCH}]
5959
[--check-consistency] [--annotated-tag] [--gpg-sign]
6060
[--changelog-to-stdout] [--git-output-to-stderr] [--retry] [--major-version-zero]
61+
[--template TEMPLATE] [--extra EXTRA]
6162
[MANUAL_VERSION]
6263

6364
positional arguments:
@@ -99,6 +100,10 @@ options:
99100
--version-scheme {pep440,semver}
100101
choose version scheme
101102

103+
--template TEMPLATE, -t TEMPLATE
104+
changelog template file name (relative to the current working directory)
105+
--extra EXTRA, -e EXTRA
106+
a changelog extra variable (in the form 'key=value')
102107
```
103108
104109
### `--files-only`
@@ -250,6 +255,21 @@ Can I transition from one to the other?
250255
251256
Yes, you shouldn't have any issues.
252257
258+
### `--template`
259+
260+
Provides your own changelog jinja template.
261+
See [the template customization section](customization.md#customizing-the-changelog-template)
262+
263+
### `--extra`
264+
265+
Provides your own changelog extra variables by using the `extras` settings or the `--extra/-e` parameter.
266+
267+
```bash
268+
cz bump --changelog --extra key=value -e short="quoted value"
269+
```
270+
271+
See [the template customization section](customization.md#customizing-the-changelog-template).
272+
253273
## Avoid raising errors
254274
255275
Some situations from commitizen raise an exit code different than 0.

‎docs/changelog.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ update_changelog_on_bump = true
1414
```bash
1515
$ cz changelog --help
1616
usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] [--unreleased-version UNRELEASED_VERSION] [--incremental] [--start-rev START_REV]
17+
[--template TEMPLATE] [--extra EXTRA]
1718
[rev_range]
1819

1920
positional arguments:
@@ -31,6 +32,11 @@ optional arguments:
3132
start rev of the changelog. If not set, it will generate changelog from the start
3233
--merge-prerelease
3334
collect all changes from prereleases into next non-prerelease. If not set, it will include prereleases in the changelog
35+
start rev of the changelog.If not set, it will generate changelog from the start
36+
--template TEMPLATE, -t TEMPLATE
37+
changelog template file name (relative to the current working directory)
38+
--extra EXTRA, -e EXTRA
39+
a changelog extra variable (in the form 'key=value')
3440
```
3541
3642
### Examples
@@ -186,6 +192,21 @@ cz changelog --merge-prerelease
186192
changelog_merge_prerelease = true
187193
```
188194
195+
### `template`
196+
197+
Provides your own changelog jinja template by using the `template` settings or the `--template` parameter.
198+
See [the template customization section](customization.md#customizing-the-changelog-template)
199+
200+
### `extras`
201+
202+
Provides your own changelog extra variables by using the `extras` settings or the `--extra/-e` parameter.
203+
204+
```bash
205+
cz changelog --extra key=value -e short="quoted value"
206+
```
207+
208+
See [the template customization section](customization.md#customizing-the-changelog-template)
209+
189210
## Hooks
190211
191212
Supported hook methods:

‎docs/config.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,22 @@ Default: `utf-8`
192192

193193
Sets the character encoding to be used when parsing commit messages. [Read more][encoding]
194194

195+
### `template`
196+
197+
Type: `str`
198+
199+
Default: `None` (provided by plugin)
200+
201+
Provide custom changelog jinja template path relative to the current working directory. [Read more][template-customization]
202+
203+
### `extras`
204+
205+
Type: `dict[str, Any]`
206+
207+
Default: `{}`
208+
209+
Provide extra variables to the changelog template. [Read more][template-customization] |
210+
195211
## Configuration file
196212

197213
### pyproject.toml or .cz.toml
@@ -364,5 +380,6 @@ setup(
364380
[additional-features]: https://github.com/tmbo/questionary#additional-features
365381
[customization]: customization.md
366382
[shortcuts]: customization.md#shortcut-keys
383+
[template-customization]: customization.md#customizing-the-changelog-template
367384
[annotated-tags-vs-lightweight]: https://stackoverflow.com/a/11514139/2047185
368385
[encoding]: tutorials/writing_commits.md#writing-commits

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /