130 lines
2.6 KiB
Bash
Executable file
130 lines
2.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# Conventional commit helper
|
|
# Usage: gc [type] [message] [-s scope] [-b] [-B body]
|
|
# gc (interactive mode)
|
|
|
|
set -o errexit
|
|
set -o nounset
|
|
|
|
TYPES="feat fix docs style refactor test chore perf ci build"
|
|
|
|
usage() {
|
|
echo "Usage: gc [type] [message] [-s scope] [-b] [-B body]"
|
|
echo " gc (interactive mode)"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -s, --scope Scope of the change"
|
|
echo " -b, --breaking Mark as breaking change (!)"
|
|
echo " -B, --body Commit body (longer description)"
|
|
echo ""
|
|
echo "Types: $TYPES"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " gc feat 'add user auth'"
|
|
echo " gc fix 'resolve crash' -s api # fix(api): resolve crash"
|
|
echo " gc feat 'new api' -b # feat!: new api"
|
|
echo " gc feat 'new api' -s auth -b # feat(auth)!: new api"
|
|
echo " gc feat 'big change' -B 'Details here'"
|
|
exit 1
|
|
}
|
|
|
|
build_message() {
|
|
local type="$1"
|
|
local scope="$2"
|
|
local breaking="$3"
|
|
local msg="$4"
|
|
local body="$5"
|
|
|
|
local commit_msg="$type"
|
|
|
|
if [ -n "$scope" ]; then
|
|
commit_msg+="($scope)"
|
|
fi
|
|
|
|
if [ "$breaking" = "true" ]; then
|
|
commit_msg+="!"
|
|
fi
|
|
|
|
commit_msg+=": $msg"
|
|
|
|
if [ -n "$body" ]; then
|
|
commit_msg+=$'\n\n'"$body"
|
|
fi
|
|
|
|
echo "$commit_msg"
|
|
}
|
|
|
|
# Interactive mode if no args
|
|
if [ $# -eq 0 ]; then
|
|
echo "Types: $TYPES"
|
|
printf "Type: "
|
|
read -r type
|
|
printf "Scope (optional): "
|
|
read -r scope
|
|
printf "Breaking change? [y/N]: "
|
|
read -r breaking_input
|
|
printf "Message: "
|
|
read -r msg
|
|
printf "Body (optional, enter for none): "
|
|
read -r body
|
|
|
|
breaking="false"
|
|
if [[ $breaking_input =~ ^[Yy] ]]; then
|
|
breaking="true"
|
|
fi
|
|
|
|
commit_msg=$(build_message "$type" "$scope" "$breaking" "$msg" "$body")
|
|
git commit -m "$commit_msg"
|
|
exit 0
|
|
fi
|
|
|
|
# Parse arguments
|
|
type=""
|
|
msg=""
|
|
scope=""
|
|
breaking="false"
|
|
body=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-s | --scope)
|
|
scope="$2"
|
|
shift 2
|
|
;;
|
|
-b | --breaking)
|
|
breaking="true"
|
|
shift
|
|
;;
|
|
-B | --body)
|
|
body="$2"
|
|
shift 2
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
;;
|
|
*)
|
|
if [ -z "$type" ]; then
|
|
type="$1"
|
|
else
|
|
msg="$1"
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Validate type
|
|
if ! echo "$TYPES" | grep -qw "$type"; then
|
|
echo "Invalid type: $type"
|
|
echo "Valid types: $TYPES"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$msg" ]; then
|
|
echo "Message required"
|
|
usage
|
|
fi
|
|
|
|
commit_msg=$(build_message "$type" "$scope" "$breaking" "$msg" "$body")
|
|
git commit -m "$commit_msg"
|