Adding upstream version 4.6.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
167a3f8553
commit
bdd390b4cf
16 changed files with 174 additions and 31 deletions
2
.github/workflows/pythonpackage.yml
vendored
2
.github/workflows/pythonpackage.yml
vendored
|
@ -7,7 +7,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||||
platform: [ubuntu-20.04, macos-latest, windows-latest]
|
platform: [ubuntu-22.04, macos-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
@ -48,7 +48,7 @@ repos:
|
||||||
- tomli
|
- tomli
|
||||||
|
|
||||||
- repo: https://github.com/commitizen-tools/commitizen
|
- repo: https://github.com/commitizen-tools/commitizen
|
||||||
rev: v4.6.0 # automatically updated by Commitizen
|
rev: v4.6.3 # automatically updated by Commitizen
|
||||||
hooks:
|
hooks:
|
||||||
- id: commitizen
|
- id: commitizen
|
||||||
- id: commitizen-branch
|
- id: commitizen-branch
|
||||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -1,3 +1,22 @@
|
||||||
|
## 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
|
||||||
|
|
||||||
|
- **docs**: fix url link and table formatting in the customization docs (#1399)
|
||||||
|
|
||||||
|
## v4.6.1 (2025-05-05)
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- **commit**: use os.unlink to remove temp file
|
||||||
|
|
||||||
## v4.6.0 (2025-04-13)
|
## v4.6.0 (2025-04-13)
|
||||||
|
|
||||||
### Feat
|
### Feat
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "4.6.0"
|
__version__ = "4.6.3"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
@ -32,21 +33,28 @@ class Changelog:
|
||||||
raise NotAGitProjectError()
|
raise NotAGitProjectError()
|
||||||
|
|
||||||
self.config: BaseConfig = config
|
self.config: BaseConfig = config
|
||||||
|
changelog_file_name = args.get("file_name") or cast(
|
||||||
|
str, self.config.settings.get("changelog_file")
|
||||||
|
)
|
||||||
|
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 = (
|
||||||
|
os.path.join(str(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.encoding = self.config.settings["encoding"]
|
||||||
self.cz = factory.commiter_factory(self.config)
|
self.cz = factory.commiter_factory(self.config)
|
||||||
|
|
||||||
self.start_rev = args.get("start_rev") or self.config.settings.get(
|
self.start_rev = args.get("start_rev") or self.config.settings.get(
|
||||||
"changelog_start_rev"
|
"changelog_start_rev"
|
||||||
)
|
)
|
||||||
self.file_name = args.get("file_name") or cast(
|
|
||||||
str, self.config.settings.get("changelog_file")
|
|
||||||
)
|
|
||||||
if not isinstance(self.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.changelog_format = get_changelog_format(self.config, self.file_name)
|
self.changelog_format = get_changelog_format(self.config, self.file_name)
|
||||||
|
|
||||||
self.incremental = args["incremental"] or self.config.settings.get(
|
self.incremental = args["incremental"] or self.config.settings.get(
|
||||||
|
|
|
@ -89,7 +89,7 @@ class Commit:
|
||||||
subprocess.call(argv)
|
subprocess.call(argv)
|
||||||
with open(file_path) as temp_file:
|
with open(file_path) as temp_file:
|
||||||
message = temp_file.read().strip()
|
message = temp_file.read().strip()
|
||||||
file.unlink()
|
os.unlink(file.name)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
|
|
|
@ -164,19 +164,22 @@ commitizen:
|
||||||
| `change_type_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the type of the commit to a changelog entry |
|
| `change_type_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the type of the commit to a changelog entry |
|
||||||
|
|
||||||
[jinja2]: https://jinja.palletsprojects.com/en/2.10.x/
|
[jinja2]: https://jinja.palletsprojects.com/en/2.10.x/
|
||||||
[changelog-spec]: https://commitizen-tools.github.io/commitizen/changelog/
|
[changelog-spec]: https://commitizen-tools.github.io/commitizen/commands/changelog/
|
||||||
|
|
||||||
#### Detailed `questions` content
|
#### Detailed `questions` content
|
||||||
|
|
||||||
| Parameter | Type | Default | Description |
|
| 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` |
|
| `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. |
|
| `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. |
|
| `default` | `Any` | `None` | (OPTIONAL) The default value for this question. |
|
||||||
| `filter` | `str` | `None` | (OPTIONAL) Validator for user's answer. **(Work in Progress)** |
|
| `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
|
[different-question-types]: https://github.com/tmbo/questionary#different-question-types
|
||||||
|
|
||||||
#### Shortcut keys
|
#### Shortcut keys
|
||||||
|
@ -444,8 +447,8 @@ Commitizen gives you the possibility to provide your own changelog template, by:
|
||||||
|
|
||||||
- providing one with your customization class
|
- providing one with your customization class
|
||||||
- providing one from the current working directory and setting it:
|
- providing one from the current working directory and setting it:
|
||||||
- as [configuration][template-config]
|
- as [configuration][template-config]
|
||||||
- as `--template` parameter to both `bump` and `changelog` commands
|
- as `--template` parameter to both `bump` and `changelog` commands
|
||||||
- either by providing a template with the same name as the default template
|
- 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.
|
By default, the template used is the `CHANGELOG.md.j2` file from the commitizen repository.
|
||||||
|
|
BIN
docs/images/bump.gif
Normal file
BIN
docs/images/bump.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
BIN
docs/images/demo.gif
Normal file
BIN
docs/images/demo.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
docs/images/init.gif
Normal file
BIN
docs/images/init.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 131 KiB |
|
@ -77,5 +77,5 @@ changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can
|
||||||
A commit message looking like this, would be included:
|
A commit message looking like this, would be included:
|
||||||
|
|
||||||
```
|
```
|
||||||
fix:(library-b) Some awesome message
|
fix(library-b): Some awesome message
|
||||||
```
|
```
|
||||||
|
|
8
poetry.lock
generated
8
poetry.lock
generated
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argcomplete"
|
name = "argcomplete"
|
||||||
version = "3.5.3"
|
version = "3.6.2"
|
||||||
description = "Bash tab completion for argparse"
|
description = "Bash tab completion for argparse"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"},
|
{file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"},
|
||||||
{file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"},
|
{file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -1965,4 +1965,4 @@ type = ["pytest-mypy"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.9,<4.0"
|
python-versions = ">=3.9,<4.0"
|
||||||
content-hash = "b0f8544806163bc0dddc039eb313f9d82119b845b3a19dedc381e9c88e8f4466"
|
content-hash = "e15b424a0569f939e297c8abfcf09753f1fbcc5b4ad891163cc0982accd3b372"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "commitizen"
|
name = "commitizen"
|
||||||
version = "4.6.0"
|
version = "4.6.3"
|
||||||
description = "Python commitizen client tool"
|
description = "Python commitizen client tool"
|
||||||
authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }]
|
authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }]
|
||||||
maintainers = [
|
maintainers = [
|
||||||
|
@ -19,7 +19,7 @@ dependencies = [
|
||||||
"tomlkit (>=0.5.3,<1.0.0)",
|
"tomlkit (>=0.5.3,<1.0.0)",
|
||||||
"jinja2>=2.10.3",
|
"jinja2>=2.10.3",
|
||||||
"pyyaml>=3.08",
|
"pyyaml>=3.08",
|
||||||
"argcomplete >=1.12.1,<3.6",
|
"argcomplete >=1.12.1,<3.7",
|
||||||
"typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'",
|
"typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'",
|
||||||
"charset-normalizer (>=2.1.0,<4)",
|
"charset-normalizer (>=2.1.0,<4)",
|
||||||
# Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility
|
# Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility
|
||||||
|
@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
[tool.commitizen]
|
[tool.commitizen]
|
||||||
version = "4.6.0"
|
version = "4.6.3"
|
||||||
tag_format = "v$version"
|
tag_format = "v$version"
|
||||||
version_files = [
|
version_files = [
|
||||||
"pyproject.toml:version",
|
"pyproject.toml:version",
|
||||||
|
|
|
@ -511,8 +511,6 @@ def test_manual_edit(editor, config, mocker: MockFixture, tmp_path):
|
||||||
|
|
||||||
assert edited_message == test_message.strip()
|
assert edited_message == test_message.strip()
|
||||||
|
|
||||||
temp_file.unlink()
|
|
||||||
|
|
||||||
|
|
||||||
@skip_below_py_3_13
|
@skip_below_py_3_13
|
||||||
def test_commit_command_shows_description_when_use_help_option(
|
def test_commit_command_shows_description_when_use_help_option(
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from jinja2 import FileSystemLoader
|
from jinja2 import FileSystemLoader
|
||||||
|
|
||||||
from commitizen import changelog, git
|
from commitizen import changelog, git
|
||||||
from commitizen.changelog_formats import ChangelogFormat
|
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 (
|
from commitizen.cz.conventional_commits.conventional_commits import (
|
||||||
ConventionalCommitsCz,
|
ConventionalCommitsCz,
|
||||||
)
|
)
|
||||||
|
@ -1499,7 +1505,7 @@ def test_changelog_message_builder_hook_can_access_and_modify_change_type(
|
||||||
def test_render_changelog_with_changelog_release_hook(
|
def test_render_changelog_with_changelog_release_hook(
|
||||||
gitcommits, tags, any_changelog_format: ChangelogFormat
|
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"
|
release["extra"] = "whatever"
|
||||||
return release
|
return release
|
||||||
|
|
||||||
|
@ -1631,3 +1637,36 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture):
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert captured.err.count("InvalidVersion") == 2
|
assert captured.err.count("InvalidVersion") == 2
|
||||||
assert captured.err.count("not-a-version") == 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 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 os.path.normpath(changelog.file_name) == os.path.normpath(
|
||||||
|
os.path.join("/my/project", "CHANGELOG.md")
|
||||||
|
)
|
||||||
|
|
76
tests/test_cz_search_filter.py
Normal file
76
tests/test_cz_search_filter.py
Normal file
|
@ -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"
|
Loading…
Add table
Add a link
Reference in a new issue