11import os
2+ import shutil
3+ from typing import Any , Dict
24
35import questionary
46import yaml
911from commitizen .config import BaseConfig , JsonConfig , TomlConfig , YAMLConfig
1012from commitizen .cz import registry
1113from commitizen .defaults import config_files
12- from commitizen .exceptions import NoAnswersError
14+ from commitizen .exceptions import InitFailedError , NoAnswersError
1315from 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- if not self .config . path :
26- config_path = self . _ask_config_path ()
27- if "toml" in config_path :
28- self . config = TomlConfig ( data = "" , path = config_path )
29- elif "json" in config_path :
30- self . config = JsonConfig ( data = "{}" , path = config_path )
31- elif "yaml" in config_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" in config_path :
31+ self . config = TomlConfig ( data = "" , path = config_path )
32+ elif "json" in config_path :
33+ self . config = JsonConfig ( data = "{}" , path = config_path )
34+ elif "yaml" in config_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+ if questionary . confirm ( "Do you want to install pre-commit hook?" ). ask ():
46+ if not self . _install_pre_commit_hook ():
47+ raise InitFailedError (
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 )
0 commit comments