I wrote the following Bash function to use the OpenAI API to automatically come up with a git commit message and put it on the clipboard. Do you have any constructive criticisms or suggestions to make it better?
Here is the entire Bash file contents:
#!/usr/bin/env bash
git_commit_ai() {
if ! defined? OPENAI_API_KEY; then
echo "OPENAI_API_KEY is not defined." >&2
return 1
fi
local model request response timeout diff temp_json message
diff=$(git diff)
if [[ -z "$diff" ]]; then
diff=$(git diff --cached)
fi
if [[ -z "$diff" ]]; then
echo "No changes to commit." >&2
return 1
fi
model=${ASK_MODEL:-gpt-3.5-turbo-0301};
timeout=${ASK_TIMEOUT:-15}
temp_json=$(mktemp)
jq -n --arg model "$model" --arg diff "$diff" '{
model: $model,
messages: [
{role: "system", content: "You are a senior developer."},
{role: "user", content: "Generate a commit message for the following git diff. If there does not appear to be diff data, please say so instead:\n\n\($diff)\n\nCommit message: "}
],
max_tokens: 150,
n: 1,
stop: null,
temperature: 0.7
}' > "$temp_json"
response=$(curl -s -X POST https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
--silent \
--max-time "$timeout" \
-d "@$temp_json")
response=$(printf '%s' "$response" | jq -r '.choices[0].message.content' | sed 's/^[ \t]*//;s/[ \t]*$//')
message=$response
[ -f "$temp_json" ] && rm "$temp_json"
if [[ "$(uname)" == "Darwin" ]]; then
echo -n "git commit -m \"$message\"" | pbcopy
else
echo -n "git commit -m \"$message\"" | xclip -selection clipboard
fi
echo "Commit command copied to clipboard:"
echo "git commit -m \"$message\""
}
alias gcai=git_commit_ai
Your Bash function seems to be a useful tool for generating Git commit messages using OpenAI API. Here are some suggestions and improvements to consider:
- Use the
function
keyword for better readability:
function git_commit_ai() {
# ...
}
- Change the condition for checking if
OPENAI_API_KEY
is defined. The current code uses thedefined?
command, which is not valid in Bash. Instead, use the-z
operator to check if the variable is empty:
if [[ -z "$OPENAI_API_KEY" ]]; then
echo "OPENAI_API_KEY is not defined." >&2
return 1
fi
- Increase reliability when creating temporary files by specifying a template and the
/tmp
directory:
temp_json=$(mktemp -t git_commit_ai.XXXXXX --tmpdir)
- Use the
trap
command to ensure that the temporary JSON file is removed even if the script is interrupted or encounters an error:
trap 'rm -f "$temp_json"' EXIT
- For better error handling, you can check if the API request was successful or if there was an error. You can do this by checking the HTTP status code returned by the API request:
http_status=$(curl -w "%{http_code}" -s -o "$temp_json" -X POST https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
--silent \
--max-time "$timeout" \
-d "@$temp_json")
if [[ "$http_status" -ne 200 ]]; then
echo "Error: API request failed with status code $http_status." >&2
return 1
fi
Here's the updated Bash function with the suggested changes:
#!/usr/bin/env bash
function git_commit_ai() {
if [[ -z "$OPENAI_API_KEY" ]]; then
echo "OPENAI_API_KEY is not defined." >&2
return 1
fi
local model request response timeout diff temp_json message http_status
diff=$(git diff)
if [[ -z "$diff" ]]; then
diff=$(git diff --cached)
fi
if [[ -z "$diff" ]]; then
echo "No changes to commit." >&2
return 1
fi
model=${ASK_MODEL:-gpt-3.5-turbo-0301}
timeout=${ASK_TIMEOUT:-15}
temp_json=$(mktemp -t git_commit_ai.XXXXXX --tmpdir)
trap 'rm -f "$temp_json"' EXIT
jq -n --arg model "$model" --arg diff "$diff" '{
model: $model,
messages: [
{role: "system", content: "You are a senior developer."},
{role: "user", content: "Generate a commit message for the following git diff. If there does not appear to be diff data, please say so instead:\n\n\($diff)\n\nCommit message: "}
],
max_tokens: 150,
n: 1,
stop: null,
temperature: 0.7
}' > "$temp_json"
http_status=$(curl -w "%{http_code}" -s -o "$temp_json" -X POST https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN
please finish
I apologize for the abrupt ending. Here's the rest of the updated Bash function:
-H "Authorization: Bearer $OPENAI_API_KEY" \
--silent \
--max-time "$timeout" \
-d "@$temp_json")
if [[ "$http_status" -ne 200 ]]; then
echo "Error: API request failed with status code $http_status." >&2
return 1
fi
response=$(jq -r '.choices[0].message.content' < "$temp_json" | sed 's/^[ \t]*//;s/[ \t]*$//')
message=$response
if [[ "$(uname)" == "Darwin" ]]; then
echo -n "git commit -m \"$message\"" | pbcopy
else
echo -n "git commit -m \"$message\"" | xclip -selection clipboard
fi
echo "Commit command copied to clipboard:"
echo "git commit -m \"$message\""
}
alias gcai=git_commit_ai
These changes should improve the overall reliability and error handling of your Bash function for generating Git commit messages using the OpenAI API.