Merge branch 'rj/send-email-validate-hook-count-messages'
The sendemail-validate validate hook learned to pass the total number of input files and where in the sequence each invocation is via environment variables. * rj/send-email-validate-hook-count-messages: send-email: export patch counters in validate environment
This commit is contained in:
commit
c4c9d5586f
@ -600,6 +600,28 @@ the name of the file that holds the e-mail to be sent. Exiting with a
|
|||||||
non-zero status causes `git send-email` to abort before sending any
|
non-zero status causes `git send-email` to abort before sending any
|
||||||
e-mails.
|
e-mails.
|
||||||
|
|
||||||
|
The following environment variables are set when executing the hook.
|
||||||
|
|
||||||
|
`GIT_SENDEMAIL_FILE_COUNTER`::
|
||||||
|
A 1-based counter incremented by one for every file holding an e-mail
|
||||||
|
to be sent (excluding any FIFOs). This counter does not follow the
|
||||||
|
patch series counter scheme. It will always start at 1 and will end at
|
||||||
|
GIT_SENDEMAIL_FILE_TOTAL.
|
||||||
|
|
||||||
|
`GIT_SENDEMAIL_FILE_TOTAL`::
|
||||||
|
The total number of files that will be sent (excluding any FIFOs). This
|
||||||
|
counter does not follow the patch series counter scheme. It will always
|
||||||
|
be equal to the number of files being sent, whether there is a cover
|
||||||
|
letter or not.
|
||||||
|
|
||||||
|
These variables may for instance be used to validate patch series.
|
||||||
|
|
||||||
|
The sample `sendemail-validate` hook that comes with Git checks that all sent
|
||||||
|
patches (excluding the cover letter) can be applied on top of the upstream
|
||||||
|
repository default branch without conflicts. Some placeholders are left for
|
||||||
|
additional validation steps to be performed after all patches of a given series
|
||||||
|
have been applied.
|
||||||
|
|
||||||
fsmonitor-watchman
|
fsmonitor-watchman
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -795,11 +795,26 @@ if (@rev_list_opts) {
|
|||||||
@files = handle_backup_files(@files);
|
@files = handle_backup_files(@files);
|
||||||
|
|
||||||
if ($validate) {
|
if ($validate) {
|
||||||
|
# FIFOs can only be read once, exclude them from validation.
|
||||||
|
my @real_files = ();
|
||||||
foreach my $f (@files) {
|
foreach my $f (@files) {
|
||||||
unless (-p $f) {
|
unless (-p $f) {
|
||||||
validate_patch($f, $target_xfer_encoding);
|
push(@real_files, $f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run the loop once again to avoid gaps in the counter due to FIFO
|
||||||
|
# arguments provided by the user.
|
||||||
|
my $num = 1;
|
||||||
|
my $num_files = scalar @real_files;
|
||||||
|
$ENV{GIT_SENDEMAIL_FILE_TOTAL} = "$num_files";
|
||||||
|
foreach my $r (@real_files) {
|
||||||
|
$ENV{GIT_SENDEMAIL_FILE_COUNTER} = "$num";
|
||||||
|
validate_patch($r, $target_xfer_encoding);
|
||||||
|
$num += 1;
|
||||||
|
}
|
||||||
|
delete $ENV{GIT_SENDEMAIL_FILE_COUNTER};
|
||||||
|
delete $ENV{GIT_SENDEMAIL_FILE_TOTAL};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@files) {
|
if (@files) {
|
||||||
|
@ -2326,6 +2326,37 @@ test_expect_success $PREREQ 'invoke hook' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
expected_file_counter_output () {
|
||||||
|
total=$1
|
||||||
|
count=0
|
||||||
|
while test $count -ne $total
|
||||||
|
do
|
||||||
|
count=$((count + 1)) &&
|
||||||
|
echo "$count/$total" || return
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success $PREREQ '--validate hook allows counting of messages' '
|
||||||
|
test_when_finished "rm -rf my-hooks.log" &&
|
||||||
|
test_config core.hooksPath "my-hooks" &&
|
||||||
|
mkdir -p my-hooks &&
|
||||||
|
|
||||||
|
write_script my-hooks/sendemail-validate <<-\EOF &&
|
||||||
|
num=$GIT_SENDEMAIL_FILE_COUNTER &&
|
||||||
|
tot=$GIT_SENDEMAIL_FILE_TOTAL &&
|
||||||
|
echo "$num/$tot" >>my-hooks.log || exit 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
>my-hooks.log &&
|
||||||
|
expected_file_counter_output 4 >expect &&
|
||||||
|
git send-email \
|
||||||
|
--from="Example <from@example.com>" \
|
||||||
|
--to=nobody@example.com \
|
||||||
|
--smtp-server="$(pwd)/fake.sendmail" \
|
||||||
|
--validate -3 --cover-letter --force &&
|
||||||
|
test_cmp expect my-hooks.log
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success $PREREQ 'test that send-email works outside a repo' '
|
test_expect_success $PREREQ 'test that send-email works outside a repo' '
|
||||||
nongit git send-email \
|
nongit git send-email \
|
||||||
--from="Example <nobody@example.com>" \
|
--from="Example <nobody@example.com>" \
|
||||||
|
77
templates/hooks--sendemail-validate.sample
Executable file
77
templates/hooks--sendemail-validate.sample
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# An example hook script to validate a patch (and/or patch series) before
|
||||||
|
# sending it via email.
|
||||||
|
#
|
||||||
|
# The hook should exit with non-zero status after issuing an appropriate
|
||||||
|
# message if it wants to prevent the email(s) from being sent.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "sendemail-validate".
|
||||||
|
#
|
||||||
|
# By default, it will only check that the patch(es) can be applied on top of
|
||||||
|
# the default upstream branch without conflicts in a secondary worktree. After
|
||||||
|
# validation (successful or not) of the last patch of a series, the worktree
|
||||||
|
# will be deleted.
|
||||||
|
#
|
||||||
|
# The following config variables can be set to change the default remote and
|
||||||
|
# remote ref that are used to apply the patches against:
|
||||||
|
#
|
||||||
|
# sendemail.validateRemote (default: origin)
|
||||||
|
# sendemail.validateRemoteRef (default: HEAD)
|
||||||
|
#
|
||||||
|
# Replace the TODO placeholders with appropriate checks according to your
|
||||||
|
# needs.
|
||||||
|
|
||||||
|
validate_cover_letter () {
|
||||||
|
file="$1"
|
||||||
|
# TODO: Replace with appropriate checks (e.g. spell checking).
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_patch () {
|
||||||
|
file="$1"
|
||||||
|
# Ensure that the patch applies without conflicts.
|
||||||
|
git am -3 "$file" || return
|
||||||
|
# TODO: Replace with appropriate checks for this patch
|
||||||
|
# (e.g. checkpatch.pl).
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_series () {
|
||||||
|
# TODO: Replace with appropriate checks for the whole series
|
||||||
|
# (e.g. quick build, coding style checks, etc.).
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
# main -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if test "$GIT_SENDEMAIL_FILE_COUNTER" = 1
|
||||||
|
then
|
||||||
|
remote=$(git config --default origin --get sendemail.validateRemote) &&
|
||||||
|
ref=$(git config --default HEAD --get sendemail.validateRemoteRef) &&
|
||||||
|
worktree=$(mktemp --tmpdir -d sendemail-validate.XXXXXXX) &&
|
||||||
|
git worktree add -fd --checkout "$worktree" "refs/remotes/$remote/$ref" &&
|
||||||
|
git config --replace-all sendemail.validateWorktree "$worktree"
|
||||||
|
else
|
||||||
|
worktree=$(git config --get sendemail.validateWorktree)
|
||||||
|
fi || {
|
||||||
|
echo "sendemail-validate: error: failed to prepare worktree" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
unset GIT_DIR GIT_WORK_TREE
|
||||||
|
cd "$worktree" &&
|
||||||
|
|
||||||
|
if grep -q "^diff --git " "$1"
|
||||||
|
then
|
||||||
|
validate_patch "$1"
|
||||||
|
else
|
||||||
|
validate_cover_letter "$1"
|
||||||
|
fi &&
|
||||||
|
|
||||||
|
if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL"
|
||||||
|
then
|
||||||
|
git config --unset-all sendemail.validateWorktree &&
|
||||||
|
trap 'git worktree remove -ff "$worktree"' EXIT &&
|
||||||
|
validate_series
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user