nix/bin/gc

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"