Skip to content

Instantly share code, notes, and snippets.

@zanderwar
Created November 20, 2024 23:37
Show Gist options
  • Save zanderwar/b9ce13d59f36b579fb20f997ac6473e2 to your computer and use it in GitHub Desktop.
Save zanderwar/b9ce13d59f36b579fb20f997ac6473e2 to your computer and use it in GitHub Desktop.
Conventional Commits CLI
#!/bin/bash
# Interactive CLI for generating conventional commit messages (https://www.conventionalcommits.org/en/v1.0.0/)
# Enabling easier adoption of this convention for engineers
type=""
description=""
body=""
footer=""
doadd=""
githooks=""
print_help() {
echo "Interactive CLI for generating commit messages."
echo ""
echo "Usage: commit [options]"
echo ""
echo "Example: commit --feat -m \"Adds new feature\""
echo "Example: commit -m \"Adds new feature\""
echo "Example: commit"
echo ""
echo "Options:"
echo " --feat: New Feature"
echo " --fix: Bug Fix"
echo " --docs: Documentation"
echo " --style: Code Style"
echo " --refactor: Refactoring"
echo " --perf: Performance"
echo " --test: Testing"
echo " --build: Build System"
echo " --ci: Continuous Integration"
echo " --chore: Chores"
echo " --revert: Revert Changes"
echo " -m: Set the description directly"
echo " -a: Add all changed files to the commit"
echo " -n: Bypass githooks"
}
# Check for initial flags
while [[ "$1" != "" ]]; do
case $1 in
--feat|--fix|--docs|--style|--refactor|--perf|--test|--build|--ci|--chore|--revert)
type="${1#--}"
;;
-m)
shift
description="$1"
;;
-h|--help)
print_help
exit
;;
-a)
doadd="y"
;;
-n)
githooks="y"
;;
*)
echo "Invalid option: $1"
print_help
exit 1
;;
esac
shift
done
# Function to prompt for a selection
prompt_choice() {
PS3="Please choose a number from above: "
options=("feat: New Feature" "fix: Bug Fix" "docs: Documentation" "style: Code Style" "refactor: Refactoring" "perf: Performance" "test: Testing" "build: Build System" "ci: Continuous Integration" "chore: Chores" "revert: Revert Changes")
select opt in "${options[@]}"; do
if [[ -n "$opt" ]]; then
echo "${opt%%:*}"
break
else
echo "Invalid choice. Please select a number from the list."
fi
done
}
if [[ -z "$type" ]]; then
echo -e '\033[0;32m---\033[0m'
echo -e '\033[0;32mSelect a commit type from the following options:\033[0m'
echo -e '\033[0;32m---\033[0m'
# Prompt for commit type
type=$(prompt_choice)
fi
echo -e '\033[0;32m---\033[0m'
echo -e '\033[0;32mSelect a scope this work applies to. If none of these apply, choose custom.\033[0m'
echo -e '\033[0;32m---\033[0m'
# Prompt for optional scope
options=(
"none: No scope"
"core: Core functionality"
"deps: Dependencies"
"cache: Caching"
"jobs: Jobs"
"users: Users"
"locale: Localization"
"auth: Authentication"
"hotfix: Hotfix"
"misc: Miscellaneous"
"custom: Enter your own..."
)
PS3="Please choose a number from above: "
select scope in "${options[@]}"; do
if [[ "$scope" == "custom" ]]; then
read -p "Enter custom scope: " custom_scope
scope=$custom_scope
else
scope=${scope%%:*}
fi
if [[ "$scope" == "none" ]]; then
scope=""
fi
if [[ -n "$scope" ]]; then
break
else
echo "Invalid choice. Please select a number from the list."
fi
done
# Prompt for commit description
if [[ -z "$description" ]]; then
while true; do
read -p "Enter a brief description of the change: " description
if [[ -n "$description" ]]; then
break
else
echo "Description is required."
fi
done
# Prompt for optional longer body
read -p "Enter a longer description (optional): " body
# Prompt for optional footer, typically used for breaking changes or issues
read -p "Enter footer (optional, e.g., BREAKING CHANGE: description): " footer
fi
# Build the commit message
scope_part=""
if [[ -n "$scope" ]]; then
scope_part="($scope)"
fi
commit_message="${type}${scope_part}: ${description}"
if [[ -n "$body" ]]; then
commit_message+="\n\n${body}"
fi
if [[ -n "$footer" ]]; then
commit_message+="\n\n${footer}"
fi
if [[ -n "$doadd" ]]; then
git add .
else
read -p "Would you like to add all changed files to the commit? (y/n): " doadd
if [[ "$doadd" == "" || "$doadd" == "y" || "$doadd" == "Y" || "$doadd" == "yes" || "$doadd" == "Yes" || "$doadd" == "YES" ]]; then
git add .
fi
fi
# Display the commit message
echo -e "\nGenerated commit message:\n"
echo -e "\033[0;32m-----------------------------\033[0m"
echo -e "\033[0;32m \033[0m"
echo -e "\033[0;32m$commit_message \033[0m"
echo -e "\033[0;32m \033[0m"
echo -e "\033[0;32m-----------------------------\033[0m"
# Option to save to clipboard (optional)
read -p "Would you like to commit with this message now? (y/n): " docommit
if [[ "$docommit" == "" || "$docommit" == "y" || "$docommit" == "Y" || "$docommit" == "yes" || "$docommit" == "Yes" || "$docommit" == "YES" ]]; then
if [[ "$githooks" == "y" || "$githooks" == "Y" || "$githooks" == "yes" || "$githooks" == "Yes" || "$githooks" == "YES" ]]; then
git commit -m "$commit_message" -n
else
git commit -m "$commit_message"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment