|
1 | | -echo "Type of change" |
2 | | -echo "Scope of this change" |
3 | | -echo "Short description" |
4 | | -echo "Long description" |
5 | | -echo "Breaking changes" |
6 | | -echo "Closed issues" |
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Color formatting |
| 4 | +RED="\033[0;31m" |
| 5 | +GREEN="\033[0;32m" |
| 6 | +BLUE="\033[1;34m" |
| 7 | +CYAN="\033[0;36m" |
| 8 | +RESET="\033[0m" |
| 9 | + |
| 10 | +# Valid types |
| 11 | +TYPES=("feat" "fix" "docs" "style" "refactor" "pref" "test" "build" "ci" "chore" "revert") |
| 12 | +NUMBERS=("1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11") |
| 13 | + |
| 14 | +# Type section |
| 15 | +printf "${BLUE}>>> Type of change (name or number)?${RESET}\n\n" |
| 16 | + |
| 17 | +printf "${CYAN}1. feat${RESET} - A new feature.\n" |
| 18 | +printf "${CYAN}2. fix${RESET} - A bug fix.\n" |
| 19 | +printf "${CYAN}3. docs${RESET} - Documentation only changes.\n" |
| 20 | +printf "${CYAN}4. style${RESET} - Changes that do notaffect the meaning of the code (white-space, formatting, missing semi-colons, etc).\n" |
| 21 | +printf "${CYAN}5. refactor${RESET} - A Code change that neither fixes a bug nor adds a feature.\n" |
| 22 | +printf "${CYAN}6. pref${RESET} - A code change that improves performance.\n" |
| 23 | +printf "${CYAN}7. test${RESET} - Adding missing tests or correcting existing tests.\n" |
| 24 | +printf "${CYAN}8. build${RESET} - Changes that effect the build system or external dependencies (example scopes: glup, broccoli, npm).\n" |
| 25 | +printf "${CYAN}9. ci${RESET} - Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs).\n" |
| 26 | +printf "${CYAN}10. chore${RESET} - Other changes that don't modify src or test files.\n" |
| 27 | +printf "${CYAN}11. revert${RESET} - Reverts a previous commit.\n\n" |
| 28 | + |
| 29 | +while :; do |
| 30 | + read TYPE |
| 31 | + # To lower case |
| 32 | + TYPE=${TYPE,,} |
| 33 | + # When input type is valid loop break |
| 34 | + if [[ " ${NUMBERS[*]} " =~ " ${TYPE} " ]]; then |
| 35 | + TYPE="${TYPES[TYPE - 1]}" |
| 36 | + break |
| 37 | + elif [[ " ${TYPES[*]} " =~ " ${TYPE} " ]]; then |
| 38 | + break |
| 39 | + else |
| 40 | + printf "${RED}❌ Please select a valid type.${RESET}\n" |
| 41 | + fi |
| 42 | +done |
| 43 | + |
| 44 | +# Scppe section |
| 45 | +printf "\n${BLUE}>>> Scope of this change (optional)?${RESET}\n" |
| 46 | +printf "The scope could be anything specifying place of the commit change e.g a file name, function name, class name, component name etc.\n\n" |
| 47 | +read SCOPE |
| 48 | + |
| 49 | +# Subject section |
| 50 | +printf "\n${BLUE}>>> Short description?${RESET}\n" |
| 51 | +printf "The short description contains succinct description of the change:\n" |
| 52 | +printf ' • use the imperative, present tense: "change" not "changed" nor "changes"\n' |
| 53 | +printf " • don't capitalize first letter\n" |
| 54 | +printf " • no dot (.) at the end\n\n" |
| 55 | + |
| 56 | +while :; do |
| 57 | + read SHORT_DESC |
| 58 | + if [ -z "$SHORT_DESC" ]; then |
| 59 | + printf "${RED}❌ Short description can not be empty.${RESET}\n" |
| 60 | + else |
| 61 | + break |
| 62 | + fi |
| 63 | +done |
| 64 | + |
| 65 | +# Description section |
| 66 | +printf "\n${BLUE}>>> Long description (optional)?${RESET}\n" |
| 67 | +printf "The body should include the motivation for the change and contrast this with previous behavior.\n\n" |
| 68 | +read LONG_DESC |
| 69 | + |
| 70 | +# Breaking changes section |
| 71 | +printf "\n${BLUE}>>> Breaking changes (optional)?${RESET}\n" |
| 72 | +printf "note the reason for a breaking change within the commit.\n\n" |
| 73 | +read BREAKING_CHANGES |
| 74 | + |
| 75 | +# Closed issues section |
| 76 | +printf "\n${BLUE}>>> Closed issues (optional)?${RESET}\n" |
| 77 | +printf "The syntax for closing keywords depends on whether the issue is in the same repository as the pull request.\n" |
| 78 | +printf " • Issue in the same repository -> Closes #10\n" |
| 79 | +printf " • Issue in a different repository -> Fixes octo-org/octo-repo#100\n" |
| 80 | +printf " • Multiple issues -> Resolves #10, resolves #123, resolves octo-org/octo-repo#100\n\n" |
| 81 | +read CLOSED_ISSUES |
| 82 | + |
| 83 | +# Result section |
| 84 | +if [ ! -z "$SCOPE" ]; then |
| 85 | + SCOPE="(${SCOPE})" |
| 86 | +fi |
| 87 | + |
| 88 | +if [ ! -z "$BREAKING_CHANGES" ]; then |
| 89 | + BREAKING_CHANGES="BREAKING CHANGE: ${BREAKING_CHANGES}" |
| 90 | +fi |
| 91 | + |
| 92 | +echo |
| 93 | +echo "${GREEN}${TYPE}${SCOPE}: ${SHORT_DESC} |
| 94 | +
|
| 95 | +${LONG_DESC} |
| 96 | +
|
| 97 | +${BREAKING_CHANGES} |
| 98 | +
|
| 99 | +${CLOSED_ISSUES}${RESET}" | awk "{gsub(/[ \t]+$/,""); print $0}" |
| 100 | +echo |
| 101 | + |
| 102 | +# Git commit |
| 103 | +RESULT_CODE=$? |
| 104 | +if [ "$RESULT_CODE" = 0 ]; then |
| 105 | + git commit -m "${TYPE}${SCOPE}: ${SHORT_DESC} |
| 106 | +
|
| 107 | +${LONG_DESC} |
| 108 | + |
| 109 | +${BREAKING_CHANGES} |
| 110 | + |
| 111 | +${CLOSED_ISSUES}" |
| 112 | +else |
| 113 | + printf "\n${RED}❌ An error occurred. Please try again.${RESET}\n" |
| 114 | +fi |
0 commit comments