| #!/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 |