77from dotenv import load_dotenv
88from openai import OpenAI , APIError
99
10+ # Regex pattern to detect conventional commits
11+ SEMANTIC_COMMIT_REGEX = re .compile (
12+ r"^(feat|fix|docs|chore|refactor|style|test|build|ci|perf)(\([\w\-]+\))?!?:\s.+"
13+ )
14+
15+ def is_semantic_commit (message ):
16+ """Check if the given commit message follows the Conventional Commit format."""
17+ return bool (SEMANTIC_COMMIT_REGEX .match (message ))
18+
1019def get_recent_scopes (max_commits = 20 ):
1120 """
1221 Retrieve the last `max_commits` commit subjects and
@@ -90,21 +99,26 @@ def main():
9099
91100 raw_message = " " .join (sys .argv [1 :])
92101
93- # 3. Retrieve the set of known scopes from recent commits
102+ # 3. Check if the message is already in conventional commit format
103+ if is_semantic_commit (raw_message ):
104+ print (raw_message ) # Print as-is and exit
105+ sys .exit (0 )
106+
107+ # 4. Retrieve the set of known scopes from recent commits
94108 known_scopes = get_recent_scopes (max_commits = 1000 )
95109 scopes_list = ", " .join (sorted (known_scopes )) if known_scopes else "none"
96110
97- # 4 . Gather local diff & detect potential break
111+ # 5 . Gather local diff & detect potential break
98112 diff_text = get_staged_diff ()
99113 if not diff_text .strip ():
100114 suspected_breaking = "false"
101115 else :
102116 suspected_breaking = detect_breaking_change (diff_text )
103117
104- # 5 . Gather staged files
118+ # 6 . Gather staged files
105119 staged_files = "\n " .join (get_staged_files ())
106120
107- # 6 . Prepare a system prompt that instructs the model
121+ # 7 . Prepare a system prompt that instructs the model
108122 system_prompt = f"""\
109123 You are an assistant that converts any given commit message into a Conventional Commit message.
110124Follow these rules:
@@ -121,11 +135,11 @@ def main():
121135{ staged_files }
122136"""
123137
124- # 7 . Instantiate the OpenAI client
138+ # 8 . Instantiate the OpenAI client
125139 client = OpenAI (api_key = api_key )
126140
127141 try :
128- # 8 . Send the request to the Chat Completions endpoint
142+ # 9 . Send the request to the Chat Completions endpoint
129143 response = client .chat .completions .create (
130144 model = "gpt-4o" , # from docs, or use e.g. "gpt-4" or "gpt-3.5-turbo" if supported
131145 messages = [
@@ -134,10 +148,10 @@ def main():
134148 ],
135149 temperature = 0.2 ,
136150 )
137- # 9 . Extract the AI-generated commit message
151+ # 10 . Extract the AI-generated commit message
138152 semantic_commit = response .choices [0 ].message .content .strip ()
139153
140- # 10 . remove ``` from the response
154+ # 11 . remove ``` from the response
141155 semantic_commit = semantic_commit .replace ("```\n " , "" )
142156 semantic_commit = semantic_commit .replace ("\n ```" , "" )
143157
0 commit comments