17
17
import sys
18
18
from typing import List
19
19
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
22
24
23
25
24
26
def get_args () -> argparse .Namespace :
@@ -34,56 +36,130 @@ def get_args() -> argparse.Namespace:
34
36
parser = argparse .ArgumentParser (
35
37
description = "Check if a commit message follows the conventional commit format."
36
38
)
37
- parser .add_argument (
39
+
40
+ # for commit message check
41
+ group = parser .add_mutually_exclusive_group (required = True )
42
+ group .add_argument (
38
43
"commit_message" , nargs = "?" , type = str , help = "The commit message to be checked."
39
44
)
40
- parser .add_argument (
45
+ group .add_argument (
41
46
"--file" , type = str , help = "Path to a file containing the commit message."
42
47
)
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" )
43
52
53
+ # parsing args
44
54
args = parser .parse_args ()
45
55
46
- if not args .file and not args .commit_message :
47
- parser .error ("Please provide either a commit message or a file." )
48
-
49
56
return args
50
57
51
58
52
- def _show_errors (errors : List [str ]) -> None :
59
+ def _show_errors (commit_message : str , errors : List [str ]) -> None :
53
60
"""
54
61
Display a formatted error message for a list of errors.
55
62
56
63
Args:
57
64
errors (List[str]): A list of error messages to be displayed.
65
+ """
66
+ error_count = len (errors )
67
+ commit_message = remove_comments (commit_message )
58
68
59
- Returns:
60
- None
69
+ sys .stderr .write (
70
+ f"⧗ Input:\n { commit_message } \n \n ✖ Found { error_count } error(s).\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 :
61
78
"""
62
- sys .stderr .write (f"✖ Found { len (errors )} 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.
65
80
81
+ Args:
82
+ filepath (str): The path to the file containing the commit message.
66
83
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.
68
90
"""
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 :
70
98
"""
71
- args = get_args ()
99
+ Handles a single commit message, checks its validity, and prints the result.
72
100
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.
79
103
104
+ Raises:
105
+ SystemExit: If the commit message is invalid.
106
+ """
80
107
success , errors = check_commit_message (commit_message )
81
108
82
109
if success :
83
- sys .stdout .write (f"{ COMMIT_SUCCESSFUL } \n " )
84
- sys .exit (0 )
110
+ sys .stdout .write (f"{ VALIDATION_SUCCESSFUL } \n " )
85
111
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 " )
87
163
sys .exit (1 )
88
164
89
165
0 commit comments