1717import  sys 
1818from  typing  import  List 
1919
20- from  .commitlint  import  check_commit_message 
21- from  .messages  import  COMMIT_SUCCESSFUL 
20+ from  .commitlint  import  check_commit_message , remove_comments 
21+ from  .exceptions  import  CommitlintException 
22+ from  .git_helpers  import  get_commit_message_of_hash , get_commit_messages_of_hash_range 
23+ from  .messages  import  VALIDATION_SUCCESSFUL 
2224
2325
2426def  get_args () ->  argparse .Namespace :
@@ -34,56 +36,130 @@ def get_args() -> argparse.Namespace:
3436    parser  =  argparse .ArgumentParser (
3537        description = "Check if a commit message follows the conventional commit format." 
3638    )
37-     parser .add_argument (
39+ 
40+     # for commit message check 
41+     group  =  parser .add_mutually_exclusive_group (required = True )
42+     group .add_argument (
3843        "commit_message" , nargs = "?" , type = str , help = "The commit message to be checked." 
3944    )
40-     parser .add_argument (
45+     group .add_argument (
4146        "--file" , type = str , help = "Path to a file containing the commit message." 
4247    )
48+     group .add_argument ("--hash" , type = str , help = "Commit hash" )
49+     group .add_argument ("--from-hash" , type = str , help = "From commit hash" )
50+     # --to-hash is optional 
51+     parser .add_argument ("--to-hash" , type = str , help = "To commit hash" , default = "HEAD" )
4352
53+     # parsing args 
4454    args  =  parser .parse_args ()
4555
46-     if  not  args .file  and  not  args .commit_message :
47-         parser .error ("Please provide either a commit message or a file." )
48- 
4956    return  args 
5057
5158
52- def  _show_errors (errors : List [str ]) ->  None :
59+ def  _show_errors (commit_message :  str ,  errors : List [str ]) ->  None :
5360    """ 
5461    Display a formatted error message for a list of errors. 
5562
5663    Args: 
5764        errors (List[str]): A list of error messages to be displayed. 
65+     """ 
66+     error_count  =  len (errors )
67+     commit_message  =  remove_comments (commit_message )
5868
59-     Returns: 
60-         None 
69+     sys .stderr .write (
70+         f"⧗ Input:\n { commit_message } \n \n ✖ Found { error_count } \n \n " 
71+     )
72+     for  index , error  in  enumerate (errors ):
73+         end_char  =  ""  if  index  ==  error_count  -  1  else  "\n " 
74+         sys .stderr .write (f"- { error } \n { end_char }  )
75+ 
76+ 
77+ def  _get_commit_message_from_file (filepath : str ) ->  str :
6178    """ 
62-     sys .stderr .write (f"✖ Found { len (errors )} \n \n " )
63-     for  error  in  errors :
64-         sys .stderr .write (f"- { error } \n \n " )
79+     Reads and returns the commit message from the specified file. 
6580
81+     Args: 
82+         filepath (str): The path to the file containing the commit message. 
6683
67- def  main () ->  None :
84+     Returns: 
85+         str: The commit message read from the file. 
86+ 
87+     Raises: 
88+         FileNotFoundError: If the specified file does not exist. 
89+         IOError: If there is an issue reading the file. 
6890    """ 
69-     Main function for cli to check a commit message. 
91+     abs_filepath  =  os .path .abspath (filepath )
92+     with  open (abs_filepath , encoding = "utf-8" ) as  commit_message_file :
93+         commit_message  =  commit_message_file .read ().strip ()
94+         return  commit_message 
95+ 
96+ 
97+ def  _handle_commit_message (commit_message : str ) ->  None :
7098    """ 
71-     args   =   get_args () 
99+     Handles a single commit message, checks its validity, and prints the result.  
72100
73-     if  args .file :
74-         commit_message_filepath  =  os .path .abspath (args .file )
75-         with  open (commit_message_filepath , encoding = "utf-8" ) as  commit_message_file :
76-             commit_message  =  commit_message_file .read ().strip ()
77-     else :
78-         commit_message  =  args .commit_message .strip ()
101+     Args: 
102+         commit_message (str): The commit message to be handled. 
79103
104+     Raises: 
105+         SystemExit: If the commit message is invalid. 
106+     """ 
80107    success , errors  =  check_commit_message (commit_message )
81108
82109    if  success :
83-         sys .stdout .write (f"{ COMMIT_SUCCESSFUL } \n " )
84-         sys .exit (0 )
110+         sys .stdout .write (f"{ VALIDATION_SUCCESSFUL } \n " )
85111    else :
86-         _show_errors (errors )
112+         _show_errors (commit_message , errors )
113+         sys .exit (1 )
114+ 
115+ 
116+ def  _handle_multiple_commit_messages (commit_messages : List [str ]) ->  None :
117+     """ 
118+     Handles multiple commit messages, checks their validity, and prints the result. 
119+ 
120+     Args: 
121+         commit_messages (List[str]): List of commit messages to be handled. 
122+ 
123+     Raises: 
124+         SystemExit: If any of the commit messages is invalid. 
125+     """ 
126+     has_error  =  False 
127+     for  commit_message  in  commit_messages :
128+         success , errors  =  check_commit_message (commit_message )
129+         if  not  success :
130+             has_error  =  True 
131+             _show_errors (commit_message , errors )
132+             sys .stderr .write ("\n " )
133+ 
134+     if  has_error :
135+         sys .exit (1 )
136+     else :
137+         sys .stdout .write (f"{ VALIDATION_SUCCESSFUL } \n " )
138+ 
139+ 
140+ def  main () ->  None :
141+     """ 
142+     Main function for cli to check a commit message. 
143+     """ 
144+     args  =  get_args ()
145+ 
146+     try :
147+         if  args .file :
148+             commit_message  =  _get_commit_message_from_file (args .file )
149+             _handle_commit_message (commit_message )
150+         elif  args .hash :
151+             commit_message  =  get_commit_message_of_hash (args .hash )
152+             _handle_commit_message (commit_message )
153+         elif  args .from_hash :
154+             commit_messages  =  get_commit_messages_of_hash_range (
155+                 args .from_hash , args .to_hash 
156+             )
157+             _handle_multiple_commit_messages (commit_messages )
158+         else :
159+             commit_message  =  args .commit_message .strip ()
160+             _handle_commit_message (commit_message )
161+     except  CommitlintException  as  ex :
162+         sys .stderr .write (f"{ ex } \n " )
87163        sys .exit (1 )
88164
89165
0 commit comments