22
33import os
44import shutil
5+ from typing import Any
56
67import questionary
78import yaml
@@ -73,6 +74,8 @@ def is_pre_commit_installed(self) -> bool:
7374
7475
7576class Init :
77+ _PRE_COMMIT_CONFIG_FILENAME = ".pre-commit-config.yaml"
78+
7679 def __init__ (self , config : BaseConfig , * args ):
7780 self .config : BaseConfig = config
7881 self .encoding = config .settings ["encoding" ]
@@ -322,7 +325,20 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None):
322325 if not hook_types :
323326 return
324327
325- PRE_COMMIT_CONFIG_FILENAME = ".pre-commit-config.yaml"
328+ config_data = self ._read_pre_commit_config ()
329+
330+ with smart_open (
331+ self ._PRE_COMMIT_CONFIG_FILENAME , "w" , encoding = self .encoding
332+ ) as config_file :
333+ yaml .safe_dump (config_data , stream = config_file )
334+
335+ if not self .project_info .is_pre_commit_installed :
336+ raise InitFailedError ("pre-commit is not installed in current environment." )
337+
338+ self ._exec_install_pre_commit_hook (hook_types )
339+ out .write ("commitizen pre-commit hook is now installed in your '.git'\n " )
340+
341+ def _read_pre_commit_config (self ) -> dict [Any , Any ]:
326342 CZ_HOOK_CONFIG = {
327343 "repo" : "https://github.com/commitizen-tools/commitizen" ,
328344 "rev" : f"v{ __version__ } " ,
@@ -332,33 +348,28 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None):
332348 ],
333349 }
334350
335- config_data = {}
336- if self .project_info .has_pre_commit_config :
337- with open (
338- PRE_COMMIT_CONFIG_FILENAME , encoding = self .encoding
339- ) as config_file :
340- if yaml_data := yaml .safe_load (config_file ):
341- config_data = yaml_data
342-
343- if repos := config_data .get ("repos" ):
344- for pre_commit_hook in repos :
345- if "commitizen" in pre_commit_hook ["repo" ]:
346- out .write ("commitizen already in pre-commit config" )
347- break
348- else :
349- repos .append (CZ_HOOK_CONFIG )
350- config_data .setdefault ("repos" , [CZ_HOOK_CONFIG ])
351+ DEFAULT_CONFIG = {"repos" : [CZ_HOOK_CONFIG ]}
351352
352- with smart_open (
353- PRE_COMMIT_CONFIG_FILENAME , "w" , encoding = self .encoding
353+ if not self .project_info .has_pre_commit_config :
354+ return DEFAULT_CONFIG
355+
356+ with open (
357+ self ._PRE_COMMIT_CONFIG_FILENAME , encoding = self .encoding
354358 ) as config_file :
355- yaml .safe_dump (config_data , stream = config_file )
359+ config_data = yaml .safe_load (config_file )
360+ if not isinstance (config_data , dict ):
361+ return DEFAULT_CONFIG
356362
357- if not self .project_info .is_pre_commit_installed :
358- raise InitFailedError ("pre-commit is not installed in current environment." )
363+ repos = config_data .get ("repos" )
364+ if not repos :
365+ return DEFAULT_CONFIG
359366
360- self ._exec_install_pre_commit_hook (hook_types )
361- out .write ("commitizen pre-commit hook is now installed in your '.git'\n " )
367+ if any ("commitizen" in hook ["repo" ] for hook in repos ):
368+ out .write ("commitizen already in pre-commit config" )
369+ else :
370+ config_data ["repos" ].append (CZ_HOOK_CONFIG )
371+
372+ return config_data
362373
363374 def _update_config_file (
364375 self , version_provider : str , version : VersionScheme , ** kwargs
0 commit comments