-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpatches.sh
More file actions
executable file
·168 lines (137 loc) · 5.21 KB
/
patches.sh
File metadata and controls
executable file
·168 lines (137 loc) · 5.21 KB
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
#!/bin/sh
set -e
##########################################################
# Setup and Installation Steps #
##########################################################
# Check that brew is installed
if ! command -v brew >/dev/null 2>&1; then
# not installed
read -p "Brew not detected. Install now? (y/n)" -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
fi
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# Check that gum is installed
if ! command -v gum >/dev/null 2>&1; then
# not installed
read -p "Gum not detected. Install now? (y/n)" -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
fi
brew install gum
fi
# Check that gh cli installed
if ! command -v gh >/dev/null 2>&1; then
# not installed
# we can use gum now that it should be installed
gum confirm "Install gh cli?" && brew install gh
fi
##########################################################
# End Setup and Installation Steps #
##########################################################
# Check if gh cli is already authenticated
if ! gh auth status >/dev/null 2>&1; then
gum confirm "Login to github cli?" && gh auth login
fi
mkdir -p "$HOME/.patches"
# if repo list exists, ask if they want to use or update
# else always grab list
if [ -f "$HOME/.patches/repos.txt" ]
then
gum confirm "Would you like to refresh the repository list?" \
&& gum spin --spinner dot --title "Fetching list of hashicorp repos..." -- \
gh repo list hashicorp --limit 2500 --json name --jq '"hashicorp/" + .[].name' > "$HOME/.patches/repos.txt"
else
# have to grab the repos since we don't have them already
gum spin --spinner dot --title "Fetching list of hashicorp repos..." -- \
gh repo list hashicorp --limit 2500 --json name --jq '"hashicorp/" + .[].name' > "$HOME/.patches/repos.txt"
fi
REPO_LIST=$(<"$HOME/.patches/repos.txt")
REPO=$(gh repo list hashicorp --limit 2000 --json name --jq '"hashicorp/" + .[].name' | gum filter)
REPO_URL=$(gh repo view $REPO --json sshUrl --jq '.sshUrl')
PR_NUM=$(gum input --placeholder "<PR_NUM>" --prompt "> #")
JQ_QUERY="[\"$REPO\", \"#\" + (.number|tostring), .mergeCommit.oid, .title] | join(\" \")"
PR_RESULTS=$(gh pr view --repo "$REPO" "$PR_NUM" --json number,mergeCommit,title --jq "$JQ_QUERY")
PR_COMMIT=""
if [ -z "$PR_RESULTS" ]
then
gum style \
--foreground 212 --border-foreground 212 --border double \
--align center --width 50 --margin "1 2" --padding "2 4" \
'PR not found' "#$PR_NUM" 'Exiting...'
exit 1
else
gum confirm "Is this the correct PR? $PR_RESULTS"
if [ $? -ne 0 ]
then
gum style "Exiting..."
exit 1
fi
PR_COMMIT=$(gh pr view --repo "$REPO" "$PR_NUM" --json mergeCommit --jq ".mergeCommit.oid")
echo "$PR_COMMIT"
fi
# Find all of the backports
BP_PRS=$(gh search prs --repo $REPO --match body "This PR is auto-generated from #$PR_NUM" --json number --jq ".[].number")
# could allow manual input of PR numbers here for manual backport cases
# split prs into array, guard against '*' in string with noglob
set -o noglob
IFS=$'\n' BP_ARR=($BP_PRS); unset IFS
set +o noglob
# Grab the commits for each of the backport PRs
j=0
for BP_PR_NUM in "${BP_ARR[@]}"
do
echo "Found Backport PR: $BP_PR_NUM"
MERGE_COMMITS[j]=$(gh pr view --repo "$REPO" "$BP_PR_NUM" --json mergeCommit --jq ".mergeCommit.oid")
j=$((j+1))
done
# get a treeless clone of the repo
# Check if repo exists
# if so ask if they want to refresh the repo
# else clone it
# bare clone of repo
# need to check if exists already
cd "$HOME/.patches/"
REPO_SHORT=${REPO##*/}
if [ -d "$HOME/.patches/$REPO_SHORT.git" ]
then
# already cloned, ask if they would like to refresh
gum confirm "Repository treeless clone exists. Would you like to refresh it?" \
&& rm -rf "$HOME/.patches/$REPO_SHORT.git" \
&& gum spin --show-output --spinner dot --title "Cloning $REPO... (may take a moment)" -- git clone --progress --bare $REPO_URL 2>&1
else
# We don't have the repo yet so we have to clone it
gum spin --show-output --spinner dot --title "Cloning $REPO... (may take a moment)" -- git clone --progress --bare $REPO_URL 2>&1
fi
cd "$HOME/.patches/$REPO_SHORT.git"
TAGS=()
# Check the main PR for which tags it is in
MAIN_TAGS=$(git tag --contains $PR_COMMIT)
# split prs into array, guard against '*' in string with noglob
set -o noglob
IFS=$'\n' MAIN_TAGS_ARR=($MAIN_TAGS); unset IFS
set +o noglob
# Check the backport merge commits
for BP_COMMIT in "${MERGE_COMMITS[@]}"
do
BP_TAGS=$(git tag --contains $BP_COMMIT)
set -o noglob
IFS=$'\n' BP_TAGS_ARR=($BP_TAGS); unset IFS
set +o noglob
MAIN_TAGS_ARR=("${MAIN_TAGS_ARR[@]}" "${BP_TAGS_ARR[@]}")
done
# sort the tags
set -o noglob
SORTED=(`printf '%s\n' "${MAIN_TAGS_ARR[@]}" | sort`)
printf "\nFound the following tags:\n"
printf "* %s\n" "${SORTED[@]}" | gum format
if [ ${#SORTED[@]} -eq 0 ]
then
printf "* No matching tags found. Please check the original PR for manual backports.\n" | gum format
fi
set +o noglob