Skip to content

Commit 05dad1b

Browse files
committed
Add helper script to extract and reformat release notes
1 parent 3893553 commit 05dad1b

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

convert-release-notes.sh

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
SCRIPTNAME=$0
6+
# SCRIPTPATH=$(dirname "$0")
7+
VERSION=""
8+
9+
RELNOTES_FILE=doc/RELNOTES
10+
PRINT_EMAIL=false
11+
PRINT_YAML=false
12+
RC=""
13+
14+
usage() {
15+
cat >&2 <<EOF
16+
Usage: $SCRIPTNAME [options] [<version>]"
17+
18+
Convert the RELNOTES file format to the different text formats used in
19+
e-mail/GitHub/git-tags/website.
20+
21+
<version> Specify the version to extract from RELNOTES. Defaults to
22+
the top-most version in the file.
23+
24+
-e, --email Generate an email header before the release notes.
25+
26+
-r <num>, --rc <num> Use this release candidate in generated text.
27+
28+
-y, --yaml Convert to yaml output for website nsd_releases.yml file.
29+
30+
-f, --file Specify the file to read. Defaults to "$RELNOTES_FILE".
31+
32+
Examples:
33+
34+
Latest release: $SCRIPTNAME
35+
Specific release: $SCRIPTNAME 4.12.0
36+
Release candidate: $SCRIPTNAME -r 1 4.12.0
37+
EOF
38+
}
39+
40+
error_unknown_option() {
41+
echo "Unknown option: $1" >&2
42+
usage && exit 1
43+
}
44+
45+
error_too_many_args() {
46+
echo "Too many arguments found: $1" >&2
47+
usage && exit 1
48+
}
49+
50+
extract_release_notes() {
51+
# Find latest version if VERSION was not specified
52+
if [[ -z "$VERSION" ]]; then
53+
VERSION=$(grep -E -m1 -B1 "^=====+$" <"$RELNOTES_FILE" | head -n1)
54+
fi
55+
56+
sed -E -e "/^$VERSION/{ n; n; bfound }; d; bend" \
57+
-e ':found; /\n=====+$/bstrip_trailer; N; bfound' \
58+
-e ':strip_trailer; s/\n+([0-9]+\.[0-9]+\.[0-9]+)\n=====+$//' \
59+
-e ':delete_tabs; s/\t+//g' \
60+
-e ':end' "$RELNOTES_FILE"
61+
62+
# grep -En -B1 '^=====+$' "$RELNOTES_FILE" | grep -A3 "$VERSION" | \
63+
# grep -E "^[0-9]+-" | cut -d- -f1 | {
64+
# read -r start
65+
# read -r end
66+
# head -n"$((end-1))" <"$RELNOTES_FILE" | tail -n+"$start" | tr -d "\t"
67+
# }
68+
}
69+
70+
convert_rel_notes_to_yaml() {
71+
local features=()
72+
local bugs=()
73+
local state=none
74+
local -n array_to_add # nameref ("pointer") to features or bugs array
75+
local tmp_item
76+
77+
while read -r; do
78+
local line=$REPLY
79+
# echo ">>> $line"
80+
81+
if grep -qE "^FEATURES:" <<<"$line"; then
82+
state=features
83+
elif grep -qE "^BUG FIXES:" <<<"$line"; then
84+
state=bugs
85+
elif grep -qE "^- " <<<"$line"; then
86+
state=item_start
87+
elif grep -qE "^ " <<<"$line"; then
88+
state=item_continue
89+
else
90+
# skip empty/unknown lines
91+
continue
92+
fi
93+
94+
case "$state" in
95+
features)
96+
# Starting a new section, add last item to previous section
97+
if [[ -R array_to_add && -n "$tmp_item" ]]; then
98+
array_to_add+=("$tmp_item")
99+
tmp_item=""
100+
fi
101+
# shellcheck disable=2178
102+
declare -n array_to_add=features
103+
;;
104+
bugs)
105+
# Starting a new section, add last item to previous section
106+
if [[ -R array_to_add && -n "$tmp_item" ]]; then
107+
array_to_add+=("$tmp_item")
108+
tmp_item=""
109+
fi
110+
# shellcheck disable=2178
111+
declare -n array_to_add=bugs
112+
;;
113+
item_start)
114+
[[ -n "$tmp_item" ]] && array_to_add+=("$tmp_item")
115+
tmp_item=${line#- }
116+
;;
117+
item_continue)
118+
tmp_item+=$'\n'"${line}"
119+
;;
120+
esac
121+
done < <(tail -n+2 <<<"$(extract_release_notes)")
122+
# Finished reading, add completed item to active section
123+
[[ -n "$tmp_item" ]] && array_to_add+=("$tmp_item")
124+
125+
cat <<EOF
126+
---
127+
version: $VERSION
128+
date: $(date "+%d %B, %Y")
129+
EOF
130+
131+
if [[ "${#features[@]}" == 0 ]]; then
132+
echo "features: []"
133+
else
134+
echo "features:"
135+
for f in "${features[@]}"; do
136+
echo "- >-"
137+
echo " $f"
138+
done
139+
fi
140+
141+
if [[ "${#bugs[@]}" == 0 ]]; then
142+
echo "bugs: []"
143+
else
144+
echo "bugs:"
145+
for f in "${bugs[@]}"; do
146+
echo "- >-"
147+
echo " $f"
148+
done
149+
fi
150+
}
151+
152+
#### PARSE ARGUMENTS ####
153+
154+
if [[ "$1" =~ ^-h|--help$ ]]; then
155+
usage && exit
156+
else
157+
until [[ -z "$1" ]]; do
158+
case "$1" in
159+
-e|--email)
160+
PRINT_EMAIL=true
161+
;;
162+
-r|--rc)
163+
RC=rc$2
164+
shift
165+
;;
166+
-y|--yaml)
167+
PRINT_YAML=true
168+
;;
169+
-f|--file)
170+
RELNOTES_FILE=$2
171+
shift
172+
;;
173+
-*)
174+
error_unknown_option "$1"
175+
;;
176+
*)
177+
if [[ -z "$VERSION" ]]; then
178+
VERSION=$1
179+
else
180+
error_too_many_args "$1"
181+
fi
182+
;;
183+
esac
184+
shift
185+
done
186+
fi
187+
188+
if ! [[ -f "$RELNOTES_FILE" ]]; then
189+
echo "$0: $RELNOTES_FILE: No such file or directory" >&2
190+
exit 3
191+
fi
192+
193+
#### Generate text ####
194+
195+
if [[ "$PRINT_EMAIL" == true ]]; then
196+
SHA256=""
197+
if [[ -f "nsd-$VERSION$RC.tar.gz.sha256" ]]; then
198+
SHA256=$(cat "nsd-$VERSION$RC.tar.gz.sha256")
199+
fi
200+
201+
cat <<EOF
202+
Dear all,
203+
204+
NSD $VERSION ${RC:+pre-}release is available:
205+
https://nlnetlabs.nl/downloads/nsd/nsd-$VERSION$RC.tar.gz
206+
sha256 $SHA256
207+
pgp https://nlnetlabs.nl/downloads/nsd/nsd-$VERSION$RC.tar.gz.asc
208+
209+
EOF
210+
fi # END PRINT_EMAIL
211+
212+
if [[ "$PRINT_YAML" == true ]]; then
213+
convert_rel_notes_to_yaml
214+
else
215+
extract_release_notes
216+
fi
217+
218+
# vim: set ts=4 et sw=4:

0 commit comments

Comments
 (0)