Created
November 20, 2024 23:37
-
-
Save zanderwar/b9ce13d59f36b579fb20f997ac6473e2 to your computer and use it in GitHub Desktop.
Conventional Commits CLI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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