Skip to content

Add yaml support for config #315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
4 changes: 3 additions & 1 deletion commitizen/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from commitizen import cmd, factory, out
from commitizen.__version__ import __version__
from commitizen.config import BaseConfig, JsonConfig, TomlConfig
from commitizen.config import BaseConfig, JsonConfig, TomlConfig, YAMLConfig
from commitizen.cz import registry
from commitizen.defaults import config_files
from commitizen.exceptions import NoAnswersError
Expand All @@ -28,6 +28,8 @@ def __call__(self):
self.config = TomlConfig(data="", path=config_path)
elif "json" in config_path:
self.config = JsonConfig(data="{}", path=config_path)
elif "yaml" in config_path:
self.config = YAMLConfig(data="", path=config_path)

self.config.init_empty_config_content()

Expand Down
9 changes: 6 additions & 3 deletions commitizen/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .base_config import BaseConfig
from .json_config import JsonConfig
from .toml_config import TomlConfig
from .yaml_config import YAMLConfig


def read_cfg() -> BaseConfig:
Expand All @@ -25,15 +26,17 @@ def read_cfg() -> BaseConfig:
if not filename.exists():
continue

_conf: Union[TomlConfig, JsonConfig, YAMLConfig]

with open(filename, "r") as f:
data: str = f.read()

_conf: Union[TomlConfig, JsonConfig]
if "toml" in filename.suffix:
_conf = TomlConfig(data=data, path=filename)

if "json" in filename.suffix:
elif "json" in filename.suffix:
_conf = JsonConfig(data=data, path=filename)
elif "yaml" in filename.suffix:
_conf = YAMLConfig(data=data, path=filename)

if _conf.is_empty_config:
continue
Expand Down
47 changes: 47 additions & 0 deletions commitizen/config/yaml_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from pathlib import Path
from typing import Union

import yaml

from .base_config import BaseConfig


class YAMLConfig(BaseConfig):
def __init__(self, *, data: str, path: Union[Path, str]):
super(YAMLConfig, self).__init__()
self.is_empty_config = False
self._parse_setting(data)
self.add_path(path)

def init_empty_config_content(self):
with open(self.path, "a") as json_file:
yaml.dump({"commitizen": {}}, json_file)

def _parse_setting(self, data: str):
"""We expect to have a section in cz.yaml looking like

```
commitizen:
name: cz_conventional_commits
```
"""
doc = yaml.safe_load(data)
try:
self.settings.update(doc["commitizen"])
except (KeyError, TypeError):
self.is_empty_config = True

def set_key(self, key, value):
"""Set or update a key in the conf.

For now only strings are supported.
We use to update the version number.
"""
with open(self.path, "r") as yaml_file:
parser = yaml.load(yaml_file)

parser["commitizen"][key] = value
with open(self.path, "w") as yaml_file:
yaml.dump(parser, yaml_file)

return self
9 changes: 8 additions & 1 deletion commitizen/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
from typing import Any, Dict, List

name: str = "cz_conventional_commits"
config_files: List[str] = ["pyproject.toml", ".cz.toml", ".cz.json", "cz.json"]
config_files: List[str] = [
"pyproject.toml",
".cz.toml",
".cz.json",
"cz.json",
".cz.yaml",
"cz.yaml",
]

DEFAULT_SETTINGS: Dict[str, Any] = {
"name": "cz_conventional_commits",
Expand Down
35 changes: 34 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ style = [

## .cz.json or cz.json

JSON may be a more commong configuration format for non-python projects, so Commitizen supports JSON config files, now.
JSON might be a more common configuration format for non-python projects, so Commitizen supports JSON config files, now.

```json
{
Expand Down Expand Up @@ -87,6 +87,39 @@ JSON may be a more commong configuration format for non-python projects, so Comm
}
```

## .cz.yaml or cz.yaml
YAML is another format for **non-python** proyects as well, supported by Commitizen:

```yaml
commitizen:
name: cz_conventional_commits
version: 0.1.0
version_files:
- src/__version__.py
- pyproject.toml:version
style:
- - qmark
- fg:#ff9d00 bold
- - question
- bold
- - answer
- fg:#ff9d00 bold
- - pointer
- fg:#ff9d00 bold
- - highlighted
- fg:#ff9d00 bold
- - selected
- fg:#cc5454
- - separator
- fg:#cc5454
- - instruction
- ''
- - text
- ''
- - disabled
- fg:#858585 italic
```

## Settings

| Variable | Type | Default | Description |
Expand Down
35 changes: 35 additions & 0 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,41 @@ The equivalent example for a json config file:
}
```

And the correspondent example for a yaml json file:

```yaml
commitizen:
name: cz_customize
customize:
message_template: "{{change_type}}:{% if show_message %} {{message}}{% endif %}"
example: 'feature: this feature enable customize through config file'
schema: "<type>: <body>"
schema_pattern: "(feature|bug fix):(\\s.*)"
bump_pattern: "^(break|new|fix|hotfix)"
bump_map:
break: MAJOR
new: MINOR
fix: PATCH
hotfix: PATCH
info_path: cz_customize_info.txt
info: This is customized info
questions:
- type: list
name: change_type
choices:
- value: feature
name: 'feature: A new feature.'
- value: bug fix
name: 'bug fix: A bug fix.'
message: Select the type of change you are committing
- type: input
name: message
message: Body.
- type: confirm
name: show_message
message: Do you want to add body message in commit?
```

### Customize configuration

| Parameter | Type | Default | Description |
Expand Down
22 changes: 15 additions & 7 deletions tests/commands/test_init_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def ask(self):
'tag_format = "$version"\n'
)

EXPECTED_JSON_CONFIG = {
EXPECTED_DICT_CONFIG = {
"commitizen": {
"name": "cz_conventional_commits",
"version": "0.0.1",
Expand Down Expand Up @@ -94,7 +94,7 @@ def test_init_without_choosing_tag(config, mocker, tmpdir):


class TestPreCommitCases:
@pytest.fixture(scope="function", params=["pyproject.toml", ".cz.json"])
@pytest.fixture(scope="function", params=["pyproject.toml", ".cz.json", ".cz.yaml"])
def default_choice(_, request, mocker):
mocker.patch(
"questionary.select",
Expand All @@ -108,13 +108,15 @@ def default_choice(_, request, mocker):
mocker.patch("questionary.confirm", return_value=FakeQuestion(True))
return request.param

def test_no_existing_pre_commit_json_conifg(_, default_choice, tmpdir, config):
def test_no_existing_pre_commit_conifg(_, default_choice, tmpdir, config):
with tmpdir.as_cwd():
commands.Init(config)()

with open(default_choice, "r") as file:
if "json" in default_choice:
assert json.load(file) == EXPECTED_JSON_CONFIG
assert json.load(file) == EXPECTED_DICT_CONFIG
elif "yaml" in default_choice:
assert yaml.load(file) == EXPECTED_DICT_CONFIG
else:
config_data = file.read()
assert config_data == expected_config
Expand All @@ -132,7 +134,9 @@ def test_empty_pre_commit_config(_, default_choice, tmpdir, config):

with open(default_choice, "r") as file:
if "json" in default_choice:
assert json.load(file) == EXPECTED_JSON_CONFIG
assert json.load(file) == EXPECTED_DICT_CONFIG
elif "yaml" in default_choice:
assert yaml.load(file) == EXPECTED_DICT_CONFIG
else:
config_data = file.read()
assert config_data == expected_config
Expand All @@ -156,7 +160,9 @@ def test_pre_commit_config_without_cz_hook(_, default_choice, tmpdir, config):

with open(default_choice, "r") as file:
if "json" in default_choice:
assert json.load(file) == EXPECTED_JSON_CONFIG
assert json.load(file) == EXPECTED_DICT_CONFIG
elif "yaml" in default_choice:
assert yaml.load(file) == EXPECTED_DICT_CONFIG
else:
config_data = file.read()
assert config_data == expected_config
Expand All @@ -176,7 +182,9 @@ def test_cz_hook_exists_in_pre_commit_config(_, default_choice, tmpdir, config):

with open(default_choice, "r") as file:
if "json" in default_choice:
assert json.load(file) == EXPECTED_JSON_CONFIG
assert json.load(file) == EXPECTED_DICT_CONFIG
elif "yaml" in default_choice:
assert yaml.load(file) == EXPECTED_DICT_CONFIG
else:
config_data = file.read()
assert config_data == expected_config
Expand Down
10 changes: 7 additions & 3 deletions tests/test_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path

import pytest
import yaml

from commitizen import config, defaults, git

Expand All @@ -24,7 +25,7 @@
target-version = ['py36', 'py37', 'py38']
"""

JSON_CONFIG = {
DICT_CONFIG = {
"commitizen": {
"name": "cz_jira",
"version": "1.0.0",
Expand All @@ -33,6 +34,7 @@
}
}


_settings = {
"name": "cz_jira",
"version": "1.0.0",
Expand Down Expand Up @@ -75,8 +77,10 @@ def config_files_manager(request, tmpdir):
with open(filename, "w") as f:
if "toml" in filename:
f.write(PYPROJECT)
if "json" in filename:
json.dump(JSON_CONFIG, f)
elif "json" in filename:
json.dump(DICT_CONFIG, f)
elif "yaml" in filename:
yaml.dump(DICT_CONFIG, f)
yield


Expand Down
Loading