summaryrefslogtreecommitdiffstats
path: root/scripts/send-pull-request
blob: 70b5a5cfb2c085a1914678fcbec7096cac8d941b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/bin/bash
#
# Copyright (c) 2010-2011,  Intel Corporation.
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

#
# This script is intended to be used to send a patch series prepared by the
# create-pull-request script to Open Embedded and The Yocto Project, as well
# as to related projects and layers.
#

AUTO=0
AUTO_CL=0
GITSOBCC="--suppress-cc=all"

# Prevent environment leakage to these vars.
unset TO
unset CC
unset AUTO_CC
unset EXTRA_CC

usage()
{
cat <<EOM
Usage: $(basename $0) [-h] [-a] [-c] [[-t email]...] -p pull-dir 
  -a           Send the cover letter to every recipient listed in Cc and
               Signed-off-by lines found in the cover letter and the patches.
	       This option implies -c.
  -c           Expand the Cc list for the individual patches using the Cc and
               Signed-off-by lines from the same patch.
  -C           Add extra CC to each email sent.
  -p pull-dir  Directory containing summary and patch files
  -t email     Explicitly add email to the recipients
EOM
}

# Collect addresses from a patch into AUTO_CC
# $1: a patch file
harvest_recipients()
{
	PATCH=$1
	export IFS=$',\n'
	for REGX in "^[Cc][Cc]: *" "^[Ss]igned-[Oo]ff-[Bb]y: *"; do
		for EMAIL in $(sed '/^---$/q' $PATCH | grep -e "$REGX" | sed "s/$REGX//"); do
			if [ "${AUTO_CC/$EMAIL/}" == "$AUTO_CC" ] && [ -n "$EMAIL" ]; then
				if [ -z "$AUTO_CC" ]; then
					AUTO_CC=$EMAIL;
				else
					AUTO_CC="$AUTO_CC,$EMAIL";
				fi
			fi
		done
	done
	unset IFS
}

# Parse and verify arguments
while getopts "acC:hp:t:" OPT; do
	case $OPT in
	a)
		AUTO=1
		GITSOBCC="--signed-off-by-cc"
		AUTO_CL=1
		;;
	c)
		AUTO=1
		GITSOBCC="--signed-off-by-cc"
		;;
	C)
		EXTRA_CC="$OPTARG"
		;;
	h)
		usage
		exit 0
		;;
	p)
		PDIR=${OPTARG%/}
		if [ ! -d $PDIR ]; then
			echo "ERROR: pull-dir \"$PDIR\" does not exist."
			usage
			exit 1
		fi
		;;
	t)
		if [ -n "$TO" ]; then
			TO="$TO,$OPTARG"
		else
			TO="$OPTARG"
		fi
		;;
	esac
done

if [ -z "$PDIR" ]; then
	echo "ERROR: you must specify a pull-dir."
	usage
	exit 1
fi


# Verify the cover letter is complete and free of tokens
if [ -e $PDIR/0000-cover-letter.patch ]; then
	CL="$PDIR/0000-cover-letter.patch"
	for TOKEN in SUBJECT BLURB; do
		grep -q "*** $TOKEN HERE ***" "$CL"
		if [ $? -eq 0 ]; then
			echo "ERROR: Please edit $CL and try again (Look for '*** $TOKEN HERE ***')."
			exit 1
		fi
	done
else
	echo "WARNING: No cover letter will be sent."
fi

# Harvest emails from the generated patches and populate AUTO_CC.
if [ $AUTO_CL -eq 1 ]; then
	for PATCH in $PDIR/*.patch; do
		harvest_recipients $PATCH
	done
fi

AUTO_TO="$(git config sendemail.to)"
if [ -n "$AUTO_TO" ]; then
	if [ -n "$TO" ]; then
		TO="$TO,$AUTO_TO"
	else
		TO="$AUTO_TO"
	fi
fi

if [ -z "$TO" ] && [ -z "$AUTO_CC" ]; then
	echo "ERROR: you have not specified any recipients."
	usage
	exit 1
fi


# Convert the collected addresses into git-send-email argument strings
export IFS=$','
GIT_TO=$(for R in $TO; do echo -n "--to='$R' "; done)
GIT_CC=$(for R in $AUTO_CC; do echo -n "--cc='$R' "; done)
GIT_EXTRA_CC=$(for R in $EXTRA_CC; do echo -n "--cc='$R' "; done)
unset IFS

# Handoff to git-send-email. It will perform the send confirmation.
# Mail threading was already handled by git-format-patch in
# create-pull-request, so we must not allow git-send-email to
# add In-Reply-To and References headers again.
PATCHES=$(echo $PDIR/*.patch)
if [ $AUTO_CL -eq 1 ]; then
	# Send the cover letter to every recipient, both specified as well as
	# harvested. Then remove it from the patches list.
	# --no-thread is redundant here (only sending a single message) and
	# merely added for the sake of consistency.
	eval "git send-email $GIT_TO $GIT_CC $GIT_EXTRA_CC --confirm=always --no-thread --suppress-cc=all $CL"
	if [ $? -eq 1 ]; then
		echo "ERROR: failed to send cover-letter with automatic recipients."
		exit 1
	fi
	PATCHES=${PATCHES/"$CL"/}
fi

# Send the patch to the specified recipients and, if -c was specified, those git
# finds in this specific patch.
eval "git send-email $GIT_TO $GIT_EXTRA_CC --confirm=always --no-thread $GITSOBCC $PATCHES"
if [ $? -eq 1 ]; then
	echo "ERROR: failed to send patches."
	exit 1
fi