1#!/bin/bash 2# 3# Copyright (c) 2010-2011, Intel Corporation. 4# 5# SPDX-License-Identifier: GPL-2.0-or-later 6# 7 8# 9# This script is intended to be used to send a patch series prepared by the 10# create-pull-request script to Open Embedded and The Yocto Project, as well 11# as to related projects and layers. 12# 13 14AUTO=0 15AUTO_CL=0 16GITSOBCC="--suppress-cc=all" 17 18# Prevent environment leakage to these vars. 19unset TO 20unset CC 21unset AUTO_CC 22unset EXTRA_CC 23 24usage() 25{ 26cat <<EOM 27Usage: $(basename $0) [-h] [-a] [-c] [[-t email]...] -p pull-dir 28 -a Send the cover letter to every recipient listed in Cc and 29 Signed-off-by lines found in the cover letter and the patches. 30 This option implies -c. 31 -c Expand the Cc list for the individual patches using the Cc and 32 Signed-off-by lines from the same patch. 33 -C Add extra CC to each email sent. 34 -p pull-dir Directory containing summary and patch files 35 -t email Explicitly add email to the recipients 36EOM 37} 38 39# Collect addresses from a patch into AUTO_CC 40# $1: a patch file 41harvest_recipients() 42{ 43 PATCH=$1 44 export IFS=$',\n' 45 for REGX in "^[Cc][Cc]: *" "^[Ss]igned-[Oo]ff-[Bb]y: *"; do 46 for EMAIL in $(sed '/^---$/q' $PATCH | grep -e "$REGX" | sed "s/$REGX//"); do 47 if [ "${AUTO_CC/$EMAIL/}" == "$AUTO_CC" ] && [ -n "$EMAIL" ]; then 48 if [ -z "$AUTO_CC" ]; then 49 AUTO_CC=$EMAIL; 50 else 51 AUTO_CC="$AUTO_CC,$EMAIL"; 52 fi 53 fi 54 done 55 done 56 unset IFS 57} 58 59# Parse and verify arguments 60while getopts "acC:hp:t:" OPT; do 61 case $OPT in 62 a) 63 AUTO=1 64 GITSOBCC="--signed-off-by-cc" 65 AUTO_CL=1 66 ;; 67 c) 68 AUTO=1 69 GITSOBCC="--signed-off-by-cc" 70 ;; 71 C) 72 EXTRA_CC="$OPTARG" 73 ;; 74 h) 75 usage 76 exit 0 77 ;; 78 p) 79 PDIR=${OPTARG%/} 80 if [ ! -d $PDIR ]; then 81 echo "ERROR: pull-dir \"$PDIR\" does not exist." 82 usage 83 exit 1 84 fi 85 ;; 86 t) 87 if [ -n "$TO" ]; then 88 TO="$TO,$OPTARG" 89 else 90 TO="$OPTARG" 91 fi 92 ;; 93 esac 94done 95 96if [ -z "$PDIR" ]; then 97 echo "ERROR: you must specify a pull-dir." 98 usage 99 exit 1 100fi 101 102 103# Verify the cover letter is complete and free of tokens 104if [ -e $PDIR/0000-cover-letter.patch ]; then 105 CL="$PDIR/0000-cover-letter.patch" 106 for TOKEN in SUBJECT BLURB; do 107 grep -q "*** $TOKEN HERE ***" "$CL" 108 if [ $? -eq 0 ]; then 109 echo "ERROR: Please edit $CL and try again (Look for '*** $TOKEN HERE ***')." 110 exit 1 111 fi 112 done 113else 114 echo "WARNING: No cover letter will be sent." 115fi 116 117# Harvest emails from the generated patches and populate AUTO_CC. 118if [ $AUTO_CL -eq 1 ]; then 119 for PATCH in $PDIR/*.patch; do 120 harvest_recipients $PATCH 121 done 122fi 123 124AUTO_TO="$(git config sendemail.to)" 125if [ -n "$AUTO_TO" ]; then 126 if [ -n "$TO" ]; then 127 TO="$TO,$AUTO_TO" 128 else 129 TO="$AUTO_TO" 130 fi 131fi 132 133if [ -z "$TO" ] && [ -z "$AUTO_CC" ]; then 134 echo "ERROR: you have not specified any recipients." 135 usage 136 exit 1 137fi 138 139 140# Convert the collected addresses into git-send-email argument strings 141export IFS=$',' 142GIT_TO=$(for R in $TO; do echo -n "--to='$R' "; done) 143GIT_CC=$(for R in $AUTO_CC; do echo -n "--cc='$R' "; done) 144GIT_EXTRA_CC=$(for R in $EXTRA_CC; do echo -n "--cc='$R' "; done) 145unset IFS 146 147# Handoff to git-send-email. It will perform the send confirmation. 148# Mail threading was already handled by git-format-patch in 149# create-pull-request, so we must not allow git-send-email to 150# add In-Reply-To and References headers again. 151PATCHES=$(echo $PDIR/*.patch) 152if [ $AUTO_CL -eq 1 ]; then 153 # Send the cover letter to every recipient, both specified as well as 154 # harvested. Then remove it from the patches list. 155 # --no-thread is redundant here (only sending a single message) and 156 # merely added for the sake of consistency. 157 eval "git send-email $GIT_TO $GIT_CC $GIT_EXTRA_CC --confirm=always --no-thread --suppress-cc=all $CL" 158 if [ $? -eq 1 ]; then 159 echo "ERROR: failed to send cover-letter with automatic recipients." 160 exit 1 161 fi 162 PATCHES=${PATCHES/"$CL"/} 163fi 164 165# Send the patch to the specified recipients and, if -c was specified, those git 166# finds in this specific patch. 167eval "git send-email $GIT_TO $GIT_EXTRA_CC --confirm=always --no-thread $GITSOBCC $PATCHES" 168if [ $? -eq 1 ]; then 169 echo "ERROR: failed to send patches." 170 exit 1 171fi 172