blob: c9a7ade89e6aa696f39972fcdb8ac343a7979ff9 [file] [log] [blame]
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2019 Daniel Borkmann <daniel@iogearbox.net>
source $(dirname $0)/lib.sh
usage()
{
cat <<-EOF
usage: pw-apply [-h] [-s SERIES] [-b MBOX] [-m BRANCHNAME] [-M]
[-a] [-3] [-N] [-e] [-T]
-- [-C] [-a ACKEDBY] [-r REVIEWEDBY] [-t TESTEDBY]
EOF
exit
}
mbox_from_url()
{
curl $1 | gunzip -f -c > mbox.i
}
get_cover()
{
cover_json=$(echo "$series_json" | jq '.cover_letter')
link=$(echo "$cover_json" | jq -r '.mbox' )
if [ "$link" == "null" ]; then
return
fi
curl -s $link > cover.i
cover_subject=$(echo -e "$cover_json" |
jq -r '.name' |
sed -e 's/\[.*\] *//')
branch=$(echo -e "$cover_json" |
jq -r '.name' |
sed -e 's/ *\[.*\] *//g' |
tr '[:upper:]' '[:lower:]' |
tr -d '\n' |
tr -cs '[:alnum:]_-' '-')
[ -n "$branch" -a ${branch: -1} == '-' ] && branch=${branch:: -1}
cover_msgid=$(echo "$cover_json" | jq -r '.msgid' | tr -d '<>')
}
set_cover_tags()
{
[ -z "$cover_tags" ] && return
cover_json=$(echo "$series_json" | jq '.cover_letter')
[ "$cover_json" == "null" ] && return
clink=$(echo "$cover_json" | jq -r '.url')
link=$(curl -s "$clink" | jq -r '.comments')
[ "$link" == "null" ] && return
tags=$(echo -e "$(curl -s $link | jq -r '.[].content')" |
sed -n '/\(Ack\|Review\)ed-[Bb]y:/p')
export ADD_TAGS="$tags"
}
clear_cover_tags()
{
[ -z "$cover_tags" ] && return
[ -n "$ADD_TAGS" ] && export ADD_TAGS=
}
accept_series()
{
for patch in $(git pw series show $1 -f simple 2> /dev/null | \
sed -n '/^Patches/,$p' | \
sed -r 's/.* ([0-9]*) .*/\1/g')
do
echo "Accepting $patch:"
git pw patch update --state accepted $patch -f simple 2> /dev/null
done
echo "Done, all accepted!"
rm -f mbox.i
exit
}
cover_from_url()
{
curl -s $1 | gunzip -f -c > tmp.i
series_num=`grep "href=\"/series" tmp.i|cut -d/ -f3|head -1`
cover_url=`grep "href=\"/project/netdevbpf/cover" tmp.i|cut -d\" -f2`
if [ ! -z "$cover_url" ]; then
curl -s https://patchwork.kernel.org${cover_url}mbox/ | gunzip -f -c > cover.i
merge="1"
fi
curl -s https://patchwork.kernel.org/series/$series_num/mbox/ | gunzip -f -c > mbox.i
}
edits=""
am_flags=""
branch="mbox"
series=""
accept=""
merge=""
mbox=""
cover=""
cover_tags="y"
mb2q_normalize="y"
head_old=$(git rev-parse --verify HEAD)
while true; do
case "$1" in
-3 ) am_flags="$am_flags -3"; shift ;;
-s | --series ) series="$2"; shift 2 ;;
-a | --accept ) accept="1"; shift ;;
-e | --do-edits ) edits="1"; shift ;;
-N | --no-mb2q ) mb2q_normalize=""; am_flags="$am_flags -s"; shift ;;
-m | --merge ) merge="1"; branch="$2"; shift 2 ;;
-M | --auto-merge) merge="1"; auto_branch="1"; shift ;;
-b | --mbox ) mbox="$2"; shift 2 ;;
-c | --cover) branch="tmp"; cover="$2"; shift 2 ;;
-T | --no-cover-tags) cover_tags=""; shift ;;
-h | --help ) usage; break ;;
-- ) shift; break ;;
* ) break ;;
esac
done
[ ! -z "$auto_branch" ] && [ -z "$series" ] && usage
[ ! -z "$mbox" ] && [ ! -z "$series" ] && usage
[ -z "$mbox" ] && [ -z "$series" ] && [ -z "$cover" ] && usage
[ ! -z "$accept" ] && [ ! -z "$mbox" ] && usage
[ ! -z "$series" ] && mbox_from_series $series
[ ! -z "$mbox" ] && mbox_from_url $mbox
[ ! -z "$accept" ] && accept_series $series
[ ! -z "$cover" ] && cover_from_url $cover
body=
author=XYZ
if [ ! -z "$auto_branch" ]; then
get_cover
set_cover_tags
[ -z "$cover_msgid" ] && merge=
fi
if [ ! -z "$auto_branch" -a ! -z "$cover_msgid" ]; then
body=$(cat cover.i |
awk 'BEGIN {h=1;t=0}
/^[A-Za-z. ]* \([0-9]+\):$/ {t=1}
// {if (!h && !t) print}
/^$/ {h=0} ')
author=$(cat cover.i |
sed -n 's/^From: \([A-Za-z. -]*[a-z]\).*$/\1/p' |
tail -1)
fi
git checkout -b $branch
if [ ! -z "$mb2q_normalize" ]; then
mb2q --mboxout mbox.o "$@" mbox.i
else
cp mbox.i mbox.o
fi
if [ -z "$merge" ]; then
flags=$am_flags
# When running without mb2q ask git-am for msgid, and have a git hook
# transform that into a lore Link.
[ -z "$mb2q_normalize" ] && flags="$flags -m"
git am $flags mbox.o
else
git am $am_flags mbox.o
if [ ! -z "$edits" ] ; then
git rebase -i master
fi
while [ -d .git/rebase-merge ]; do
echo -ne "\rWaiting for rebase to finish $(date)"
sleep 0.5
done
echo
fi
git checkout master
if [ ! -z "$merge" ]; then
git merge --stat --log --no-edit --no-ff $branch
if [ ! -z "$cover" ]; then
author=$(grep 'X-Patchwork-Submitter:' cover.i | cut -d' ' -f2- | cut -d'<' -f1 | awk '{$1=$1;print}')
if [[ "$author" =~ ^=\?utf-8\?b\?(.*)\?=$ ]]; then
# strip away "=?utf-8?b?" prefix and "?=" suffix and base64-decode
author=$(echo "${BASH_REMATCH[1]}" | base64 -d)
elif [[ "$author" =~ ^=\?utf-8\?q\?(.*)\?=$ ]]; then
# strip away "=?utf-8?q?" prefix and "?=" suffix and quoted-printable-decode
author=$(echo "${BASH_REMATCH[1]}" | tr '_' ' ' | perl -MMIME::QuotedPrint -0777 -nle 'print decode_qp($_)')
fi
# Extract cover letter subject, potentially split into two lines
branch_name=$(awk '/^\w+: / { subj=0 } /^Subject: / { subj = 1 } subj { print $0 }' cover.i | tr -d '\n' | cut -d']' -f2 | cut -c 2-)
text=`grep -A300 'X-Mailing-List:' cover.i |tail --lines=+3|grep -B300 -E "^.*\([0-9]+\):$"|head --lines=-2`
git commit --amend --signoff -F- <<EOF
Merge branch '$branch_name'
$author says:
====================
$text
====================
EOF
else
git commit --amend --signoff -F- <<EOF
Merge branch '$branch'
$author says:
====================
$cover_subject
$body
====================
Link: https://lore.kernel.org/r/$cover_msgid
EOF
fi
else
git merge --stat --ff $branch
fi
git branch -d $branch
rm -f mbox.i mbox.o tmp.i cover.i
head_new=$(git rev-parse --verify HEAD)
pw-check -s $head_old -e $head_new
if [ ! -z "$merge" ]; then
if [ -z "$edits" ] ; then
echo "Edit merge commit via: git commit --amend"
else
git commit --amend
fi
fi
clear_cover_tags
exit 0