|
| 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