-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgenchlog.sh
executable file
·251 lines (205 loc) · 7.62 KB
/
genchlog.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/usr/bin/env bash
#echo "$0 Your script args ($#) are: $@"
# delta to diplay messages is from
# a) HEAD to latest tag
# b) Tag and previous tag
# Params needed
# 1: Tag/Commit Hash as current
# 2: Filename to write
# EnvVars needed
# PROJECT > Projectname used in Heading
# INTENT_PREFIXES > Bash Array ( sss sss sss ) with prefixes to look fo ( Feat Fix )
# Fix: Error when deviding by zero #KEY-123
# INTENT_NAMES > Bash Array ( sss sss sss ) with Full names for prefixes eg ( Features Fixes )
# TICKET_URL > URL to concat with fouond ticket
# TICKET_MATCH > regexp to match ticketkey eg: "[A-Z]\+-[0-9]\+"
usage() {
echo -e "${BWHITE}$0${NC} - generate a markdown file which represents"
echo -e " your changes grouped by defined prefixes"
echo ""
echo -e "${BWHITE}Usage:${NC}"
echo -e " $0 --end <hash|tag> [--start <hash|tag>] --file reports/changelog/changelog.md"
echo ""
echo -e "${BWHITE}Configuration${NC} (required when using this feature build.env)"
echo -e " PROJECT > Projectname used in Heading"
echo -e " INTENT_PREFIXES > Bash Array ( String String String ) with prefixes to look fo ( Feat Fix )"
echo -e " Fix: Error when deviding by zero #KEY-123"
echo -e " INTENT_NAMES > Bash Array ( String String String ) with Full names for prefixes eg ( Features Fixes )"
echo -e " INTENT_ELSE > When no intent in matched or INTENT_PREFIXES is not defined"
echo -e " All other staff goes hier"
echo -e " TICKET_URL > URL to concat with found ticket"
echo -e " TICKET_MATCH > regexp to match ticketkey eg: \"[A-Z]\+-[0-9]\+\""
echo ""
echo -e "${BWHITE}Options:${NC}"
echo -e " -h | --help - Show this screen"
echo -e " -d | --debug - Show additionaly output messages"
echo -e " -e | --end <hash|tag> - Optional hash or tag to determine the difference to the start, defaults to HEAD"
echo -e " -s | --start <hash|tag> - Optional hash or tag to determine the difference to the end, defaults to previous tag found"
echo -e " -f | --file <filename.md> - Required filename the changelog get written to"
echo ""
echo -e "${BWHITE}Examples:${NC}"
echo -e " $0 --file changelog.md"
echo -e " $0 --end ba12010a --file reports/changelog/changelog.md"
echo -e " $0 --end HEAD --start 1.0.0 --file reports/changelog/changelog.md"
exit 1
}
# get required functions and vars
if [[ $LIBSOURCED != "TRUE" ]]; then
source ./.dbFlow/lib.sh
fi
# set project-settings from build.env if exists
if [[ -e ./build.env ]]; then
source ./build.env
fi
function check_vars() {
timelog "Checking Vars" ${info}
# check require vars from build.env
do_exit="NO"
if [[ -z ${PROJECT:-} ]]; then
echo_error "undefined var: PROJECT"
do_exit="YES"
fi
####
if [[ ${do_exit} == "YES" ]]; then
echo_warning "aborting"
exit 1;
fi
}
function check_params() {
debug="n" help="n" start="-" end=HEAD file="changelog.md"
while getopts_long 'dhs:e:f: debug help start: end: file:' OPTKEY "${@}"; do
echo "OPTKEY: ${OPTKEY}"
case ${OPTKEY} in
'd'|'debug')
d=y
;;
'h'|'help')
h=y
;;
'f'|'file')
file="${OPTARG}"
;;
's'|'start')
start="${OPTARG}"
;;
'e'|'end')
end="${OPTARG}"
;;
'?')
echo_error "INVALID OPTION -- ${OPTARG}" >&2
usage
;;
':')
echo_error "MISSING ARGUMENT for option -- ${OPTARG}" >&2
usage
;;
*)
echo_error "UNIMPLEMENTED OPTION -- ${OPTKEY}" >&2
usage
;;
esac
done
# help first
if [[ -n ${h} ]] && [[ ${h} == "y" ]]; then
usage
fi
if git cat-file -e $end 2> /dev/null; then
current_tag=$end
else
timelog "End Commit or Tag $end not found" ${failure}
exit 1
fi
if [[ $start != "-" ]]; then
if git cat-file -e $start 2> /dev/null; then
previous_tag=$start
else
timelog "Start Commit or Tag $start not found" ${failure}
exit 1
fi
else
if [[ ${current_tag} == "HEAD" ]]; then
previous_tag=$(git describe --tags --abbrev=0 --always)
else
previous_tag=$(git tag --sort=-creatordate | grep -A 1 ${current_tag} | tail -n 1) || true
fi
fi
# if start and end are the same at head, we put all into the change log
# otherwise we had to look for a previous commit: git log --format="%H" -n 2 | tail -1
if [[ ${current_tag} == "HEAD" ]]; then
current_commit=$(git rev-parse HEAD)
if [[ ${current_commit} == ${previous_tag} ]]; then
previous_tag=$(git log --max-parents=0 HEAD --pretty=format:%H)
fi
fi
targetfile=${file}
}
function gen_changelog() {
timelog "Generating Changelog ${current_tag}...${previous_tag}" ${info}
# define log
changetime=`date "+%Y%m%d%H%M%S"`
logf=changelog_${changetime}.md
tag_date=$(git log -1 --pretty=format:'%ad' --date=short ${current_tag})
printf "# ${PROJECT} - Changelog\n\n" > ${logf}
printf "## ${current_tag} (${tag_date})\n\n" >> ${logf}
if [[ -n ${INTENT_PREFIXES} ]]; then
for intent in "${!INTENT_PREFIXES[@]}"; do
readarray -t fixes <<< $(git log ${current_tag}...${previous_tag} --pretty="%s" --reverse | grep -v Merge | grep "^${INTENT_PREFIXES[$intent]}: *")
eval fixes=($(printf "%q\n" "${fixes[@]}" | sort -u))
if [[ ${#fixes[@]} -gt 0 ]] && [[ ${fixes[0]} != "" ]]; then
printf "### ${INTENT_NAMES[$intent]}\n\n" >> ${logf}
for fix in "${fixes[@]}"; do
fix_line=${fix/"${INTENT_PREFIXES[$intent]}: "/}
fix_issue=""
if [[ -n ${TICKET_MATCH} ]]; then
fix_issue=$(echo "${fix_line}" | grep -e "${TICKET_MATCH}" -o || true)
fi
echo_line=""
if [[ $fix_issue != "" ]] && [[ -n ${TICKET_URL} ]]; then
echo_line="* ${fix_line} [View]($(force_trailing_slash ${TICKET_URL})${fix_issue})" >> ${logf}
else
echo_line="* ${fix_line}" >> ${logf}
fi
grep -qxF "${echo_line}" ${logf} || echo "${echo_line}" >> ${logf}
done
printf "\n\n" >> ${logf}
fi;
done
fi
# when INTENT_ELSE is defined output goes here
if [[ -n ${INTENT_ELSE} ]]; then
intent_pipes=$(printf '%s|' "${INTENT_PREFIXES[@]}" | sed 's/|$//')
readarray -t fixes <<< $(git log ${current_tag}...${previous_tag} --pretty="%s" --reverse | grep -v Merge | grep -v -E "^${intent_pipes}: *")
eval fixes=($(printf "%q\n" "${fixes[@]}" | sort -u))
if [[ ${#fixes[@]} -gt 0 ]] && [[ ${fixes[0]} != "" ]]; then
if [[ -n ${INTENT_PREFIXES} ]]; then
printf "### ${INTENT_ELSE}\n\n" >> ${logf}
fi
for fix in "${fixes[@]}"; do
fix_line=${fix}
fix_issue=$(echo "${fix_line}" | grep -e "${TICKET_MATCH}" -o || true)
if [[ $fix_issue != "" ]]; then
printf "* ${fix_line} [View]($(force_trailing_slash ${TICKET_URL})${fix_issue})\n" >> ${logf}
else
printf "* ${fix_line}\n" >> ${logf}
fi
done
printf "\n\n" >> ${logf}
fi;
fi
echo "---" >> ${logf}
if [[ -f ${targetfile} ]]; then
# remove first line
sed -i '1d' ${targetfile}
# append to new output
cat ${targetfile} >> ${logf}
rm ${targetfile}
fi
mv ${logf} ${targetfile}
timelog "Changelog written to ${targetfile}" ${success}
}
# First check params
check_params "$@"
# now lets check config
check_vars
# now gen the log
gen_changelog