2
2
3
3
import os
4
4
import shutil
5
- from typing import Any
6
5
7
6
import questionary
8
7
import yaml
14
13
from commitizen .defaults import DEFAULT_SETTINGS , config_files
15
14
from commitizen .exceptions import InitFailedError , NoAnswersError
16
15
from 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
+ )
18
22
19
23
20
24
class ProjectInfo :
@@ -67,10 +71,10 @@ def is_php_composer(self) -> bool:
67
71
def latest_tag (self ) -> str | None :
68
72
return get_latest_tag_name ()
69
73
70
- def tags (self ) -> list | None :
74
+ def tags (self ) -> list [ str ] :
71
75
"""Not a property, only use if necessary"""
72
76
if self .latest_tag is None :
73
- return None
77
+ return []
74
78
return get_tag_names ()
75
79
76
80
@property
@@ -113,72 +117,48 @@ def __call__(self):
113
117
except KeyboardInterrupt :
114
118
raise InitFailedError ("Stopped by user" )
115
119
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 )
132
121
133
- if update_changelog_on_bump :
134
- values_to_add ["update_changelog_on_bump" ] = update_changelog_on_bump
122
+ self ._init_pre_commit_hook ()
135
123
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
154
124
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
+ )
156
134
157
135
out .write ("\n You can bump the version running:\n " )
158
136
out .info ("\t cz bump\n " )
159
137
out .success ("Configuration complete 🚀" )
160
138
161
139
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
+ )
173
152
174
153
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
+ )
182
162
183
163
def _ask_tag (self ) -> str :
184
164
latest_tag = self .project_info .latest_tag
@@ -189,22 +169,27 @@ def _ask_tag(self) -> str:
189
169
is_correct_tag = questionary .confirm (
190
170
f"Is { latest_tag } the latest tag?" , style = self .cz .style , default = False
191
171
).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
+ # Tags are sorted in reverse order to get the most recent tag first,
181
+ # which is typically the one we want to use as a reference.
182
+ latest_tag = str (
183
+ questionary .select (
201
184
"Please choose the latest tag: " ,
202
- choices = sorted_tags ,
185
+ choices = sorted ( tags , reverse = True ) ,
203
186
style = self .cz .style ,
204
187
).unsafe_ask ()
188
+ )
189
+
190
+ if not latest_tag :
191
+ raise NoAnswersError ("Tag is required!" )
205
192
206
- if not latest_tag :
207
- raise NoAnswersError ("Tag is required!" )
208
193
return latest_tag
209
194
210
195
def _ask_tag_format (self , latest_tag ) -> str :
@@ -215,16 +200,16 @@ def _ask_tag_format(self, latest_tag) -> str:
215
200
f'Is "{ tag_format } " the correct tag format?' , style = self .cz .style
216
201
).unsafe_ask ()
217
202
203
+ if is_correct_format :
204
+ return tag_format
205
+
218
206
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 ()
207
+ tag_format = questionary .text (
208
+ f'Please enter the correct version format: (default: "{ default_format } ")' ,
209
+ style = self .cz .style ,
210
+ ).unsafe_ask ()
224
211
225
- if not tag_format :
226
- tag_format = default_format
227
- return tag_format
212
+ return tag_format or default_format
228
213
229
214
def _ask_version_provider (self ) -> str :
230
215
"""Ask for setting: version_provider"""
@@ -323,7 +308,31 @@ def _gen_pre_commit_cmd(self, hook_types: list[str]) -> str:
323
308
)
324
309
return cmd_str
325
310
326
- def _install_pre_commit_hook (self , hook_types : list [str ] | None = None ):
311
+ def _init_config (self , config_path : str ):
312
+ if "toml" in config_path :
313
+ self .config = TomlConfig (data = "" , path = config_path )
314
+ elif "json" in config_path :
315
+ self .config = JsonConfig (data = "{}" , path = config_path )
316
+ elif "yaml" in config_path :
317
+ self .config = YAMLConfig (data = "" , path = config_path )
318
+
319
+ def _init_pre_commit_hook (self ):
320
+ hook_types = questionary .checkbox (
321
+ "What types of pre-commit hook you want to install? (Leave blank if you don't want to install)" ,
322
+ choices = [
323
+ questionary .Choice ("commit-msg" , checked = False ),
324
+ questionary .Choice ("pre-push" , checked = False ),
325
+ ],
326
+ ).unsafe_ask ()
327
+ try :
328
+ self ._install_pre_commit_hook (hook_types )
329
+ except InitFailedError as e :
330
+ raise InitFailedError (f"Failed to install pre-commit hook.\n { e } " )
331
+
332
+ def _install_pre_commit_hook (self , hook_types : list [str ] | None ):
333
+ if not hook_types :
334
+ return
335
+
327
336
pre_commit_config_filename = ".pre-commit-config.yaml"
328
337
cz_hook_config = {
329
338
"repo" : "https://github.com/commitizen-tools/commitizen" ,
@@ -364,11 +373,18 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None):
364
373
365
374
if not self .project_info .is_pre_commit_installed :
366
375
raise InitFailedError ("pre-commit is not installed in current environment." )
367
- if hook_types is None :
368
- hook_types = ["commit-msg" , "pre-push" ]
376
+
369
377
self ._exec_install_pre_commit_hook (hook_types )
370
378
out .write ("commitizen pre-commit hook is now installed in your '.git'\n " )
371
379
372
- def _update_config_file (self , values : dict [str , Any ]):
373
- for key , value in values .items ():
374
- self .config .set_key (key , value )
380
+ def _update_config_file (
381
+ self , version_provider : str , version : VersionScheme , ** kwargs
382
+ ):
383
+ for key , value in kwargs .items ():
384
+ if value :
385
+ self .config .set_key (key , value )
386
+
387
+ if version_provider == "commitizen" :
388
+ self .config .set_key ("version" , version .public )
389
+ else :
390
+ self .config .set_key ("version_provider" , version_provider )
0 commit comments