Skip to content

Commit 4b5e66d

Browse files
authored
Merge pull request #480 from mmartinortiz/master
Safely ignore modules named `cz_` that are not plugins
2 parents 258f7c9 + e6f1dc3 commit 4b5e66d

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

commitizen/cz/__init__.py

+25-7
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
11
import importlib
22
import pkgutil
3-
from typing import Dict, Type
3+
import warnings
4+
from typing import Dict, Iterable, Type
45

56
from commitizen.cz.base import BaseCommitizen
67
from commitizen.cz.conventional_commits import ConventionalCommitsCz
78
from commitizen.cz.customize import CustomizeCommitsCz
89
from commitizen.cz.jira import JiraSmartCz
910

11+
12+
def discover_plugins(path: Iterable[str] = None) -> Dict[str, Type[BaseCommitizen]]:
13+
"""Discover commitizen plugins on the path
14+
15+
Args:
16+
path (Path, optional): If provided, 'path' should be either None or a list of paths to look for
17+
modules in. If path is None, all top-level modules on sys.path.. Defaults to None.
18+
19+
Returns:
20+
Dict[str, Type[BaseCommitizen]]: Registry with found plugins
21+
"""
22+
plugins = {}
23+
for finder, name, ispkg in pkgutil.iter_modules(path):
24+
try:
25+
if name.startswith("cz_"):
26+
plugins[name] = importlib.import_module(name).discover_this # type: ignore
27+
except AttributeError as e:
28+
warnings.warn(UserWarning(e.args[0]))
29+
continue
30+
return plugins
31+
32+
1033
registry: Dict[str, Type[BaseCommitizen]] = {
1134
"cz_conventional_commits": ConventionalCommitsCz,
1235
"cz_jira": JiraSmartCz,
1336
"cz_customize": CustomizeCommitsCz,
1437
}
15-
plugins = {
16-
name: importlib.import_module(name).discover_this # type: ignore
17-
for finder, name, ispkg in pkgutil.iter_modules()
18-
if name.startswith("cz_")
19-
}
2038

21-
registry.update(plugins)
39+
registry.update(discover_plugins())

tests/test_factory.py

+27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import sys
2+
13
import pytest
24

35
from commitizen import BaseCommitizen, defaults, factory
46
from commitizen.config import BaseConfig
7+
from commitizen.cz import discover_plugins
58
from commitizen.exceptions import NoCommitizenFoundException
69

710

@@ -19,3 +22,27 @@ def test_factory_fails():
1922
factory.commiter_factory(config)
2023

2124
assert "The committer has not been found in the system." in str(excinfo)
25+
26+
27+
@pytest.mark.parametrize(
28+
"module_content, plugin_name, expected_plugins",
29+
[
30+
("", "cz_no_plugin", {}),
31+
],
32+
)
33+
def test_discover_plugins(module_content, plugin_name, expected_plugins, tmp_path):
34+
no_plugin_folder = tmp_path / plugin_name
35+
no_plugin_folder.mkdir()
36+
init_file = no_plugin_folder / "__init__.py"
37+
init_file.write_text(module_content)
38+
39+
sys.path.append(tmp_path.as_posix())
40+
with pytest.warns(UserWarning) as record:
41+
discovered_plugins = discover_plugins([tmp_path.as_posix()])
42+
sys.path.pop()
43+
44+
assert (
45+
record[0].message.args[0]
46+
== f"module '{plugin_name}' has no attribute 'discover_this'"
47+
)
48+
assert expected_plugins == discovered_plugins

0 commit comments

Comments
 (0)