22
33import os
44import shutil
5- from typing import Any
65
76import questionary
87import yaml
1413from commitizen .defaults import DEFAULT_SETTINGS , config_files
1514from commitizen .exceptions import InitFailedError , NoAnswersError
1615from commitizen .git import get_latest_tag_name , get_tag_names , smart_open
17- from commitizen .version_schemes import KNOWN_SCHEMES , Version , get_version_scheme
16+ from commitizen .version_schemes import (
17+ KNOWN_SCHEMES ,
18+ Version ,
19+ VersionScheme ,
20+ get_version_scheme ,
21+ )
1822
1923
2024class ProjectInfo :
@@ -67,10 +71,10 @@ def is_php_composer(self) -> bool:
6771 def latest_tag (self ) -> str | None :
6872 return get_latest_tag_name ()
6973
70- def tags (self ) -> list | None :
74+ def tags (self ) -> list [ str ] :
7175 """Not a property, only use if necessary"""
7276 if self .latest_tag is None :
73- return None
77+ return []
7478 return get_tag_names ()
7579
7680 @property
@@ -113,72 +117,48 @@ def __call__(self):
113117 except KeyboardInterrupt :
114118 raise InitFailedError ("Stopped by user" )
115119
116- # Initialize configuration
117- if "toml" in config_path :
118- self .config = TomlConfig (data = "" , path = config_path )
119- elif "json" in config_path :
120- self .config = JsonConfig (data = "{}" , path = config_path )
121- elif "yaml" in config_path :
122- self .config = YAMLConfig (data = "" , path = config_path )
123- values_to_add = {}
124- values_to_add ["name" ] = cz_name
125- values_to_add ["tag_format" ] = tag_format
126- values_to_add ["version_scheme" ] = version_scheme
127-
128- if version_provider == "commitizen" :
129- values_to_add ["version" ] = version .public
130- else :
131- values_to_add ["version_provider" ] = version_provider
120+ self ._init_config (config_path )
132121
133- if update_changelog_on_bump :
134- values_to_add ["update_changelog_on_bump" ] = update_changelog_on_bump
122+ self ._init_pre_commit_hook ()
135123
136- if major_version_zero :
137- values_to_add ["major_version_zero" ] = major_version_zero
138-
139- # Collect hook data
140- hook_types = questionary .checkbox (
141- "What types of pre-commit hook you want to install? (Leave blank if you don't want to install)" ,
142- choices = [
143- questionary .Choice ("commit-msg" , checked = False ),
144- questionary .Choice ("pre-push" , checked = False ),
145- ],
146- ).unsafe_ask ()
147- if hook_types :
148- try :
149- self ._install_pre_commit_hook (hook_types )
150- except InitFailedError as e :
151- raise InitFailedError (f"Failed to install pre-commit hook.\n { e } " )
152-
153- # Create and initialize config
154124 self .config .init_empty_config_content ()
155- self ._update_config_file (values_to_add )
125+ self ._update_config_file (
126+ version_provider ,
127+ version ,
128+ name = cz_name ,
129+ tag_format = tag_format ,
130+ version_scheme = version_scheme ,
131+ update_changelog_on_bump = update_changelog_on_bump ,
132+ major_version_zero = major_version_zero ,
133+ )
156134
157135 out .write ("\n You can bump the version running:\n " )
158136 out .info ("\t cz bump\n " )
159137 out .success ("Configuration complete 🚀" )
160138
161139 def _ask_config_path (self ) -> str :
162- default_path = ".cz.toml"
163- if self .project_info .has_pyproject :
164- default_path = "pyproject.toml"
165-
166- name : str = questionary .select (
167- "Please choose a supported config file: " ,
168- choices = config_files ,
169- default = default_path ,
170- style = self .cz .style ,
171- ).unsafe_ask ()
172- return name
140+ default_path = (
141+ "pyproject.toml" if self .project_info .has_pyproject else ".cz.toml"
142+ )
143+
144+ return str (
145+ questionary .select (
146+ "Please choose a supported config file: " ,
147+ choices = config_files ,
148+ default = default_path ,
149+ style = self .cz .style ,
150+ ).unsafe_ask ()
151+ )
173152
174153 def _ask_name (self ) -> str :
175- name : str = questionary .select (
176- "Please choose a cz (commit rule): (default: cz_conventional_commits)" ,
177- choices = list (registry .keys ()),
178- default = "cz_conventional_commits" ,
179- style = self .cz .style ,
180- ).unsafe_ask ()
181- return name
154+ return str (
155+ questionary .select (
156+ "Please choose a cz (commit rule): (default: cz_conventional_commits)" ,
157+ choices = list (registry .keys ()),
158+ default = "cz_conventional_commits" ,
159+ style = self .cz .style ,
160+ ).unsafe_ask ()
161+ )
182162
183163 def _ask_tag (self ) -> str :
184164 latest_tag = self .project_info .latest_tag
@@ -189,22 +169,26 @@ def _ask_tag(self) -> str:
189169 is_correct_tag = questionary .confirm (
190170 f"Is { latest_tag } the latest tag?" , style = self .cz .style , default = False
191171 ).unsafe_ask ()
192- if not is_correct_tag :
193- tags = self .project_info .tags ()
194- if not tags :
195- out .error ("No Existing Tag. Set tag to v0.0.1" )
196- return "0.0.1"
197-
198- # the latest tag is most likely with the largest number. Thus list the tags in reverse order makes more sense
199- sorted_tags = sorted (tags , reverse = True )
200- latest_tag = questionary .select (
172+ if is_correct_tag :
173+ return latest_tag
174+
175+ tags = self .project_info .tags ()
176+ if not tags :
177+ out .error ("No Existing Tag. Set tag to v0.0.1" )
178+ return "0.0.1"
179+
180+ # The latest tag is most likely with the largest number. Thus list the tags in reverse order makes more sense
181+ latest_tag = str (
182+ questionary .select (
201183 "Please choose the latest tag: " ,
202- choices = sorted_tags ,
184+ choices = sorted ( tags , reverse = True ) ,
203185 style = self .cz .style ,
204186 ).unsafe_ask ()
187+ )
188+
189+ if not latest_tag :
190+ raise NoAnswersError ("Tag is required!" )
205191
206- if not latest_tag :
207- raise NoAnswersError ("Tag is required!" )
208192 return latest_tag
209193
210194 def _ask_tag_format (self , latest_tag ) -> str :
@@ -215,16 +199,16 @@ def _ask_tag_format(self, latest_tag) -> str:
215199 f'Is "{ tag_format } " the correct tag format?' , style = self .cz .style
216200 ).unsafe_ask ()
217201
202+ if is_correct_format :
203+ return tag_format
204+
218205 default_format = DEFAULT_SETTINGS ["tag_format" ]
219- if not is_correct_format :
220- tag_format = questionary .text (
221- f'Please enter the correct version format: (default: "{ default_format } ")' ,
222- style = self .cz .style ,
223- ).unsafe_ask ()
206+ tag_format = questionary .text (
207+ f'Please enter the correct version format: (default: "{ default_format } ")' ,
208+ style = self .cz .style ,
209+ ).unsafe_ask ()
224210
225- if not tag_format :
226- tag_format = default_format
227- return tag_format
211+ return tag_format or default_format
228212
229213 def _ask_version_provider (self ) -> str :
230214 """Ask for setting: version_provider"""
@@ -323,7 +307,31 @@ def _gen_pre_commit_cmd(self, hook_types: list[str]) -> str:
323307 )
324308 return cmd_str
325309
326- def _install_pre_commit_hook (self , hook_types : list [str ] | None = None ):
310+ def _init_config (self , config_path : str ):
311+ if "toml" in config_path :
312+ self .config = TomlConfig (data = "" , path = config_path )
313+ elif "json" in config_path :
314+ self .config = JsonConfig (data = "{}" , path = config_path )
315+ elif "yaml" in config_path :
316+ self .config = YAMLConfig (data = "" , path = config_path )
317+
318+ def _init_pre_commit_hook (self ):
319+ hook_types = questionary .checkbox (
320+ "What types of pre-commit hook you want to install? (Leave blank if you don't want to install)" ,
321+ choices = [
322+ questionary .Choice ("commit-msg" , checked = False ),
323+ questionary .Choice ("pre-push" , checked = False ),
324+ ],
325+ ).unsafe_ask ()
326+ try :
327+ self ._install_pre_commit_hook (hook_types )
328+ except InitFailedError as e :
329+ raise InitFailedError (f"Failed to install pre-commit hook.\n { e } " )
330+
331+ def _install_pre_commit_hook (self , hook_types : list [str ] | None ):
332+ if not hook_types :
333+ return
334+
327335 pre_commit_config_filename = ".pre-commit-config.yaml"
328336 cz_hook_config = {
329337 "repo" : "https://github.com/commitizen-tools/commitizen" ,
@@ -364,11 +372,17 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None):
364372
365373 if not self .project_info .is_pre_commit_installed :
366374 raise InitFailedError ("pre-commit is not installed in current environment." )
367- if hook_types is None :
368- hook_types = ["commit-msg" , "pre-push" ]
375+
369376 self ._exec_install_pre_commit_hook (hook_types )
370377 out .write ("commitizen pre-commit hook is now installed in your '.git'\n " )
371378
372- def _update_config_file (self , values : dict [str , Any ]):
373- for key , value in values .items ():
379+ def _update_config_file (
380+ self , version_provider : str , version : VersionScheme , ** kwargs
381+ ):
382+ for key , value in kwargs .items ():
374383 self .config .set_key (key , value )
384+
385+ if version_provider == "commitizen" :
386+ self .config .set_key ("version" , version .public )
387+ else :
388+ self .config .set_key ("version_provider" , version_provider )
0 commit comments