Skip to content
Merged
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
10 changes: 8 additions & 2 deletions commitizen/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import re
from collections import defaultdict
from datetime import date
from typing import Dict, Iterable, List, Optional
from typing import Callable, Dict, Iterable, List, Optional

import pkg_resources
from jinja2 import Template
Expand Down Expand Up @@ -72,6 +72,8 @@ def generate_tree_from_commits(
commit_parser: str,
changelog_pattern: str = defaults.bump_pattern,
unreleased_version: Optional[str] = None,
change_type_map: Optional[Dict[str, str]] = None,
changelog_message_builder_hook: Optional[Callable] = None,
) -> Iterable[Dict]:
pat = re.compile(changelog_pattern)
map_pat = re.compile(commit_parser)
Expand Down Expand Up @@ -112,10 +114,14 @@ def generate_tree_from_commits(
message = map_pat.match(commit.message)
message_body = map_pat.match(commit.body)
if message:
# TODO: add a post hook coming from a rule (CzBase)
parsed_message: Dict = message.groupdict()
# change_type becomes optional by providing None
change_type = parsed_message.pop("change_type", None)

if change_type_map:
change_type = change_type_map.get(change_type, change_type)
if changelog_message_builder_hook:
parsed_message = changelog_message_builder_hook(parsed_message, commit)
changes[change_type].append(parsed_message)
if message_body:
parsed_message_body: Dict = message_body.groupdict()
Expand Down
28 changes: 23 additions & 5 deletions commitizen/commands/changelog.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os.path
from difflib import SequenceMatcher
from operator import itemgetter
from typing import Dict, List
from typing import Callable, Dict, List, Optional

from commitizen import changelog, factory, git, out
from commitizen.config import BaseConfig
Expand All @@ -27,6 +27,9 @@ def __init__(self, config: BaseConfig, args):
self.incremental = args["incremental"]
self.dry_run = args["dry_run"]
self.unreleased_version = args["unreleased_version"]
self.change_type_map = (
self.config.settings.get("change_type_map") or self.cz.change_type_map
)

def _find_incremental_rev(self, latest_version: str, tags: List[GitTag]) -> str:
"""Try to find the 'start_rev'.
Expand Down Expand Up @@ -60,6 +63,11 @@ def __call__(self):
start_rev = self.start_rev
unreleased_version = self.unreleased_version
changelog_meta: Dict = {}
change_type_map: Optional[Dict] = self.change_type_map
changelog_message_builder_hook: Optional[
Callable
] = self.cz.changelog_message_builder_hook
changelog_hook: Optional[Callable] = self.cz.changelog_hook

if not changelog_pattern or not commit_parser:
out.error(
Expand All @@ -83,7 +91,13 @@ def __call__(self):
raise SystemExit(NO_COMMITS_FOUND)

tree = changelog.generate_tree_from_commits(
commits, tags, commit_parser, changelog_pattern, unreleased_version
commits,
tags,
commit_parser,
changelog_pattern,
unreleased_version,
change_type_map=change_type_map,
changelog_message_builder_hook=changelog_message_builder_hook,
)
changelog_out = changelog.render_changelog(tree)

Expand All @@ -97,10 +111,14 @@ def __call__(self):
lines = changelog_file.readlines()

with open(self.file_name, "w") as changelog_file:
partial_changelog: Optional[str] = None
if self.incremental:
new_lines = changelog.incremental_build(
changelog_out, lines, changelog_meta
)
changelog_file.writelines(new_lines)
else:
changelog_file.write(changelog_out)
changelog_out = "".join(new_lines)
partial_changelog = changelog_out

if changelog_hook:
changelog_out = changelog_hook(changelog_out, partial_changelog)
changelog_file.write(changelog_out)
4 changes: 2 additions & 2 deletions commitizen/commands/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ def __call__(self):
if version:
out.write(f"{version}")
else:
out.error(f"No project information in this project.")
out.error("No project information in this project.")
elif self.parameter.get("verbose"):
out.write(f"Installed Commitizen Version: {__version__}")
version = self.config.settings["version"]
if version:
out.write(f"Project Version: {version}")
else:
out.error(f"No project information in this project.")
out.error("No project information in this project.")
else:
# if no argument is given, show installed commitizen version
out.write(f"{__version__}")
13 changes: 11 additions & 2 deletions commitizen/cz/base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from abc import ABCMeta, abstractmethod
from typing import List, Optional, Tuple
from typing import Callable, Dict, List, Optional, Tuple

from prompt_toolkit.styles import Style, merge_styles

from commitizen import git
from commitizen.config.base_config import BaseConfig


Expand All @@ -27,7 +28,15 @@ class BaseCommitizen(metaclass=ABCMeta):
# It can be modified per rule
commit_parser: Optional[str] = r"(?P<message>.*)"
changelog_pattern: Optional[str] = r".*"
changelog_map: Optional[dict] = None # TODO: Use it
change_type_map: Optional[Dict[str, str]] = None

# Executed per message parsed by the commitizen
changelog_message_builder_hook: Optional[
Callable[[Dict, git.GitCommit], Dict]
] = None

# Executed only at the end of the changelog generation
changelog_hook: Optional[Callable[[str, Optional[str]], str]] = None

def __init__(self, config: BaseConfig):
self.config = config
Expand Down
6 changes: 6 additions & 0 deletions commitizen/cz/conventional_commits/conventional_commits.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class ConventionalCommitsCz(BaseCommitizen):
bump_map = defaults.bump_map
commit_parser = defaults.commit_parser
changelog_pattern = defaults.bump_pattern
change_type_map = {
"feat": "Feat",
"fix": "Fix",
"refactor": "Refactor",
"perf": "Perf",
}

def questions(self) -> List[Dict[str, Any]]:
questions: List[Dict[str, Any]] = [
Expand Down
2 changes: 1 addition & 1 deletion commitizen/templates/keep_a_changelog_template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{% for change_key, changes in entry.changes.items() %}

{% if change_key %}
### {{ change_key|title }}
### {{ change_key }}
{% endif %}

{% for change in changes %}
Expand Down
11 changes: 8 additions & 3 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,15 @@ Benefits:
cz changelog --incremental
```

## TODO
## Hooks

- [ ] support for hooks: this would allow introduction of custom information in the commiter, like a github or jira url. Eventually we could build a `CzConventionalGithub`, which would add links to commits
- [ ] support for map: allow the usage of a `change_type` mapper, to convert from feat to feature for example.
Supported hook methods:

- per parsed message: useful to add links
- end of changelog generation: useful to send slack or chat message, or notify another department

Read more about hooks in the [customization page][customization]

[keepachangelog]: https://keepachangelog.com/
[semver]: https://semver.org/
[customization]: ./customization.md
Loading