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 :
@@ -63,16 +67,6 @@ def is_npm_package(self) -> bool:
63
67
def is_php_composer (self ) -> bool :
64
68
return os .path .isfile ("composer.json" )
65
69
66
- @property
67
- def latest_tag (self ) -> str | None :
68
- return get_latest_tag_name ()
69
-
70
- def tags (self ) -> list | None :
71
- """Not a property, only use if necessary"""
72
- if self .latest_tag is None :
73
- return None
74
- return get_tag_names ()
75
-
76
70
@property
77
71
def is_pre_commit_installed (self ) -> bool :
78
72
return bool (shutil .which ("pre-commit" ))
@@ -113,98 +107,79 @@ def __call__(self):
113
107
except KeyboardInterrupt :
114
108
raise InitFailedError ("Stopped by user" )
115
109
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
110
+ self ._init_config (config_path )
132
111
133
- if update_changelog_on_bump :
134
- values_to_add ["update_changelog_on_bump" ] = update_changelog_on_bump
112
+ self ._init_pre_commit_hook ()
135
113
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
114
self .config .init_empty_config_content ()
155
- self ._update_config_file (values_to_add )
115
+ self ._update_config_file (
116
+ version_provider ,
117
+ version ,
118
+ name = cz_name ,
119
+ tag_format = tag_format ,
120
+ version_scheme = version_scheme ,
121
+ update_changelog_on_bump = update_changelog_on_bump ,
122
+ major_version_zero = major_version_zero ,
123
+ )
156
124
157
125
out .write ("\n You can bump the version running:\n " )
158
126
out .info ("\t cz bump\n " )
159
127
out .success ("Configuration complete 🚀" )
160
128
161
129
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
130
+ default_path = (
131
+ "pyproject.toml" if self .project_info .has_pyproject else ".cz.toml"
132
+ )
133
+
134
+ return str (
135
+ questionary .select (
136
+ "Please choose a supported config file: " ,
137
+ choices = config_files ,
138
+ default = default_path ,
139
+ style = self .cz .style ,
140
+ ).unsafe_ask ()
141
+ )
173
142
174
143
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
144
+ return str (
145
+ questionary .select (
146
+ "Please choose a cz (commit rule): (default: cz_conventional_commits)" ,
147
+ choices = list (registry .keys ()),
148
+ default = "cz_conventional_commits" ,
149
+ style = self .cz .style ,
150
+ ).unsafe_ask ()
151
+ )
182
152
183
153
def _ask_tag (self ) -> str :
184
- latest_tag = self . project_info . latest_tag
154
+ latest_tag = get_latest_tag_name ()
185
155
if not latest_tag :
186
156
out .error ("No Existing Tag. Set tag to v0.0.1" )
187
157
return "0.0.1"
188
158
189
159
is_correct_tag = questionary .confirm (
190
160
f"Is { latest_tag } the latest tag?" , style = self .cz .style , default = False
191
161
).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 (
162
+ if is_correct_tag :
163
+ return latest_tag
164
+
165
+ tags = get_tag_names ()
166
+ if not tags :
167
+ out .error ("No Existing Tag. Set tag to v0.0.1" )
168
+ return "0.0.1"
169
+
170
+ # Tags are sorted in reverse order to get the most recent tag first,
171
+ # which is typically the one we want to use as a reference.
172
+ latest_tag = str (
173
+ questionary .select (
201
174
"Please choose the latest tag: " ,
202
- choices = sorted_tags ,
175
+ choices = sorted ( tags , reverse = True ) ,
203
176
style = self .cz .style ,
204
177
).unsafe_ask ()
178
+ )
179
+
180
+ if not latest_tag :
181
+ raise NoAnswersError ("Tag is required!" )
205
182
206
- if not latest_tag :
207
- raise NoAnswersError ("Tag is required!" )
208
183
return latest_tag
209
184
210
185
def _ask_tag_format (self , latest_tag ) -> str :
@@ -215,16 +190,16 @@ def _ask_tag_format(self, latest_tag) -> str:
215
190
f'Is "{ tag_format } " the correct tag format?' , style = self .cz .style
216
191
).unsafe_ask ()
217
192
193
+ if is_correct_format :
194
+ return tag_format
195
+
218
196
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 ()
197
+ tag_format = questionary .text (
198
+ f'Please enter the correct version format: (default: "{ default_format } ")' ,
199
+ style = self .cz .style ,
200
+ ).unsafe_ask ()
224
201
225
- if not tag_format :
226
- tag_format = default_format
227
- return tag_format
202
+ return tag_format or default_format
228
203
229
204
def _ask_version_provider (self ) -> str :
230
205
"""Ask for setting: version_provider"""
@@ -323,7 +298,31 @@ def _gen_pre_commit_cmd(self, hook_types: list[str]) -> str:
323
298
)
324
299
return cmd_str
325
300
326
- def _install_pre_commit_hook (self , hook_types : list [str ] | None = None ):
301
+ def _init_config (self , config_path : str ):
302
+ if "toml" in config_path :
303
+ self .config = TomlConfig (data = "" , path = config_path )
304
+ elif "json" in config_path :
305
+ self .config = JsonConfig (data = "{}" , path = config_path )
306
+ elif "yaml" in config_path :
307
+ self .config = YAMLConfig (data = "" , path = config_path )
308
+
309
+ def _init_pre_commit_hook (self ):
310
+ hook_types = questionary .checkbox (
311
+ "What types of pre-commit hook you want to install? (Leave blank if you don't want to install)" ,
312
+ choices = [
313
+ questionary .Choice ("commit-msg" , checked = False ),
314
+ questionary .Choice ("pre-push" , checked = False ),
315
+ ],
316
+ ).unsafe_ask ()
317
+ try :
318
+ self ._install_pre_commit_hook (hook_types )
319
+ except InitFailedError as e :
320
+ raise InitFailedError (f"Failed to install pre-commit hook.\n { e } " )
321
+
322
+ def _install_pre_commit_hook (self , hook_types : list [str ] | None ):
323
+ if not hook_types :
324
+ return
325
+
327
326
pre_commit_config_filename = ".pre-commit-config.yaml"
328
327
cz_hook_config = {
329
328
"repo" : "https://github.com/commitizen-tools/commitizen" ,
@@ -364,11 +363,18 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None):
364
363
365
364
if not self .project_info .is_pre_commit_installed :
366
365
raise InitFailedError ("pre-commit is not installed in current environment." )
367
- if hook_types is None :
368
- hook_types = ["commit-msg" , "pre-push" ]
366
+
369
367
self ._exec_install_pre_commit_hook (hook_types )
370
368
out .write ("commitizen pre-commit hook is now installed in your '.git'\n " )
371
369
372
- def _update_config_file (self , values : dict [str , Any ]):
373
- for key , value in values .items ():
374
- self .config .set_key (key , value )
370
+ def _update_config_file (
371
+ self , version_provider : str , version : VersionScheme , ** kwargs
372
+ ):
373
+ for key , value in kwargs .items ():
374
+ if value :
375
+ self .config .set_key (key , value )
376
+
377
+ if version_provider == "commitizen" :
378
+ self .config .set_key ("version" , version .public )
379
+ else :
380
+ self .config .set_key ("version_provider" , version_provider )
0 commit comments