-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoCommit.sh
executable file
·196 lines (169 loc) · 5.4 KB
/
doCommit.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/bin/bash
# Dedicated script to facilitate the creation of new commit message
# following conventional commits specs.
#
# The script will guide the end-user step by step to collect all required
# information to generate appropriate commit message
#
# Author : Jacques Raphanel
# Version: 1.2
#
COLOR_RESET='\033[0m'
COLOR_ERROR='\033[31m'
COLOR_SELECTED='\e[32m'
COLOR_INFO='\033[94m'
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
ctrl_c() {
tput cnorm
exit 1
}
# Print an error message through stderr
echo_err() {
printf "${COLOR_ERROR}ERROR: %s${COLOR_RESET}\n" "$@" >&2
}
# Print a normal text
echo_msg() {
printf "%s\n" "$@"
}
# Print a selected text
echo_selected() {
printf "${COLOR_SELECTED}%s${COLOR_RESET}\n" "$@"
}
# Print an informative text
echo_info() {
printf "${COLOR_INFO}%s${COLOR_RESET}\n" "$@"
}
# selected_item, ...menu_items
print_menu() {
local function_arguments=($@)
local selected_item="$1"
local menu_items=(${function_arguments[@]:1})
local menu_size="${#menu_items[@]}"
#for item in `echo "${menu_items[@]}"`; do
for (( i = 0; i < $menu_size; ++i )); do
if [ "$i" = "$selected_item" ]; then
echo_selected "-> ${menu_items[$i]}"
else
echo_msg " ${menu_items[$i]}"
fi
done
}
# selected_item, ...menu_items
function run_menu() {
IFS=""
local function_arguments=("$@")
local selected_item="$1"
local menu_items=(${function_arguments[@]:1})
local menu_size="${#menu_items[@]}"
local menu_limit=$((menu_size - 1))
local timeout=0.1
if [ "$(uname -s)" = "Darwin" ]; then
timeout=1
fi
tput civis
tput sc
print_menu "$selected_item" "${menu_items[@]}"
while read -rsn1 input
do
case "$input"
in
$'\x1B') # ESC ASCII code (https://dirask.com/posts/ASCII-Table-pJ3Y0j)
read -rsn1 -t $timeout input
if [ "$input" = "[" ]; then
# occurs before arrow code
read -rsn1 -t $timeout input
case "$input" in
A) # Up Arrow
if [ "$selected_item" -ge 1 ]; then
selected_item=$((selected_item - 1))
tput rc
tput sc
print_menu "$selected_item" "${menu_items[@]}"
fi
;;
B) # Down Arrow
if [ "$selected_item" -lt "$menu_limit" ]; then
selected_item=$((selected_item + 1))
tput rc
tput sc
print_menu "$selected_item" "${menu_items[@]}"
fi
;;
esac
fi
read -rsn5 -t $timeout # flushing stdin
;;
"") # Enter key
tput cnorm
return "$selected_item"
;;
esac
done
}
check_stagged_files() {
IFSOLD=$IFS
IFS=$'\n'
local fileslist=($(git diff --cached --name-only 2>/dev/null))
if [ -z "${fileslist}" ]; then
echo_err "no file stagged yet"
exit 1
fi
echo_info "Please find below the list of stagged files:"
for file in "${fileslist[@]}"; do
echo " $file"
done
IFS=$IFSOLD
}
# Clear screen to focus on git commit operation
clear
# Ensure that at least one file is stagged
check_stagged_files
echo ""
echo ""
# Select the commit type
selected_item=0
menu_items=('feat: A new feature' )
menu_items+=('fix: A bug fix' )
menu_items+=('doc: Documentation only changes' )
menu_items+=('style: Changes that do not affect the meaning of the code (white-space, formatting, ...)')
menu_items+=('refactor: A code change that neither fixes a bug or adds a feature')
menu_items+=('perf: A code change that improves performance')
menu_items+=('test: Add missing tests')
menu_items+=('build: Changes to to the build process')
menu_items+=('chore: Changes that are not related to a fix or feature and do not modify the source or test files')
echo_info "? Select the type of change that you're commiting: (Use arrow keys)"
run_menu "$selected_item" "${menu_items[@]}"
menu_result="$?"
ctype=$(echo ${menu_items[$menu_result]} | cut -d: -f1)
# Enter the commit's scope
echo ""
echo_info "? An optional scope MAY be provided after a type. A scope is a phrase describing a section of the codebase."
read -p "Enter a custom commit's scope: " scope
# Enter short description/subject
subject=""
while [ -z "${subject// /}" ]; do
echo ""
echo_info "? A description MUST immediately follow the type/scope prefix. The description is a short description of the changes."
read -p "Enter a custom commit's description: " subject
done
# Enter long description/body
echo ""
echo_info "? A longer commit body MAY be provided after the short description."
body=""
while true; do
[ -z "$body" ] && read -p "Enter a commit's body: " line || read line
[ -z "$line" ] && break || true
[ -n "$body" ] && body+=$'\n' || true
body+="$line"
done
msg="${ctype}"
if [ -n "${scope}" ]; then
msg+="(${scope})"
fi
msg+=": $subject"
if [ -n "${body}" ]; then
msg+=$'\n\n'
msg+="${body}"
fi
git commit -m "$msg" "$@"