summaryrefslogtreecommitdiffstats
path: root/scripts/send-pull-request
blob: b294d35bd50395b60d53dd6b749c3bdb2343f7d4 (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
#!/bin/bash
AUTO=0

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

usage()
{
cat <<EOM
Usage: $(basename $0) [-h] [-a] [[-t email]...] -p pull-dir 
  -t email     Explicitly add email to the recipients
  -a           Automatically harvest recipients from "*-by: email" lines
               in the patches in the pull-dir
  -p pull-dir  Directory containing summary and patch files
EOM
}

# Collect To and CC addresses from the patch files if they exist
# $1: Which header to add the recipients to, "TO" or "CC"
# $2: The regex to match and strip from the line with email addresses
harvest_recipients()
{
	TO_CC=$1
	REGX=$2
	export IFS=$',\n'
	for PATCH in $PDIR/*.patch; do
		# Grab To addresses
		for EMAIL in $(sed '/^---$/q' $PATCH | grep -e "$REGX" | sed "s/$REGX//"); do
			if [ "$TO_CC" == "TO" ] && [ "${TO/$EMAIL/}" == "$TO" ] && [ -n "$EMAIL" ]; then
				if [ -z "$TO" ]; then TO=$EMAIL; else TO="$TO,$EMAIL"; fi
			elif [ "$TO_CC" == "CC" ] && [ "${CC/$EMAIL/}" == "$CC" ] && [ -n "$EMAIL" ]; then
				if [ -z "$CC" ]; then CC=$EMAIL; else CC="$CC,$EMAIL"; fi
			fi
		done
	done
	unset IFS
}


# Parse and verify arguments
while getopts "ahp:t:" OPT; do
	case $OPT in
	a)
		AUTO=1
		;;
	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
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


# Harvest emails from the generated patches and populate the TO and CC variables
# In addition to To and CC headers/lines, the common Signed-off-by, Tested-by,
# etc. (*-by) will be added to CC.
if [ $AUTO -eq 1 ]; then
	harvest_recipients TO "^[Tt][Oo]: *"
	harvest_recipients CC "^[Cc][Cc]: *"
	harvest_recipients CC "^[A-Z][A-Za-z-]*-[Bb][Yy]: *"
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 "$CC" ]; then
	echo "ERROR: you have not specified any recipients."
	usage
	exit 1
fi


# Generate report for the user and require confirmation before sending
cat <<EOM
The following patches:
$(for PATCH in $PDIR/*.patch; do echo "    $PATCH"; done)

will now be sent via the git send-email command.

EOM
echo "Continue? [y/N] "
read cont

if [ "$cont" == "y" ] || [ "$cont" == "Y" ]; then
	ERROR=0
	export IFS=$','
	GIT_TO=$(for R in $TO; do echo -n "--to='$R' "; done)
	GIT_CC=$(for R in $CC; do echo -n "--cc='$R' "; done)
	unset IFS
	for PATCH in $PDIR/*patch; do
		# We harvest the emails manually, so force git not to.
		eval "git send-email $GIT_TO $GIT_CC --no-chain-reply-to --suppress-cc=all $PATCH"
		if [ $? -eq 1 ]; then
			ERROR=1
		fi
	done

	if [ $ERROR -eq 1 ]; then
		echo "ERROR: Failed to send one or more messages."
	fi
else
	echo "Send aborted."
fi