github.com/whyrusleeping/gx@v0.14.3/contrib/gx-changelog.sh (about) 1 #!/bin/zsh 2 3 [[ -n "$REPO_FILTER" ]] || REPO_FILTER="github.com/(ipfs|libp2p|ipld)" 4 [[ -n "$IGNORED_FILES" ]] || IGNORED_FILES='^\(\.gx\|package.json\|\.travis.yml\)$' 5 6 export GOPATH="$(go env GOPATH)" 7 8 alias jq="jq --unbuffered" 9 10 set -e 11 set -o pipefail 12 13 # Returns a json object recursively listing all deps of the current package. 14 gx_deps() { 15 gx deps -r | column -J --table-columns name,hash,version | jq '.table' 16 } 17 18 # Convert a stream into an array. 19 slurp() { 20 jq -s . 21 } 22 23 # Convert an array into a stream. 24 stream() { 25 jq '.[]' 26 } 27 28 # Returns a stream of deps changed between $1 and $2. 29 dep_changes() { 30 { 31 <"$1" 32 <"$2" 33 } | jq -s 'JOIN(INDEX(.[0][]; .repo); .[1][]; .repo; {repo: .[0].repo, old: .[1].hash, new: .[0].hash}) | select(.new != .old)' 34 } 35 36 # Replace all gx package names with go import paths. 37 resolve_repos() { 38 jq -r '"\(env.GOPATH)/src/gx/ipfs/\(.hash)/\(.name)/package.json \(@json)"' | 39 while read gxfile json; do 40 jq --argjson pkg "$json" '($pkg|del(.name)) + {repo: .gx.dvcsimport}' "$gxfile" 41 done 42 } 43 44 # Takes in a stream of objects in the form: 45 # `{ repo: path, old: GxHash, new: GxHash }` 46 # And returns a stream of objects in the form: 47 # `{ repo: phat, old: CommitHash, new: CommitHash }` 48 resolve_commits() { 49 local repo new old 50 jq -r '"\(.repo) \(.new) \(.old)"' | while read repo new old; do 51 local old_commit="null" 52 local new_commit="null" 53 local dir="$GOPATH/src/$repo" 54 while read commit; do 55 hash="$(git -C "$dir" show "$commit:.gx/lastpubver" 2>/dev/null | cut -d' ' -f2)" 56 case "$hash" in 57 "$new") new_commit="$(printf '"%q"' "$commit")" ;; 58 "$old") old_commit="$(printf '"%q"' "$commit")" ;; 59 esac 60 done < <(git -C "$dir" log origin/master --format=tformat:'%H' .gx/lastpubver) 61 printf '{"repo": "%q", "old": %s, "new": %s}\n' "$repo" "$old_commit" "$new_commit" 62 done | jq 63 } 64 65 # Generate a release log for a range of commits in a single repo. 66 release_log() { 67 local repo="$1" 68 local start="$2" 69 local end="${3:-HEAD}" 70 local ghname="${repo##github.com/}" 71 local dir="$GOPATH/src/$repo" 72 73 local commit prnum 74 git -C "$dir" log \ 75 --format='tformat:%H %s' \ 76 --merges \ 77 "$start..$end" | 78 sed -n -e 's/\([a-f0-9]\+\) Merge pull request #\([0-9]\+\) from .*/\1 \2/p' | 79 while read commit prnum; do 80 # Skip gx-only PRs. 81 git -C "$dir" diff-tree --no-commit-id --name-only "$commit^" "$commit" | 82 grep -v "${IGNORED_FILES}" >/dev/null || continue 83 84 local desc="$(git -C "$dir" show --summary --format='tformat:%b' "$commit" | head -1)" 85 printf "- %s ([%s#%s](https://%s/pull/%s))\n" "$desc" "$ghname" "$prnum" "$repo" "$prnum" 86 done 87 } 88 89 indent() { 90 sed -e 's/^/ /' 91 } 92 93 recursive_release_log() { 94 local start="${1:-$(git tag -l | sort -V | grep -v -- '-rc' | grep 'v'| tail -n1)}" 95 local end="${2:-$(git rev-parse HEAD)}" 96 local repo_root="$(git rev-parse --show-toplevel)" 97 local package="$(go list)" 98 ( 99 local workspace="$(mktemp -d)" 100 trap "$(printf 'rm -rf "%q"' "$workspace")" INT TERM EXIT 101 cd "$workspace" 102 103 echo "Computing old deps..." >&2 104 git -C "$repo_root" show "$start:package.json" > "package.json" 105 gx install --nofancy >/dev/null 106 gx_deps | stream | resolve_repos | slurp > old_deps.json 107 108 echo "Computing new deps..." >&2 109 git -C "$repo_root" show "$end:package.json" > "package.json" 110 gx install --nofancy >/dev/null 111 gx_deps | stream | resolve_repos | slurp > new_deps.json 112 113 rm package.json 114 115 echo "Generating Changelog..." >&2 116 117 printf "- %s:\n" "$package" 118 release_log "$package" "$start" "$end" | indent 119 120 dep_changes old_deps.json new_deps.json | 121 # Filter by repo 122 jq --arg filter "$REPO_FILTER" 'select(.repo | match($filter))' | 123 # Add in commit ranges. 124 resolve_commits | 125 # Compute changelogs 126 jq -r '"\(.repo) \(.new // "origin/master") \(.old // "")"' | 127 while read repo new old; do 128 local changelog="$(release_log "$repo" "$old" "$new")" 129 if [[ -n "$changelog" ]]; then 130 printf "- %s:\n" "$repo" 131 echo "$changelog" | indent 132 fi 133 done 134 ) 135 } 136 137 recursive_release_log "$@"