Skip to content
Open
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
29 changes: 21 additions & 8 deletions commitizen/changelog_formats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,30 @@ def get_changelog_format(
"""
Get a format from its name

:raises FormatUnknown: if a non-empty name is provided but cannot be found in the known formats
:raises ChangelogFormatUnknown: if a non-empty name is provided but cannot
be found in the known formats, or if the filename's extension cannot
be matched to a known format and no ``changelog_format`` is set.
"""
name: str | None = config.settings.get("changelog_format")
format = (
name and KNOWN_CHANGELOG_FORMATS.get(name) or _guess_changelog_format(filename)
)

if not format:
raise ChangelogFormatUnknown(f"Unknown changelog format '{name}'")
known = ", ".join(sorted(KNOWN_CHANGELOG_FORMATS)) or "(none registered)"

if name:
format_cls = KNOWN_CHANGELOG_FORMATS.get(name)
if format_cls is None:
raise ChangelogFormatUnknown(
f"Unknown changelog format '{name}'. Known formats: {known}."
)
return format_cls(config)

format_cls = _guess_changelog_format(filename)
if format_cls is None:
raise ChangelogFormatUnknown(
"Cannot infer changelog format from filename "
f"'{filename}'. Set the `changelog_format` setting "
f"explicitly. Known formats: {known}."
)

return format(config)
return format_cls(config)


def _guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None:
Expand Down
35 changes: 33 additions & 2 deletions tests/test_changelog_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,42 @@ def test_get_format_empty_filename(config: BaseConfig, filename: str | None):
@pytest.mark.parametrize("filename", [None, ""])
def test_get_format_empty_filename_no_setting(config: BaseConfig, filename: str | None):
config.settings["changelog_format"] = None
with pytest.raises(ChangelogFormatUnknown):
with pytest.raises(ChangelogFormatUnknown) as excinfo:
get_changelog_format(config, filename)
# The error message should hint at setting `changelog_format` and list
# the known formats so users on non-standard file extensions know what
# to do (#894).
msg = str(excinfo.value)
assert "changelog_format" in msg
assert "Known formats" in msg


@pytest.mark.parametrize("filename", ["extensionless", "file.unknown"])
def test_get_format_unknown(config: BaseConfig, filename: str | None):
with pytest.raises(ChangelogFormatUnknown):
with pytest.raises(ChangelogFormatUnknown) as excinfo:
get_changelog_format(config, filename)
# Same hint when the filename extension is unknown.
msg = str(excinfo.value)
assert "changelog_format" in msg
assert "Known formats" in msg


def test_get_format_unknown_name_lists_known_formats(config: BaseConfig):
"""Regression test for #894: when ``changelog_format`` is set to an
unknown value, the error must list the registered formats so users
can self-correct."""
config.settings["changelog_format"] = "definitely-not-a-format"
with pytest.raises(ChangelogFormatUnknown) as excinfo:
get_changelog_format(config)
msg = str(excinfo.value)
assert "definitely-not-a-format" in msg
assert "Known formats" in msg
Comment thread
bearomorphism marked this conversation as resolved.


def test_get_format_unknown_name_with_known_filename_raises(config: BaseConfig):
config.settings["changelog_format"] = "invalidformat"
with pytest.raises(ChangelogFormatUnknown) as excinfo:
get_changelog_format(config, "CHANGELOG.md")
msg = str(excinfo.value)
assert "invalidformat" in msg
assert "Known formats" in msg
Loading