From 5f607f3d090bbc9291cce4ca3fec6bd1618ac2d5 Mon Sep 17 00:00:00 2001 From: baluyotraf Date: Tue, 6 May 2025 15:42:35 +0200 Subject: [PATCH 1/7] Revert removal of escape in toml --- docs/tutorials/monorepo_guidance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index e530c596c..792c8c224 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -71,7 +71,7 @@ Example config and commit for `library-b`: ```toml [tool.commitizen.customize] -changelog_pattern = "^(feat|fix)\(library-b\)(!)?:" #the pattern on types can be a wild card or any types you wish to include +changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include ``` A commit message looking like this, would be included: From c991feaf07370e635e38cd713d59da06eb19aba1 Mon Sep 17 00:00:00 2001 From: name Date: Tue, 8 Apr 2025 02:19:34 +0800 Subject: [PATCH 2/7] docs(customization.md): add select type and search filter documentation --- docs/customization.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index da41071b9..31749d1c8 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -170,13 +170,15 @@ commitizen: | Parameter | Type | Default | Description | | ----------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | `str` | `None` | The type of questions. Valid type: `list`, `input` and etc. [See More][different-question-types] | +| `type` | `str` | `None` | The type of questions. Valid types: `list`, `select`, `input` and etc. The `select` type provides an interactive searchable list interface. [See More][different-question-types] | | `name` | `str` | `None` | The key for the value answered by user. It's used in `message_template` | | `message` | `str` | `None` | Detail description for the question. | -| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | +| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list` or `type = select`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | | `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | | `filter` | `str` | `None` | (OPTIONAL) Validator for user's answer. **(Work in Progress)** | -| `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | +| `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | +| `use_search_filter` | `bool` | `False` | (OPTIONAL) Enable search/filter functionality for list/select type questions. This allows users to type and filter through the choices. | +| `use_jk_keys` | `bool` | `True` | (OPTIONAL) Enable/disable j/k keys for navigation in list/select type questions. Set to false if you prefer arrow keys only. | [different-question-types]: https://github.com/tmbo/questionary#different-question-types @@ -445,8 +447,8 @@ Commitizen gives you the possibility to provide your own changelog template, by: - providing one with your customization class - providing one from the current working directory and setting it: - - as [configuration][template-config] - - as `--template` parameter to both `bump` and `changelog` commands + - as [configuration][template-config] + - as `--template` parameter to both `bump` and `changelog` commands - either by providing a template with the same name as the default template By default, the template used is the `CHANGELOG.md.j2` file from the commitizen repository. From 5be28470ecf803c5092794201810ef89f54b9f87 Mon Sep 17 00:00:00 2001 From: yusin huang Date: Mon, 14 Apr 2025 10:11:42 +0800 Subject: [PATCH 3/7] test(test_cz_search_filter.py): add test cases for search filter configuration --- tests/test_cz_search_filter.py | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 tests/test_cz_search_filter.py diff --git a/tests/test_cz_search_filter.py b/tests/test_cz_search_filter.py new file mode 100644 index 000000000..0e70e3104 --- /dev/null +++ b/tests/test_cz_search_filter.py @@ -0,0 +1,76 @@ +import pytest + +from commitizen.config import TomlConfig +from commitizen.cz.customize import CustomizeCommitsCz + +TOML_WITH_SEARCH_FILTER = r""" +[tool.commitizen] +name = "cz_customize" + +[tool.commitizen.customize] +message_template = "{{change_type}}:{% if scope %} ({{scope}}){% endif %}{% if breaking %}!{% endif %} {{message}}" + +[[tool.commitizen.customize.questions]] +type = "select" +name = "change_type" +message = "Select the type of change you are committing" +use_search_filter = true +use_jk_keys = false +choices = [ + {value = "fix", name = "fix: A bug fix. Correlates with PATCH in SemVer"}, + {value = "feat", name = "feat: A new feature. Correlates with MINOR in SemVer"}, + {value = "docs", name = "docs: Documentation only changes"}, + {value = "style", name = "style: Changes that do not affect the meaning of the code"}, + {value = "refactor", name = "refactor: A code change that neither fixes a bug nor adds a feature"}, + {value = "perf", name = "perf: A code change that improves performance"}, + {value = "test", name = "test: Adding missing or correcting existing tests"}, + {value = "build", name = "build: Changes that affect the build system or external dependencies"}, + {value = "ci", name = "ci: Changes to CI configuration files and scripts"} +] + +[[tool.commitizen.customize.questions]] +type = "input" +name = "scope" +message = "What is the scope of this change? (class or file name): (press [enter] to skip)" + +[[tool.commitizen.customize.questions]] +type = "input" +name = "message" +message = "Write a short and imperative summary of the code changes: (lower case and no period)" +""" + + +@pytest.fixture +def config(): + return TomlConfig(data=TOML_WITH_SEARCH_FILTER, path="not_exist.toml") + + +def test_questions_with_search_filter(config): + """Test that questions are properly configured with search filter""" + cz = CustomizeCommitsCz(config) + questions = cz.questions() + + # Test that the first question (change_type) has search filter enabled + assert questions[0]["type"] == "select" + assert questions[0]["name"] == "change_type" + assert questions[0]["use_search_filter"] is True + assert questions[0]["use_jk_keys"] is False + + # Test that the choices are properly configured + choices = questions[0]["choices"] + assert len(choices) == 9 # We have 9 commit types + assert choices[0]["value"] == "fix" + assert choices[1]["value"] == "feat" + + +def test_message_template(config): + """Test that the message template is properly configured""" + cz = CustomizeCommitsCz(config) + template = cz.message( + { + "change_type": "feat", + "scope": "search", + "message": "add search filter support", + } + ) + assert template == "feat: (search) add search filter support" From 776d70f700752789a42b31864807c389337e314f Mon Sep 17 00:00:00 2001 From: Yusin Huang Date: Tue, 15 Apr 2025 23:00:50 +0800 Subject: [PATCH 4/7] fix(changelog.py): modify the CHANGELOG.md generated by cz bump --changelog to the right place --- commitizen/commands/changelog.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 80a72651e..71bc93265 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -32,21 +32,28 @@ def __init__(self, config: BaseConfig, args): raise NotAGitProjectError() self.config: BaseConfig = config - self.encoding = self.config.settings["encoding"] - self.cz = factory.commiter_factory(self.config) - - self.start_rev = args.get("start_rev") or self.config.settings.get( - "changelog_start_rev" - ) - self.file_name = args.get("file_name") or cast( + changelog_file_name = args.get("file_name") or cast( str, self.config.settings.get("changelog_file") ) - if not isinstance(self.file_name, str): + if not isinstance(changelog_file_name, str): raise NotAllowed( "Changelog file name is broken.\n" "Check the flag `--file-name` in the terminal " f"or the setting `changelog_file` in {self.config.path}" ) + self.file_name = ( + str(Path(self.config.path.parent) / changelog_file_name) + if self.config.path is not None + else changelog_file_name + ) + + self.encoding = self.config.settings["encoding"] + self.cz = factory.commiter_factory(self.config) + + self.start_rev = args.get("start_rev") or self.config.settings.get( + "changelog_start_rev" + ) + self.changelog_format = get_changelog_format(self.config, self.file_name) self.incremental = args["incremental"] or self.config.settings.get( From 15c185709ea2dba6a850f1b19c9a3790d4e92f50 Mon Sep 17 00:00:00 2001 From: Yusin Huang Date: Tue, 15 Apr 2025 23:01:40 +0800 Subject: [PATCH 5/7] test(test_changelog_command.py): add test for changelog file_name construction from args and config --- tests/test_changelog.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index df42b8226..6ffb6bc29 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,13 +1,18 @@ +from __future__ import annotations + import re from dataclasses import dataclass from pathlib import Path -from typing import Any, Optional +from typing import Any +from unittest.mock import Mock import pytest from jinja2 import FileSystemLoader from commitizen import changelog, git from commitizen.changelog_formats import ChangelogFormat +from commitizen.commands.changelog import Changelog +from commitizen.config import BaseConfig from commitizen.cz.conventional_commits.conventional_commits import ( ConventionalCommitsCz, ) @@ -1499,7 +1504,7 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): def test_render_changelog_with_changelog_release_hook( gitcommits, tags, any_changelog_format: ChangelogFormat ): - def changelog_release_hook(release: dict, tag: Optional[git.GitTag]) -> dict: + def changelog_release_hook(release: dict, tag: git.GitTag | None) -> dict: release["extra"] = "whatever" return release @@ -1631,3 +1636,32 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): captured = capsys.readouterr() assert captured.err.count("InvalidVersion") == 2 assert captured.err.count("not-a-version") == 2 + + +def test_changelog_file_name_from_args_and_config(): + mock_config = Mock(spec=BaseConfig) + mock_config.path.parent = "/my/project/" + mock_config.settings = { + "name": "cz_conventional_commits", + "changelog_file": "CHANGELOG.md", + "encoding": "utf-8", + "changelog_start_rev": "v1.0.0", + "tag_format": "$version", + "legacy_tag_formats": [], + "ignored_tag_formats": [], + "incremental": True, + "changelog_merge_prerelease": True, + } + + args = { + "file_name": "CUSTOM.md", + "incremental": None, + "dry_run": False, + "unreleased_version": "1.0.1", + } + changelog = Changelog(mock_config, args) + assert changelog.file_name == "/my/project/CUSTOM.md" + + args = {"incremental": None, "dry_run": False, "unreleased_version": "1.0.1"} + changelog = Changelog(mock_config, args) + assert changelog.file_name == "/my/project/CHANGELOG.md" From 7bea5a5082fe0fafc1e62515a9868095bb96fa4c Mon Sep 17 00:00:00 2001 From: Yusin Huang Date: Thu, 17 Apr 2025 01:02:27 +0800 Subject: [PATCH 6/7] fix(changelog.py): cross-platform path handling using os.path.join and modify the path linter and test parameter --- commitizen/commands/changelog.py | 3 ++- tests/test_changelog.py | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 71bc93265..3b8f43e37 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import os.path from difflib import SequenceMatcher from operator import itemgetter @@ -42,7 +43,7 @@ def __init__(self, config: BaseConfig, args): f"or the setting `changelog_file` in {self.config.path}" ) self.file_name = ( - str(Path(self.config.path.parent) / changelog_file_name) + os.path.join(str(self.config.path.parent), changelog_file_name) if self.config.path is not None else changelog_file_name ) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 6ffb6bc29..67ba273b5 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import re from dataclasses import dataclass from pathlib import Path @@ -1640,7 +1641,7 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): def test_changelog_file_name_from_args_and_config(): mock_config = Mock(spec=BaseConfig) - mock_config.path.parent = "/my/project/" + mock_config.path.parent = "/my/project" mock_config.settings = { "name": "cz_conventional_commits", "changelog_file": "CHANGELOG.md", @@ -1660,8 +1661,12 @@ def test_changelog_file_name_from_args_and_config(): "unreleased_version": "1.0.1", } changelog = Changelog(mock_config, args) - assert changelog.file_name == "/my/project/CUSTOM.md" + assert os.path.normpath(changelog.file_name) == os.path.normpath( + os.path.join("/my/project", "CUSTOM.md") + ) args = {"incremental": None, "dry_run": False, "unreleased_version": "1.0.1"} changelog = Changelog(mock_config, args) - assert changelog.file_name == "/my/project/CHANGELOG.md" + assert os.path.normpath(changelog.file_name) == os.path.normpath( + os.path.join("/my/project", "CHANGELOG.md") + ) From e177141ec11f6bf72a6661c6a9fabebe3b670251 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 7 May 2025 00:43:53 +0000 Subject: [PATCH 7/7] =?UTF-8?q?bump:=20version=204.6.2=20=E2=86=92=204.6.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ac8b99626..08c31ba0a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.2 # automatically updated by Commitizen + rev: v4.6.3 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index def8dab18..dbad46395 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v4.6.3 (2025-05-07) + +### Fix + +- **changelog.py**: cross-platform path handling using os.path.join and modify the path linter and test parameter +- **changelog.py**: modify the CHANGELOG.md generated by cz bump --changelog to the right place + ## v4.6.2 (2025-05-05) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 456bc7c31..de3842dc7 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.2" +__version__ = "4.6.3" diff --git a/pyproject.toml b/pyproject.toml index 43bed32b5..92b28fd09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.2" +version = "4.6.3" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.2" +version = "4.6.3" tag_format = "v$version" version_files = [ "pyproject.toml:version",