send-email: support validate hook
authorJonathan Tan <jonathantanmy@google.com>
Fri, 12 May 2017 22:38:26 +0000 (15:38 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 May 2017 02:13:00 +0000 (11:13 +0900)
Currently, send-email has support for rudimentary e-mail validation.
Allow the user to add support for more validation by providing a
sendemail-validate hook.

Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-send-email.txt
Documentation/githooks.txt
git-send-email.perl
t/t9001-send-email.sh
index 9d66166f69d93e544c949ad80fe0f432fa3f1ffd..bb23b02caf3ee50a32c86d97e0451cd4be6ab232 100644 (file)
@@ -377,6 +377,7 @@ have been specified, in which case default to 'compose'.
        Currently, validation means the following:
 +
 --
+               *       Invoke the sendemail-validate hook if present (see linkgit:githooks[5]).
                *       Warn of patches that contain lines longer than 998 characters; this
                        is due to SMTP limits as described by http://www.ietf.org/rfc/rfc2821.txt.
 --
index 706091a569c17cae93e250ed7cb34d056a5b25f0..b2514f4d4426a730e65bcae264a6364eb50bcd60 100644 (file)
@@ -447,6 +447,14 @@ rebase::
 The commits are guaranteed to be listed in the order that they were
 processed by rebase.
 
+sendemail-validate
+~~~~~~~~~~~~~~~~~~
+
+This hook is invoked by 'git send-email'.  It takes a single parameter,
+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
+e-mails.
+
 
 GIT
 ---
index eea0a517f71b66f861db38f70fac0593f8c8cea4..c314cc2b51e363defcd216391df1ef6dd5897f16 100755 (executable)
@@ -25,8 +25,9 @@
 use Text::ParseWords;
 use Term::ANSIColor;
 use File::Temp qw/ tempdir tempfile /;
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catdir catfile);
 use Error qw(:try);
+use Cwd qw(abs_path cwd);
 use Git;
 use Git::I18N;
 
@@ -1737,6 +1738,23 @@ sub unique_email_list {
 
 sub validate_patch {
        my $fn = shift;
+
+       my $validate_hook = catfile(catdir($repo->repo_path(), 'hooks'),
+                                   'sendemail-validate');
+       my $hook_error;
+       if (-x $validate_hook) {
+               my $target = abs_path($fn);
+               # The hook needs a correct cwd and GIT_DIR.
+               my $cwd_save = cwd();
+               chdir($repo->wc_path() or $repo->repo_path())
+                       or die("chdir: $!");
+               local $ENV{"GIT_DIR"} = $repo->repo_path();
+               $hook_error = "rejected by sendemail-validate hook"
+                       if system($validate_hook, $target);
+               chdir($cwd_save) or die("chdir: $!");
+       }
+       return $hook_error if $hook_error;
+
        open(my $fh, '<', $fn)
                or die sprintf(__("unable to open %s: %s\n"), $fn, $!);
        while (my $line = <$fh>) {
index 60a80f60b2685c461f80cdbf4256eb17dc18b85b..15128c755a4eb820b9735e1a94616a694b1b8054 100755 (executable)
@@ -1913,4 +1913,44 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
        test_cmp expected-list actual-list
 '
 
+test_expect_success $PREREQ 'invoke hook' '
+       mkdir -p .git/hooks &&
+
+       write_script .git/hooks/sendemail-validate <<-\EOF &&
+       # test that we have the correct environment variable, pwd, and
+       # argument
+       case "$GIT_DIR" in
+       *.git)
+               true
+               ;;
+       *)
+               false
+               ;;
+       esac &&
+       test -f 0001-add-master.patch &&
+       grep "add master" "$1"
+       EOF
+
+       mkdir subdir &&
+       (
+               # Test that it works even if we are not at the root of the
+               # working tree
+               cd subdir &&
+               git send-email \
+                       --from="Example <nobody@example.com>" \
+                       --to=nobody@example.com \
+                       --smtp-server="$(pwd)/../fake.sendmail" \
+                       ../0001-add-master.patch &&
+
+               # Verify error message when a patch is rejected by the hook
+               sed -e "s/add master/x/" ../0001-add-master.patch >../another.patch &&
+               git send-email \
+                       --from="Example <nobody@example.com>" \
+                       --to=nobody@example.com \
+                       --smtp-server="$(pwd)/../fake.sendmail" \
+                       ../another.patch 2>err
+               test_i18ngrep "rejected by sendemail-validate hook" err
+       )
+'
+
 test_done