From 3f891ed1768603576e8c206d67c4d783aa5ecd8b Mon Sep 17 00:00:00 2001 From: Tim Hsiung <26526132+bearomorphism@users.noreply.github.com> Date: Sat, 9 May 2026 22:25:37 +0800 Subject: [PATCH] feat: add cz dump-config command to output effective configuration Closes #1331 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- commitizen/cli.py | 15 +++++ commitizen/commands/__init__.py | 2 + commitizen/commands/dump_config.py | 55 ++++++++++++++++ docs/commands/dump_config.md | 41 ++++++++++++ mkdocs.yml | 2 + tests/commands/test_common_command.py | 1 + ...n_use_help_option_py_3_10_dump_config_.txt | 8 +++ ...n_use_help_option_py_3_11_dump_config_.txt | 8 +++ ...n_use_help_option_py_3_12_dump_config_.txt | 8 +++ ...n_use_help_option_py_3_13_dump_config_.txt | 8 +++ ...n_use_help_option_py_3_14_dump_config_.txt | 8 +++ tests/commands/test_dump_config_command.py | 63 +++++++++++++++++++ 12 files changed, 219 insertions(+) create mode 100644 commitizen/commands/dump_config.py create mode 100644 docs/commands/dump_config.md create mode 100644 tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_dump_config_.txt create mode 100644 tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_dump_config_.txt create mode 100644 tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_dump_config_.txt create mode 100644 tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_dump_config_.txt create mode 100644 tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_dump_config_.txt create mode 100644 tests/commands/test_dump_config_command.py diff --git a/commitizen/cli.py b/commitizen/cli.py index 177099480e..be12646f04 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -197,6 +197,20 @@ def __call__( "help": "Show commit schema.", "func": commands.Schema, }, + { + "name": "dump-config", + "description": "Output the current commitizen configuration", + "help": "Output the current commitizen configuration.", + "func": commands.DumpConfig, + "arguments": [ + { + "name": ["--format", "-f"], + "choices": ["toml", "yaml", "json"], + "default": "toml", + "help": "Output format (default: toml).", + } + ], + }, { "name": "bump", "description": "Bump semantic version based on the git log", @@ -660,6 +674,7 @@ class Args(argparse.Namespace): | commands.Example # example | commands.Info # info | commands.Schema # schema + | commands.DumpConfig # dump-config | commands.Bump # bump | commands.Changelog # changelog (ch) | commands.Check # check diff --git a/commitizen/commands/__init__.py b/commitizen/commands/__init__.py index 58b18297dc..c51c5e6063 100644 --- a/commitizen/commands/__init__.py +++ b/commitizen/commands/__init__.py @@ -2,6 +2,7 @@ from .changelog import Changelog from .check import Check from .commit import Commit +from .dump_config import DumpConfig from .example import Example from .info import Info from .init import Init @@ -14,6 +15,7 @@ "Changelog", "Check", "Commit", + "DumpConfig", "Example", "Info", "Init", diff --git a/commitizen/commands/dump_config.py b/commitizen/commands/dump_config.py new file mode 100644 index 0000000000..992de6b500 --- /dev/null +++ b/commitizen/commands/dump_config.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import json +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any + +import tomlkit +import yaml + +from commitizen import out + +if TYPE_CHECKING: + from commitizen.config import BaseConfig + + +class DumpConfig: + """Output the current commitizen configuration.""" + + def __init__(self, config: BaseConfig, arguments: dict[str, Any]) -> None: + self.config: BaseConfig = config + self.format: str = arguments.get("format", "toml") + + def __call__(self) -> None: + settings = dict(self.config.settings) + + if self.format == "toml": + filtered = _filter_none_values(settings) + doc = tomlkit.document() + tool_table = tomlkit.table() + cz_table = tomlkit.table() + for key, value in filtered.items(): + cz_table.add(key, value) + tool_table.add("commitizen", cz_table) + doc.add("tool", tool_table) + out.write(tomlkit.dumps(doc)) + elif self.format == "yaml": + out.write( + yaml.safe_dump( + {"tool": {"commitizen": settings}}, + default_flow_style=False, + allow_unicode=True, + ) + ) + else: + out.write( + json.dumps({"tool": {"commitizen": settings}}, indent=2, default=str) + ) + + +def _filter_none_values(settings: Mapping[str, Any]) -> dict[str, Any]: + return { + key: _filter_none_values(value) if isinstance(value, Mapping) else value + for key, value in settings.items() + if value is not None + } diff --git a/docs/commands/dump_config.md b/docs/commands/dump_config.md new file mode 100644 index 0000000000..344f34ec28 --- /dev/null +++ b/docs/commands/dump_config.md @@ -0,0 +1,41 @@ +# dump-config + +Output the current commitizen configuration (defaults merged with any project overrides) so you can paste it directly into a configuration file as a starting point. + +## Usage + +``` +cz dump-config [--format {toml,yaml,json}] +``` + +## Options + +| Option | Description | +|---|---| +| `--format`, `-f` | Output format: `toml` (default), `yaml`, or `json` | + +## Examples + +Dump the current configuration as TOML (default): + +```bash +cz dump-config +``` + +Dump as YAML: + +```bash +cz dump-config --format yaml +``` + +Dump as JSON: + +```bash +cz dump-config --format json +``` + +Use the TOML output as a starting point for `pyproject.toml`: + +```bash +cz dump-config >> pyproject.toml +``` diff --git a/mkdocs.yml b/mkdocs.yml index 5f3190f7d7..77cde63219 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ nav: - info: "commands/info.md" - ls: "commands/ls.md" - schema: "commands/schema.md" + - dump-config: "commands/dump_config.md" - version: "commands/version.md" - Configuration: - Configuration File: "config/configuration_file.md" @@ -137,6 +138,7 @@ plugins: - commands/info.md: Show information about the active configuration. - commands/ls.md: List supported commit message choices for the active rules. - commands/schema.md: Show the commit message schema for the active convention. + - commands/dump_config.md: Output the current commitizen configuration. - commands/version.md: Show the installed or project version. Configuration: - config/configuration_file.md: Where configuration can live and how it is loaded. diff --git a/tests/commands/test_common_command.py b/tests/commands/test_common_command.py index c70bc96e94..76b456cc65 100644 --- a/tests/commands/test_common_command.py +++ b/tests/commands/test_common_command.py @@ -12,6 +12,7 @@ "changelog", "check", "commit", + "dump-config", "example", "info", "init", diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_dump_config_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_dump_config_.txt new file mode 100644 index 0000000000..c357443f46 --- /dev/null +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_dump_config_.txt @@ -0,0 +1,8 @@ +usage: cz dump-config [-h] [--format {toml,yaml,json}] + +Output the current commitizen configuration + +options: + -h, --help show this help message and exit + --format, -f {toml,yaml,json} + Output format (default: toml). diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_dump_config_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_dump_config_.txt new file mode 100644 index 0000000000..c357443f46 --- /dev/null +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_dump_config_.txt @@ -0,0 +1,8 @@ +usage: cz dump-config [-h] [--format {toml,yaml,json}] + +Output the current commitizen configuration + +options: + -h, --help show this help message and exit + --format, -f {toml,yaml,json} + Output format (default: toml). diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_dump_config_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_dump_config_.txt new file mode 100644 index 0000000000..c357443f46 --- /dev/null +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_dump_config_.txt @@ -0,0 +1,8 @@ +usage: cz dump-config [-h] [--format {toml,yaml,json}] + +Output the current commitizen configuration + +options: + -h, --help show this help message and exit + --format, -f {toml,yaml,json} + Output format (default: toml). diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_dump_config_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_dump_config_.txt new file mode 100644 index 0000000000..c357443f46 --- /dev/null +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_dump_config_.txt @@ -0,0 +1,8 @@ +usage: cz dump-config [-h] [--format {toml,yaml,json}] + +Output the current commitizen configuration + +options: + -h, --help show this help message and exit + --format, -f {toml,yaml,json} + Output format (default: toml). diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_dump_config_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_dump_config_.txt new file mode 100644 index 0000000000..c357443f46 --- /dev/null +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_dump_config_.txt @@ -0,0 +1,8 @@ +usage: cz dump-config [-h] [--format {toml,yaml,json}] + +Output the current commitizen configuration + +options: + -h, --help show this help message and exit + --format, -f {toml,yaml,json} + Output format (default: toml). diff --git a/tests/commands/test_dump_config_command.py b/tests/commands/test_dump_config_command.py new file mode 100644 index 0000000000..835b8c94e7 --- /dev/null +++ b/tests/commands/test_dump_config_command.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +import json + +import pytest +import tomlkit +import yaml + +from commitizen.commands.dump_config import DumpConfig +from commitizen.config import BaseConfig + + +@pytest.fixture +def config() -> BaseConfig: + cfg = BaseConfig() + return cfg + + +def test_dump_config_toml(config, capsys): + DumpConfig(config, {"format": "toml"})() + out, _ = capsys.readouterr() + doc = tomlkit.loads(out) + assert "tool" in doc + assert "commitizen" in doc["tool"] + cz = doc["tool"]["commitizen"] + assert cz["name"] == "cz_conventional_commits" + + +def test_dump_config_yaml(config, capsys): + DumpConfig(config, {"format": "yaml"})() + out, _ = capsys.readouterr() + data = yaml.safe_load(out) + assert "tool" in data + assert "commitizen" in data["tool"] + assert data["tool"]["commitizen"]["name"] == "cz_conventional_commits" + + +def test_dump_config_json(config, capsys): + DumpConfig(config, {"format": "json"})() + out, _ = capsys.readouterr() + data = json.loads(out) + assert "tool" in data + assert "commitizen" in data["tool"] + assert data["tool"]["commitizen"]["name"] == "cz_conventional_commits" + + +def test_dump_config_toml_default_format(config, capsys): + """Test that toml is the default format.""" + DumpConfig(config, {})() + out, _ = capsys.readouterr() + doc = tomlkit.loads(out) + assert "tool" in doc + + +def test_dump_config_toml_no_none_values(config, capsys): + """Test that None values are filtered out in TOML output.""" + DumpConfig(config, {"format": "toml"})() + out, _ = capsys.readouterr() + assert "null" not in out.lower() + doc = tomlkit.loads(out) + cz = doc["tool"]["commitizen"] + for value in cz.values(): + assert value is not None