#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # # Copyright (C) 2019 Daniel Borkmann # Copyright (C) 2020 Jakub Kicinski # Pull from a pull request in patchwork, add a commit message # based on the contents of the tag or the email if tag was empty. # Optionally, compare if the patches on the branch are identical # to what's posted on the mailing list. source $(dirname $0)/lib.sh usage() { cat <<-EOF usage: pw-pull [-p PULL] [-s SERIES] [-c] [-P PULL_URL] [-T] [-h] EOF exit } get_cover_tags() { [ -z "$cover_tags" ] && return # first arg is JSON either of cover or of the pull local json="$1" clink=$(echo "$json" | jq -r '.url') link=$(curl -s "$clink" | jq -r '.comments') [ "$link" == "null" ] && return echo -ne "$(curl -s $link | jq -r '.[].content')" | sed -n '/^\(Ack\|Review\|Test\)ed-[Bb]y:/p' } pull="" pull_url="" cover="" cover_tags="y" series="" series_branch="tmp" head_old=$(git rev-parse --verify HEAD) while true; do case "$1" in -p | --pull ) pull="$2"; shift 2 ;; -s | --series ) series="$2"; shift 2 ;; -c | --pull-from-cover ) cover="y"; shift ;; -P | --pull-url ) pull_url="$2"; shift 2 ;; -T | --no-cover-tags) cover_tags=""; shift ;; -h | --help ) usage; break ;; -- ) shift; break ;; * ) break ;; esac done [ -z "$pull" ] && [ -z "$cover" ] && [ -z "$pull_url" ] && usage [ ! -z "$pull" ] && [ ! -z "$cover" ] && usage [ ! -z "$pull" ] && [ ! -z "$pull_url" ] && usage srv=$(git config --get pw.server) srv=${srv%/} # strip trailing slash target=$(git branch --show-current) if [ ! -z "$pull" ]; then pull_json=$(curl -s $srv/patches/$pull/) pull_url=$(echo "$pull_json" | jq -r '.pull_url') pull_author=$(echo "$pull_json" | jq -r '.submitter.name') pull_subject=$(echo "$pull_json" | jq -r '.name' | sed -e 's/\[.*\] *//') pull_msgid=$(echo "$pull_json" | jq -r '.msgid' | tr -d '<>') json=$pull_json elif [ ! -z "$cover" ]; then series_json=$(curl -s $srv/series/$series/) pull_author=$(echo "$series_json" | jq -r '.submitter.name') pull_subject=$(echo "$series_json" | jq -r '.name' | sed -e 's/\[.*\] *//') pull_msgid=$(echo "$series_json" | jq -r '.cover_letter.msgid' | tr -d '<>') cover_id=$(echo "$series_json" | jq -r '.cover_letter.id') cover_json=$(curl -s $srv/covers/$cover_id/) pull_msg=$(echo "$pull" | jq -r '.content' | awk 'BEGIN {e=0} /^---/ {e=1} /^Please consider/ {e=1} {if(!e) print}') if [ -z "$pull_url" ]; then pull_url=$(echo "$cover_json" | jq -r '.content' | awk '/^.+$/ { if (n) {n=0; print} } /and are available in the git repository at:/ {n=1}') pull_url=$(echo $pull_url) fi if [ -z "$pull_url" ]; then echo "Unable to parse out pull URL" exit 1 fi json=$cover_json fi tags="$(get_cover_tags "$json")" # Download the series from ML and make a local branch if [ ! -z "$series" ]; then mbox_from_series $series git checkout -b $series_branch git am -3 mbox.i rm -f mbox.i git checkout "$target" fi git pull --stat --log --no-edit --no-ff $pull_url if [ $? -ne 0 ]; then bold "Waiting for conflict resolution..." while git status | head -9 | grep "conflicts" >/dev/null; do sleep 0.25 done fi merge_header=$(git show --format="%s" --no-patch) merge_body=$(git show --format="%b" --no-patch) # count lines until "* tag", ignore empty and gpg output significant_lines=$(echo -e "$merge_body" | awk 'BEGIN {c=0; e=0} /^\* (tag|git|https|'"'"')/ {e=1} /^[^#]/ { if(!e) c++} END {print c}') if [ "$significant_lines" -le 1 ]; then # Construct the message from email body if tag is empty pull_msg=$(echo "$json" | jq -r '.content' | awk 'BEGIN {e=0} /^---/ {e=1} /^The following changes since commit/ {e=1} /^The following are changes since commit/ {e=1} /^Please consider/ {e=1} /^Please, pull these changes/ {e=1} {if(!e) print}') git commit --amend --signoff -F- <