github-merge-pr: fix loading .config if symbolic link is used
[maintainer-tools.git] / patchwork-apply.sh
1 #!/usr/bin/env bash
2
3 SED=$(which gsed 2>/dev/null); SED=${SED:-sed}
4
5 yesno() {
6 local prompt="$1"
7 local default="${2:-n}"
8 local input
9
10 while [ 1 ]; do
11 printf "%s y/n [%s] > " "$prompt" "$default"
12 read input
13 case "${input:-$default}" in
14 y*) return 0 ;;
15 n*) return 1 ;;
16 esac
17 done
18 }
19
20 fetch() {(
21 set -e
22 mkdir "pwclient.get.$$"
23 cd "pwclient.get.$$"
24 pwclient get "$1"
25 mv * "../$1.patch"
26 cd ..
27 rmdir "pwclient.get.$$"
28 )}
29
30 get_date() {
31 date +"%a, %d %b %Y %H:%M:%S %z" | $SED -e 's|, 0|, |'
32 }
33
34 get_subject() {
35 local subject line
36 local IFS="
37 "
38
39 for line in $($SED -ne '/^Subject: */ { s/^Subject: *//p; :next; n; s/^ \+//p; t next; b }' "$1"); do
40 subject="$subject$line"
41 done
42
43 printf "%s\n" "$subject" | $SED -e 's/^\[.*\] \+//'
44 }
45
46 get_hdr_list() {
47 local file="$1"
48 local field="$2"
49 local addr list
50
51 local IFS=",
52 "
53
54 for addr in $($SED -ne "/^$field: */ { s/^$field: *//p; :next; n; s/^ \\+//p; t next; b }" "$file"); do
55 list="${list:+$list, }$(echo "$addr" | $SED -e 's/^ \+//; s/ \+$//')"
56 done
57
58 [ -n "$list" ] && printf "%s: %s\n" "$field" "$list"
59 }
60
61 get_hdr() {
62 $SED -ne "s/^$2: *//p" "$1" | head -n1
63 }
64
65 format_reply() {
66 local remote_ref remote_url remote_host remote_host remote_repo remote_user
67
68 remote_ref="$(git for-each-ref --format='%(push:short)' $(git symbolic-ref -q HEAD))"
69
70 [ -n "$remote_ref" ] || \
71 remote_ref="$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))"
72
73 [ -n "$remote_ref" ] || \
74 return 1
75
76 remote_url="$(git remote get-url "${remote_ref%%/*}")"
77
78 case "$remote_url" in
79 http*://*)
80 remote_host="${remote_url##http*://}"
81 case "$remote_host" in *@*)
82 remote_user="${remote_host%%@*}"
83 remote_host="${remote_host##*@}"
84 esac
85 case "$remote_host" in */*)
86 remote_repo="${remote_host#*/}"
87 remote_host="${remote_host%%/*}"
88 esac
89 ;;
90 *:*)
91 remote_host="$remote_url"
92 case "$remote_host" in *@*)
93 remote_user="${remote_host%%@*}"
94 remote_host="${remote_host##*@}"
95 esac
96 case "$remote_host" in *:*)
97 remote_repo="${remote_host##*:}"
98 remote_host="${remote_host%%:*}"
99 esac
100 ;;
101 esac
102
103 case "$remote_host" in
104 git.openwrt.org|git.lede-project.org)
105 case "$remote_repo" in
106 source.git|openwrt/openwrt.git)
107 echo "Merged into ${remote_ref##*/}."
108 ;;
109 lede/*/staging.git|openwrt/staging/*.git)
110 echo "Merged into my staging tree."
111 ;;
112 *)
113 echo "Merged into ${remote_repo:-the repository}, branch ${remote_ref##*/}."
114 ;;
115 esac
116 ;;
117 *)
118 echo "Merged."
119 ;;
120 esac
121
122 echo "Thank you!"
123 echo ""
124 }
125
126 echo "$1" | grep -sqE '^[0-9]+$' || {
127 echo "Usage: $0 <patch-id>" >&2
128 exit 1
129 }
130
131 [ -f "$1.patch" ] || {
132 pwclient info "$1" >/dev/null 2>/dev/null || {
133 echo "Unknown patch ID: $1" >&2
134 exit 2
135 }
136
137 fetch "$1" || {
138 echo "Failed to download patch" >&2
139 exit 3
140 }
141 }
142
143 git am "$1.patch" || {
144 echo "Failed to apply patch $1" >&2
145 git am --abort
146 exit 4
147 }
148
149 git log -p -1
150
151 if ! yesno "Keep change?" "y"; then
152 git reset --hard HEAD^
153
154 if yesno "Set to 'Changes Requested'?"; then
155 pwclient update -s "Changes Requested" "$1"
156 fi
157 else
158 if yesno "Set to 'Accepted'?" "y"; then
159 pwclient update -s "Accepted" "$1"
160
161 if yesno "Send reply mail?" "y"; then
162 {
163 printf "From: %s <%s>\n" "$(git config user.name)" "$(git config user.email)"
164
165 get_hdr_list "$1.patch" Cc
166
167 printf "Date: %s\n" "$(get_date)"
168 printf "Subject: Merged: %s\n\n" "$(get_subject "$1.patch")"
169
170 format_reply
171 } > "$1.reply"
172
173 echo "==="
174 cat "$1.reply"
175 echo "==="
176
177 if yesno "Edit reply?" "n"; then
178 git send-email \
179 --to "$(get_hdr "$1.patch" To)" \
180 --cc "$(get_hdr "$1.patch" From)" \
181 --in-reply-to "$(get_hdr "$1.patch" Message-Id)" \
182 --compose "$1.reply"
183 else
184 git send-email \
185 --to "$(get_hdr "$1.patch" To)" \
186 --cc "$(get_hdr "$1.patch" From)" \
187 --in-reply-to "$(get_hdr "$1.patch" Message-Id)" \
188 --confirm=never "$1.reply"
189 fi
190
191 rm -f "$1.reply" "$1.patch"
192 fi
193 fi
194 fi