Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 947cc68

Browse files
BogayLee-W
authored andcommitted
fix(init): report error when hook installation failed
1 parent 3c7d67d commit 947cc68

File tree

3 files changed

+71
-42
lines changed

3 files changed

+71
-42
lines changed

‎commitizen/commands/init.py‎

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os
2+
import shutil
3+
from typing import Any, Dict
24

35
import questionary
46
import yaml
@@ -9,7 +11,7 @@
911
from commitizen.config import BaseConfig, JsonConfig, TomlConfig, YAMLConfig
1012
from commitizen.cz import registry
1113
from commitizen.defaults import config_files
12-
from commitizen.exceptions import NoAnswersError
14+
from commitizen.exceptions import InitFailedError, NoAnswersError
1315
from commitizen.git import get_latest_tag_name, get_tag_names, smart_open
1416

1517

@@ -19,34 +21,36 @@ def __init__(self, config: BaseConfig, *args):
1921
self.cz = factory.commiter_factory(self.config)
2022

2123
def __call__(self):
22-
values_to_add = {}
24+
if self.config.path:
25+
out.line(f"Config file {self.config.path} already exists")
26+
return
2327

2428
# No config for commitizen exist
25-
ifnot self.config.path:
26-
config_path=self._ask_config_path()
27-
if"toml"inconfig_path:
28-
self.config=TomlConfig(data="", path=config_path)
29-
elif"json"inconfig_path:
30-
self.config=JsonConfig(data="{}", path=config_path)
31-
elif"yaml"inconfig_path:
32-
self.config=YAMLConfig(data="", path=config_path)
33-
34-
self.config.init_empty_config_content()
35-
36-
values_to_add["name"] = self._ask_name()
37-
tag=self._ask_tag()
38-
values_to_add["version"] = Version(tag).public
39-
values_to_add["tag_format"] =self._ask_tag_format(tag)
40-
self._update_config_file(values_to_add)
41-
42-
if questionary.confirm("Do you want to install pre-commit hook?").ask():
43-
self._install_pre_commit_hook()
44-
45-
out.write("You can bump the version and create changelog running:\n")
46-
out.info("cz bump --changelog")
47-
out.success("The configuration are all set.")
48-
else:
49-
out.line(f"Config file {self.config.path} already exists")
29+
config_path= self._ask_config_path()
30+
if"toml"inconfig_path:
31+
self.config=TomlConfig(data="", path=config_path)
32+
elif"json"inconfig_path:
33+
self.config=JsonConfig(data="{}", path=config_path)
34+
elif"yaml"inconfig_path:
35+
self.config=YAMLConfig(data="", path=config_path)
36+
self.config.init_empty_config_content()
37+
38+
values_to_add= {}
39+
values_to_add["name"] =self._ask_name()
40+
tag= self._ask_tag()
41+
values_to_add["version"] =Version(tag).public
42+
values_to_add["tag_format"] = self._ask_tag_format(tag)
43+
self._update_config_file(values_to_add)
44+
45+
ifquestionary.confirm("Do you want to install pre-commit hook?").ask():
46+
if notself._install_pre_commit_hook():
47+
raiseInitFailedError(
48+
"Installation failed. See error outputs for more information."
49+
)
50+
51+
out.write("You can bump the version and create changelog running:\n")
52+
out.info("cz bump --changelog")
53+
out.success("The configuration are all set.")
5054

5155
def _ask_config_path(self) -> str:
5256
name: str = questionary.select(
@@ -109,7 +113,20 @@ def _ask_tag_format(self, latest_tag) -> str:
109113
tag_format = "$version"
110114
return tag_format
111115

112-
def _install_pre_commit_hook(self):
116+
def _search_pre_commit(self):
117+
return shutil.which("pre-commit") is not None
118+
119+
def _exec_install_pre_commit_hook(self):
120+
cmd_str = "pre-commit install --hook-type commit-msg"
121+
c = cmd.run(cmd_str)
122+
if c.return_code != 0:
123+
out.error(f"Error running {cmd_str}. Outputs are attached below:")
124+
out.error(f"stdout: {c.out}")
125+
out.error(f"stderr: {c.err}")
126+
return False
127+
return True
128+
129+
def _install_pre_commit_hook(self) -> bool:
113130
pre_commit_config_filename = ".pre-commit-config.yaml"
114131
cz_hook_config = {
115132
"repo": "https://github.com/commitizen-tools/commitizen",
@@ -119,7 +136,7 @@ def _install_pre_commit_hook(self):
119136

120137
config_data = {}
121138
if not os.path.isfile(pre_commit_config_filename):
122-
# .pre-commit-config does not exist
139+
# .pre-commit-config.yaml does not exist
123140
config_data["repos"] = [cz_hook_config]
124141
else:
125142
with open(pre_commit_config_filename) as config_file:
@@ -135,23 +152,22 @@ def _install_pre_commit_hook(self):
135152
else:
136153
config_data["repos"].append(cz_hook_config)
137154
else:
138-
# .pre-commit-config exists but there's no "repos" key
155+
# .pre-commit-config.yaml exists but there's no "repos" key
139156
config_data["repos"] = [cz_hook_config]
140157

141158
with smart_open(pre_commit_config_filename, "w") as config_file:
142159
yaml.safe_dump(config_data, stream=config_file)
143160

144-
c = cmd.run("pre-commit install --hook-type commit-msg")
145-
if c.return_code == 127:
146-
out.error(
147-
"pre-commit is not installed in current environement.\n"
148-
"Run 'pre-commit install --hook-type commit-msg' again after it's installed"
149-
)
150-
elif c.return_code != 0:
151-
out.error(c.err)
152-
else:
153-
out.write("commitizen pre-commit hook is now installed in your '.git'\n")
161+
if not self._search_pre_commit():
162+
out.error("pre-commit is not installed in current environement.")
163+
return False
164+
165+
if not self._exec_install_pre_commit_hook():
166+
return False
167+
168+
out.write("commitizen pre-commit hook is now installed in your '.git'\n")
169+
return True
154170

155-
def _update_config_file(self, values):
171+
def _update_config_file(self, values: Dict[str, Any]):
156172
for key, value in values.items():
157173
self.config.set_key(key, value)

‎commitizen/exceptions.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ExitCode(enum.IntEnum):
2929
UNRECOGNIZED_CHARACTERSET_ENCODING = 22
3030
GIT_COMMAND_ERROR = 23
3131
INVALID_MANUAL_VERSION = 24
32+
INIT_FAILED = 25
3233

3334

3435
class CommitizenException(Exception):
@@ -163,3 +164,7 @@ class GitCommandError(CommitizenException):
163164

164165
class InvalidManualVersion(CommitizenException):
165166
exit_code = ExitCode.INVALID_MANUAL_VERSION
167+
168+
169+
class InitFailedError(CommitizenException):
170+
exit_code = ExitCode.INIT_FAILED

‎tests/commands/test_init_command.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,15 @@ def default_choice(_, request, mocker):
105105
)
106106
mocker.patch("questionary.confirm", return_value=FakeQuestion(True))
107107
mocker.patch("questionary.text", return_value=FakeQuestion("$version"))
108-
mocker.patch("questionary.confirm", return_value=FakeQuestion(True))
108+
# Assume the `pre-commit` is installed
109+
mocker.patch(
110+
"commitizen.commands.init.Init._search_pre_commit",
111+
return_value=True,
112+
)
113+
mocker.patch(
114+
"commitizen.commands.init.Init._exec_install_pre_commit_hook",
115+
return_value=True,
116+
)
109117
return request.param
110118

111119
def test_no_existing_pre_commit_conifg(_, default_choice, tmpdir, config):

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /