Skip to content

Commit 1ca0c12

Browse files
committed
refactor(config): rename config method and refactor to centralize --config logic
1 parent 6c8fad1 commit 1ca0c12

File tree

3 files changed

+54
-37
lines changed

3 files changed

+54
-37
lines changed

commitizen/cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -675,12 +675,12 @@ def main() -> None:
675675
extra_args = " ".join(unknown_args[1:])
676676
arguments["extra_cli_args"] = extra_args
677677

678-
conf = config.read_cfg(args.config)
679678
args = cast("Args", args)
679+
config_object = config.search_and_read_config_file(args.config)
680680
if args.name:
681-
conf.update({"name": args.name})
682-
elif not conf.path:
683-
conf.update({"name": "cz_conventional_commits"})
681+
config_object.update({"name": args.name})
682+
elif not config_object.path:
683+
config_object.update({"name": "cz_conventional_commits"})
684684

685685
if args.debug:
686686
logging.getLogger("commitizen").setLevel(logging.DEBUG)
@@ -692,7 +692,7 @@ def main() -> None:
692692
)
693693
sys.excepthook = no_raise_debug_excepthook
694694

695-
args.func(conf, arguments)() # type: ignore[arg-type]
695+
args.func(config_object, arguments)() # type: ignore[arg-type]
696696

697697

698698
if __name__ == "__main__":

commitizen/config/__init__.py

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
from collections.abc import Generator
43
from pathlib import Path
54

65
from commitizen import defaults, git
@@ -10,37 +9,51 @@
109
from .base_config import BaseConfig
1110

1211

13-
def _resolve_config_paths(filepath: str | None = None) -> Generator[Path, None, None]:
14-
if filepath is not None:
15-
out_path = Path(filepath)
12+
def _try_read_config_file(filename: Path) -> BaseConfig | None:
13+
with open(filename, "rb") as f:
14+
data: bytes = f.read()
15+
16+
conf = create_config(data=data, path=filename)
17+
if not conf.is_empty_config:
18+
return conf
19+
20+
return None
21+
22+
23+
def search_and_read_config_file(specified_config_path: str | None = None) -> BaseConfig:
24+
"""Search and read config file from specified path, current directory, or git project root. If not found, return empty config object.
25+
26+
Args:
27+
specified_config_path (str | None, optional): from --config command line argument. Defaults to None.
28+
29+
Raises:
30+
ConfigFileNotFound: specified config file not found
31+
ConfigFileIsEmpty: specified config file is empty
32+
33+
Returns:
34+
BaseConfig: config object
35+
"""
36+
if specified_config_path is not None:
37+
out_path = Path(specified_config_path)
1638
if not out_path.exists():
1739
raise ConfigFileNotFound()
1840

19-
yield out_path
20-
return
41+
if (ret := _try_read_config_file(out_path)) is not None:
42+
return ret
43+
raise ConfigFileIsEmpty()
2144

22-
git_project_root = git.find_git_project_root()
2345
cfg_search_paths = [Path(".")]
24-
if git_project_root:
46+
if git_project_root := git.find_git_project_root():
2547
cfg_search_paths.append(git_project_root)
2648

2749
for path in cfg_search_paths:
2850
for filename in defaults.CONFIG_FILES:
2951
out_path = path / Path(filename)
30-
if out_path.exists():
31-
yield out_path
32-
33-
34-
def read_cfg(filepath: str | None = None) -> BaseConfig:
35-
for filename in _resolve_config_paths(filepath):
36-
with open(filename, "rb") as f:
37-
data: bytes = f.read()
38-
39-
conf = create_config(data=data, path=filename)
40-
if not conf.is_empty_config:
41-
return conf
42-
43-
if filepath is not None:
44-
raise ConfigFileIsEmpty()
52+
if (
53+
out_path.exists()
54+
and (ret := _try_read_config_file(out_path)) is not None
55+
):
56+
return ret
4557

58+
# TODO: add comment about why we return empty config object
4659
return BaseConfig()

tests/test_conf.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ def test_find_git_project_root(tmpdir):
175175
"config_files_manager", defaults.CONFIG_FILES.copy(), indirect=True
176176
)
177177
def test_set_key(config_files_manager):
178-
_conf = config.read_cfg()
178+
_conf = config.search_and_read_config_file()
179179
_conf.set_key("version", "2.0.0")
180-
cfg = config.read_cfg()
180+
cfg = config.search_and_read_config_file()
181181
assert cfg.settings == _new_settings
182182

183183

@@ -186,12 +186,12 @@ class TestReadCfg:
186186
"config_files_manager", defaults.CONFIG_FILES.copy(), indirect=True
187187
)
188188
def test_load_conf(_, config_files_manager):
189-
cfg = config.read_cfg()
189+
cfg = config.search_and_read_config_file()
190190
assert cfg.settings == _settings
191191

192192
def test_conf_returns_default_when_no_files(_, tmpdir):
193193
with tmpdir.as_cwd():
194-
cfg = config.read_cfg()
194+
cfg = config.search_and_read_config_file()
195195
assert cfg.settings == defaults.DEFAULT_SETTINGS
196196

197197
def test_load_empty_pyproject_toml_and_cz_toml_with_config(_, tmpdir):
@@ -201,23 +201,25 @@ def test_load_empty_pyproject_toml_and_cz_toml_with_config(_, tmpdir):
201201
p = tmpdir.join(".cz.toml")
202202
p.write(PYPROJECT)
203203

204-
cfg = config.read_cfg()
204+
cfg = config.search_and_read_config_file()
205205
assert cfg.settings == _settings
206206

207207
def test_load_pyproject_toml_from_config_argument(_, tmpdir):
208208
with tmpdir.as_cwd():
209209
_not_root_path = tmpdir.mkdir("not_in_root").join("pyproject.toml")
210210
_not_root_path.write(PYPROJECT)
211211

212-
cfg = config.read_cfg(filepath="./not_in_root/pyproject.toml")
212+
cfg = config.search_and_read_config_file(
213+
filepath="./not_in_root/pyproject.toml"
214+
)
213215
assert cfg.settings == _settings
214216

215217
def test_load_cz_json_not_from_config_argument(_, tmpdir):
216218
with tmpdir.as_cwd():
217219
_not_root_path = tmpdir.mkdir("not_in_root").join(".cz.json")
218220
_not_root_path.write(JSON_STR)
219221

220-
cfg = config.read_cfg(filepath="./not_in_root/.cz.json")
222+
cfg = config.search_and_read_config_file(filepath="./not_in_root/.cz.json")
221223
json_cfg_by_class = JsonConfig(data=JSON_STR, path=_not_root_path)
222224
assert cfg.settings == json_cfg_by_class.settings
223225

@@ -226,7 +228,7 @@ def test_load_cz_yaml_not_from_config_argument(_, tmpdir):
226228
_not_root_path = tmpdir.mkdir("not_in_root").join(".cz.yaml")
227229
_not_root_path.write(YAML_STR)
228230

229-
cfg = config.read_cfg(filepath="./not_in_root/.cz.yaml")
231+
cfg = config.search_and_read_config_file(filepath="./not_in_root/.cz.yaml")
230232
yaml_cfg_by_class = YAMLConfig(data=YAML_STR, path=_not_root_path)
231233
assert cfg.settings == yaml_cfg_by_class._settings
232234

@@ -236,7 +238,9 @@ def test_load_empty_pyproject_toml_from_config_argument(_, tmpdir):
236238
_not_root_path.write("")
237239

238240
with pytest.raises(ConfigFileIsEmpty):
239-
config.read_cfg(filepath="./not_in_root/pyproject.toml")
241+
config.search_and_read_config_file(
242+
filepath="./not_in_root/pyproject.toml"
243+
)
240244

241245

242246
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)