misc: update mkreleaselog to build a recursive changelog
Steven Allen committed
May 26, 2019 at 16:46 UTC
8fb4e924fb00955bd54369743a85912ff6102faa
1 file changed
+115
-25
bin/mkreleaselog
+115
-25
@@ -1,29 +1,119 @@
1
-#!/usr/bin/env bash
1
+#!/bin/zsh
2
#set -x
3
set -euo pipefail
4
-IFS=$'\n\t'
4
export GO111MODULE=on
5
+export GOPATH="$(go env GOPATH)"
6
7
-LAST_TAG=$(git tag -l | sort -V | grep -v -- '-rc' | grep 'v'| tail -n1)
8
-
9
-git log --oneline --merges --reverse $LAST_TAG...master |
10
-while read MERGE
11
-do
12
- commit=$(echo $MERGE | awk '{ print $1 }')
13
- prnum=$(echo $MERGE | awk '{ print $5 }' | tr -d '#')
14
- desc=$(git show $commit | sed '8q;d' | sed 's/^ //g')
15
- printf " - %s ([ipfs/go-ipfs#%s](https://github.com/ipfs/go-ipfs/pull/%s))\n" "$desc" "$prnum" "$prnum"
16
-done
17
-
18
-TMP_DIR=$(mktemp -d --tmpdir go-ipfs-mkreleaselog-XXXXXX)
19
-git show "$LAST_TAG:go.mod" > "$TMP_DIR/go.mod"
20
-
21
-echo
22
-echo "Dependecy updates:"
23
-join -a 2 <(cd "$TMP_DIR" && go list -m all | sort -k 1b,1) <(go list -m all | sort -k 1b,1) | awk \
24
- '
25
- { if (NF == 2)
26
- printf "2 - %s none => %s\n", $1, $2
27
- else if ($2 != $3)
28
- printf "1 - %s %s => %s\n", $1, $2, $3 }
29
- ' | sort | sed 's/[0-9] //'
7
+alias jq="jq --unbuffered"
8
+
9
+[[ -n "${REPO_FILTER+x}" ]] || REPO_FILTER="github.com/(ipfs|libp2p|ipld)"
10
+[[ -n "${IGNORED_FILES+x}" ]] || IGNORED_FILES='^\(\.gx\|package.json\|\.travis.yml\|go.mod\|go.sum\)$'
11
+
12
+msg() {
13
+ echo "$*" >&2
14
+}
15
+
16
+# Returns a stream of deps changed between $1 and $2.
17
+dep_changes() {
18
+ {
19
+ <"$1"
20
+ <"$2"
21
+ } | jq -s 'JOIN(INDEX(.[0][]; .Path); .[1][]; .Path; {Path: .[0].Path, Old: (.[1] | del(.Path)), New: (.[0] | del(.Path))}) | select(.New.Version != .Old.Version)'
22
+}
23
+
24
+# resolve_commits resolves a git ref for each version.
25
+resolve_commits() {
26
+ jq '. + {Ref: (.Version|capture("^((?<ref1>.*)\\+incompatible|v.*-[0-9]{14}-(?<ref2>[a-f0-9]{12})|(?<ref3>v.*))$") | .ref1 // .ref2 // .ref3)}'
27
+}
28
+
29
+# Generate a release log for a range of commits in a single repo.
30
+release_log() {
31
+ local repo="$1"
32
+ local start="$2"
33
+ local end="${3:-HEAD}"
34
+ local ghname="${repo##github.com/}"
35
+ local dir="$GOPATH/src/$repo"
36
+
37
+ local commit prnum
38
+ git -C "$dir" log \
39
+ --format='tformat:%H %s' \
40
+ --merges \
41
+ "$start..$end" |
42
+ sed -n -e 's/\([a-f0-9]\+\) .*#\([0-9]\+\).*/\1 \2/p' |
43
+ while read commit prnum; do
44
+ # Skip gx-only PRs.
45
+ git -C "$dir" diff-tree --no-commit-id --name-only "$commit^" "$commit" |
46
+ grep -v "${IGNORED_FILES}" >/dev/null || continue
47
+
48
+ local desc="$(git -C "$dir" show --summary --format='tformat:%b' "$commit" | head -1)"
49
+ printf "- %s ([%s#%s](https://%s/pull/%s))\n" "$desc" "$ghname" "$prnum" "$repo" "$prnum"
50
+ done
51
+}
52
+
53
+indent() {
54
+ sed -e 's/^/ /'
55
+}
56
+
57
+mod_deps() {
58
+ go list -json -m all | jq 'select(.Version != null)'
59
+}
60
+
61
+ensure() {
62
+ local repo="$1"
63
+ local commit="$2"
64
+ local rpath="$GOPATH/src/$repo"
65
+ if [[ ! -d "$rpath" ]]; then
66
+ msg "Cloning $repo..."
67
+ git clone "http://$repo" "$rpath" >&2
68
+ fi
69
+
70
+ if ! git -C "$rpath" rev-parse --verify "$commit" >/dev/null; then
71
+ msg "Fetching $repo..."
72
+ git -C "$rpath" fetch --all >&2
73
+ fi
74
+
75
+ git -C "$rpath" rev-parse --verify "$commit" >/dev/null || return 1
76
+}
77
+
78
+recursive_release_log() {
79
+ local start="${1:-$(git tag -l | sort -V | grep -v -- '-rc' | grep 'v'| tail -n1)}"
80
+ local end="${2:-$(git rev-parse HEAD)}"
81
+ local repo_root="$(git rev-parse --show-toplevel)"
82
+ local package="$(go list)"
83
+ (
84
+ local workspace="$(mktemp -d)"
85
+ trap "$(printf 'rm -rf "%q"' "$workspace")" INT TERM EXIT
86
+ cd "$workspace"
87
+
88
+ echo "Computing old deps..." >&2
89
+ git -C "$repo_root" show "$start:go.mod" >go.mod
90
+ mod_deps | resolve_commits | jq -s > old_deps.json
91
+
92
+ echo "Computing new deps..." >&2
93
+ git -C "$repo_root" show "$end:go.mod" >go.mod
94
+ mod_deps | resolve_commits | jq -s > new_deps.json
95
+
96
+ rm -f go.mod go.sum
97
+
98
+ printf "Generating Changelog for %s %s..%s\n" "$package" "$start" "$end" >&2
99
+
100
+ printf "- %s:\n" "$package"
101
+ release_log "$package" "$start" "$end" | indent
102
+
103
+
104
+ dep_changes old_deps.json new_deps.json |
105
+ jq --arg filter "$REPO_FILTER" 'select(.Path | match($filter))' |
106
+ # Compute changelogs
107
+ jq -r '"\(.Path) \(.New.Version) \(.New.Ref) \(.Old.Version) \(.Old.Ref // "")"' |
108
+ while read repo new new_ref old old_ref; do
109
+ ensure "$repo" "$new_ref"
110
+ local changelog="$(release_log "$repo" "$old_ref" "$new_ref")"
111
+ if [[ -n "$changelog" ]]; then
112
+ printf "- %s (%s -> %s):\n" "$repo" "$old" "$new"
113
+ echo "$changelog" | indent
114
+ fi
115
+ done
116
+ )
117
+}
118
+
119
+recursive_release_log "$@"