From c573572c52758c4368ebc410d6b801fefa6bcbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 9 May 2019 13:48:28 +0200 Subject: send-email: move the read_config() function above getopts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for a later change where we'll read the config first before parsing command-line options. As the move detection will show no lines (except one line of comment) is changed here, just moved around. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/git-send-email.perl b/git-send-email.perl index f4c0790..6d6dee6 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -307,6 +307,54 @@ sub signal_handler { $SIG{TERM} = \&signal_handler; $SIG{INT} = \&signal_handler; +# Read our sendemail.* config +sub read_config { + my ($prefix) = @_; + + foreach my $setting (keys %config_bool_settings) { + my $target = $config_bool_settings{$setting}->[0]; + $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target); + } + + foreach my $setting (keys %config_path_settings) { + my $target = $config_path_settings{$setting}; + if (ref($target) eq "ARRAY") { + unless (@$target) { + my @values = Git::config_path(@repo, "$prefix.$setting"); + @$target = @values if (@values && defined $values[0]); + } + } + else { + $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target); + } + } + + foreach my $setting (keys %config_settings) { + my $target = $config_settings{$setting}; + next if $setting eq "to" and defined $no_to; + next if $setting eq "cc" and defined $no_cc; + next if $setting eq "bcc" and defined $no_bcc; + if (ref($target) eq "ARRAY") { + unless (@$target) { + my @values = Git::config(@repo, "$prefix.$setting"); + @$target = @values if (@values && defined $values[0]); + } + } + else { + $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); + } + } + + if (!defined $smtp_encryption) { + my $enc = Git::config(@repo, "$prefix.smtpencryption"); + if (defined $enc) { + $smtp_encryption = $enc; + } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { + $smtp_encryption = 'ssl'; + } + } +} + # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: @@ -387,55 +435,6 @@ die __("`batch-size` and `relogin` must be specified together " . "(via command-line or configuration option)\n") if defined $relogin_delay and not defined $batch_size; -# Now, let's fill any that aren't set in with defaults: - -sub read_config { - my ($prefix) = @_; - - foreach my $setting (keys %config_bool_settings) { - my $target = $config_bool_settings{$setting}->[0]; - $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target); - } - - foreach my $setting (keys %config_path_settings) { - my $target = $config_path_settings{$setting}; - if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config_path(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } - } - else { - $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target); - } - } - - foreach my $setting (keys %config_settings) { - my $target = $config_settings{$setting}; - next if $setting eq "to" and defined $no_to; - next if $setting eq "cc" and defined $no_cc; - next if $setting eq "bcc" and defined $no_bcc; - if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } - } - else { - $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); - } - } - - if (!defined $smtp_encryption) { - my $enc = Git::config(@repo, "$prefix.smtpencryption"); - if (defined $enc) { - $smtp_encryption = $enc; - } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { - $smtp_encryption = 'ssl'; - } - } -} - # read configuration from [sendemail "$identity"], fall back on [sendemail] $identity = Git::config(@repo, "sendemail.identity") unless (defined $identity); read_config("sendemail.$identity") if (defined $identity); -- cgit v0.10.2-6-g49f6 From e60f6d13f3b04ee3a8aa50ed5a0b97d2fb58bad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 9 May 2019 13:48:29 +0200 Subject: send-email: rename the @bcclist variable for consistency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "to" and "cc" variables are named @initial_{to,cc}, let's rename this one to match them. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/git-send-email.perl b/git-send-email.perl index 6d6dee6..b6af001 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -169,7 +169,7 @@ my $re_encoded_text = qr/[^? \000-\037\177-\377]+/; my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/; # Variables we fill in automatically, or via prompting: -my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh, +my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@initial_bcc,$no_bcc,@xh, $initial_in_reply_to,$reply_to,$initial_subject,@files, $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time); @@ -264,7 +264,7 @@ my %config_settings = ( "cc" => \@initial_cc, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, - "bcc" => \@bcclist, + "bcc" => \@initial_bcc, "suppresscc" => \@suppress_cc, "envelopesender" => \$envelope_sender, "confirm" => \$confirm, @@ -374,7 +374,7 @@ $rc = GetOptions( "no-to" => \$no_to, "cc=s" => \@initial_cc, "no-cc" => \$no_cc, - "bcc=s" => \@bcclist, + "bcc=s" => \@initial_bcc, "no-bcc" => \$no_bcc, "chain-reply-to!" => \$chain_reply_to, "no-chain-reply-to" => sub {$chain_reply_to = 0}, @@ -922,7 +922,7 @@ sub expand_one_alias { @initial_to = process_address_list(@initial_to); @initial_cc = process_address_list(@initial_cc); -@bcclist = process_address_list(@bcclist); +@initial_bcc = process_address_list(@initial_bcc); if ($thread && !defined $initial_in_reply_to && $prompting) { $initial_in_reply_to = ask( @@ -1345,7 +1345,7 @@ sub send_message { } @cc); my $to = join (",\n\t", @recipients); - @recipients = unique_email_list(@recipients,@cc,@bcclist); + @recipients = unique_email_list(@recipients,@cc,@initial_bcc); @recipients = (map { extract_valid_address_or_die($_) } @recipients); my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; -- cgit v0.10.2-6-g49f6 From 3494dfd3ee058bbeab6a462673d9184dcd694a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 9 May 2019 13:48:30 +0200 Subject: send-email: do defaults -> config -> getopt in that order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the git-send-email command-line argument parsing and config reading code to parse those two in the right order. I.e. first we set our hardcoded defaults, then we read our config, and finally we read the command-line, with later sets overriding earlier sets. This fixes a bug introduced in e67a228cd8 ("send-email: automatically determine transfer-encoding", 2018-07-08). That change broke the reading of sendmail.transferencoding because it wasn't careful to update the code to parse them in the previous "defaults -> getopt -> config" order. But as we can see from the history for this file doing it this way was never what we actually wanted, it's just something we grew organically as of 5483c71d7a ("git-send-email: make options easier to configure.", 2007-06-27) and have been dealing with the fallout since, e.g. in 463b0ea22b ("send-email: Fix %config_path_settings handling", 2011-10-14). As can be seen in this change the only place where we actually want to do something clever is with the to/cc/bcc variables, where setting them on the command-line (or using --no-{to,cc,bcc}) should clear out values we grab from the config. All the rest are things where the command-line should simply override the config values, and by reading the config first the config code doesn't need all this "let's not set it, if it was on the command-line" special-casing, as [1] shows we'd otherwise need to care about the difference between whether something was a default or present in config to fix the bug in e67a228cd8. 1. https://public-inbox.org/git/20190508105607.178244-2-gitster@pobox.com/ Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/git-send-email.perl b/git-send-email.perl index b6af001..46a5242 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -169,11 +169,15 @@ my $re_encoded_text = qr/[^? \000-\037\177-\377]+/; my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/; # Variables we fill in automatically, or via prompting: -my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@initial_bcc,$no_bcc,@xh, +my (@to,@cc,@xh,$envelope_sender, $initial_in_reply_to,$reply_to,$initial_subject,@files, - $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time); - -my $envelope_sender; + $author,$sender,$smtp_authpass,$annotate,$compose,$time); +# Things we either get from config, *or* are overridden on the +# command-line. +my ($no_cc, $no_to, $no_bcc); +my (@config_to, @getopt_to); +my (@config_cc, @getopt_cc); +my (@config_bcc, @getopt_bcc); # Example reply to: #$initial_in_reply_to = ''; #<20050203173208.GA23964@foobar.com>'; @@ -220,33 +224,37 @@ sub do_edit { } # Variables with corresponding config settings -my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc); +my ($suppress_from, $signed_off_by_cc); my ($cover_cc, $cover_to); my ($to_cmd, $cc_cmd); my ($smtp_server, $smtp_server_port, @smtp_server_options); my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); my ($batch_size, $relogin_delay); my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth); -my ($validate, $confirm); +my ($confirm); my (@suppress_cc); my ($auto_8bit_encoding); my ($compose_encoding); -my $target_xfer_encoding = 'auto'; - +# Variables with corresponding config settings & hardcoded defaults my ($debug_net_smtp) = 0; # Net::SMTP, see send_message() +my $thread = 1; +my $chain_reply_to = 0; +my $use_xmailer = 1; +my $validate = 1; +my $target_xfer_encoding = 'auto'; my %config_bool_settings = ( - "thread" => [\$thread, 1], - "chainreplyto" => [\$chain_reply_to, 0], - "suppressfrom" => [\$suppress_from, undef], - "signedoffbycc" => [\$signed_off_by_cc, undef], - "cccover" => [\$cover_cc, undef], - "tocover" => [\$cover_to, undef], - "signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated - "validate" => [\$validate, 1], - "multiedit" => [\$multiedit, undef], - "annotate" => [\$annotate, undef], - "xmailer" => [\$use_xmailer, 1] + "thread" => \$thread, + "chainreplyto" => \$chain_reply_to, + "suppressfrom" => \$suppress_from, + "signedoffbycc" => \$signed_off_by_cc, + "cccover" => \$cover_cc, + "tocover" => \$cover_to, + "signedoffcc" => \$signed_off_by_cc, + "validate" => \$validate, + "multiedit" => \$multiedit, + "annotate" => \$annotate, + "xmailer" => \$use_xmailer, ); my %config_settings = ( @@ -259,12 +267,12 @@ my %config_settings = ( "smtpauth" => \$smtp_auth, "smtpbatchsize" => \$batch_size, "smtprelogindelay" => \$relogin_delay, - "to" => \@initial_to, + "to" => \@config_to, "tocmd" => \$to_cmd, - "cc" => \@initial_cc, + "cc" => \@config_cc, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, - "bcc" => \@initial_bcc, + "bcc" => \@config_bcc, "suppresscc" => \@suppress_cc, "envelopesender" => \$envelope_sender, "confirm" => \$confirm, @@ -312,8 +320,9 @@ sub read_config { my ($prefix) = @_; foreach my $setting (keys %config_bool_settings) { - my $target = $config_bool_settings{$setting}->[0]; - $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target); + my $target = $config_bool_settings{$setting}; + my $v = Git::config_bool(@repo, "$prefix.$setting"); + $$target = $v if defined $v; } foreach my $setting (keys %config_path_settings) { @@ -325,15 +334,13 @@ sub read_config { } } else { - $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target); + my $v = Git::config_path(@repo, "$prefix.$setting"); + $$target = $v if defined $v; } } foreach my $setting (keys %config_settings) { my $target = $config_settings{$setting}; - next if $setting eq "to" and defined $no_to; - next if $setting eq "cc" and defined $no_cc; - next if $setting eq "bcc" and defined $no_bcc; if (ref($target) eq "ARRAY") { unless (@$target) { my @values = Git::config(@repo, "$prefix.$setting"); @@ -341,7 +348,8 @@ sub read_config { } } else { - $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); + my $v = Git::config(@repo, "$prefix.$setting"); + $$target = $v if defined $v; } } @@ -355,6 +363,10 @@ sub read_config { } } +$identity = Git::config(@repo, "sendemail.identity"); +read_config("sendemail.$identity") if defined $identity; +read_config("sendemail"); + # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: @@ -369,12 +381,12 @@ $rc = GetOptions( "in-reply-to=s" => \$initial_in_reply_to, "reply-to=s" => \$reply_to, "subject=s" => \$initial_subject, - "to=s" => \@initial_to, + "to=s" => \@getopt_to, "to-cmd=s" => \$to_cmd, "no-to" => \$no_to, - "cc=s" => \@initial_cc, + "cc=s" => \@getopt_cc, "no-cc" => \$no_cc, - "bcc=s" => \@initial_bcc, + "bcc=s" => \@getopt_bcc, "no-bcc" => \$no_bcc, "chain-reply-to!" => \$chain_reply_to, "no-chain-reply-to" => sub {$chain_reply_to = 0}, @@ -423,6 +435,11 @@ $rc = GetOptions( "relogin-delay=i" => \$relogin_delay, ); +# Munge any "either config or getopt, not both" variables +my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to); +my @initial_cc = @getopt_cc ? @getopt_cc : ($no_cc ? () : @config_cc); +my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc); + usage() if $help; unless ($rc) { usage(); @@ -435,16 +452,6 @@ die __("`batch-size` and `relogin` must be specified together " . "(via command-line or configuration option)\n") if defined $relogin_delay and not defined $batch_size; -# read configuration from [sendemail "$identity"], fall back on [sendemail] -$identity = Git::config(@repo, "sendemail.identity") unless (defined $identity); -read_config("sendemail.$identity") if (defined $identity); -read_config("sendemail"); - -# fall back on builtin bool defaults -foreach my $setting (values %config_bool_settings) { - ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]})); -} - # 'default' encryption is none -- this only prevents a warning $smtp_encryption = '' unless (defined $smtp_encryption); diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 1da282c..c67be97 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1433,7 +1433,18 @@ test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEnc test -z "$(ls msgtxt*)" ' -test_expect_success $PREREQ 'sendemail.transferencoding=8bit' ' +test_expect_success $PREREQ 'sendemail.transferencoding=8bit via config' ' + clean_fake_sendmail && + git -c sendemail.transferencoding=8bit send-email \ + --smtp-server="$(pwd)/fake.sendmail" \ + email-using-8bit \ + 2>errors >out && + sed '1,/^$/d' msgtxt1 >actual && + sed '1,/^$/d' email-using-8bit >expected && + test_cmp expected actual +' + +test_expect_success $PREREQ 'sendemail.transferencoding=8bit via cli' ' clean_fake_sendmail && git send-email \ --transfer-encoding=8bit \ -- cgit v0.10.2-6-g49f6 From 2554dd1aa8ddbaa043cbd12da0ec7084a1413f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 17 May 2019 21:55:41 +0200 Subject: send-email: remove cargo-culted multi-patch pattern in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change test code added in f434c083a0 ("send-email: add --no-cc, --no-to, and --no-bcc", 2010-03-07) which blindly copied a pattern from an earlier test added in 32ae83194b ("add a test for git-send-email for non-threaded mails", 2009-06-12) where the "$patches" variable was supplied more than once. As it turns out we didn't need more than one "$patches" for the test added in 32ae83194b either. The only tests that actually needed this sort of invocation were the tests added in 54aae5e1a0 ("t9001: send-email interation with --in-reply-to and --chain-reply-to", 2010-10-19). Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index c67be97..461bb5b 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1176,7 +1176,7 @@ test_expect_success $PREREQ 'no in-reply-to and no threading' ' --from="Example " \ --to=nobody@example.com \ --no-thread \ - $patches $patches >stdout && + $patches >stdout && ! grep "In-Reply-To: " stdout ' @@ -1196,7 +1196,7 @@ test_expect_success $PREREQ 'sendemail.to works' ' git send-email \ --dry-run \ --from="Example " \ - $patches $patches >stdout && + $patches >stdout && grep "To: Somebody " stdout ' @@ -1206,7 +1206,7 @@ test_expect_success $PREREQ '--no-to overrides sendemail.to' ' --from="Example " \ --no-to \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "To: nobody@example.com" stdout && ! grep "To: Somebody " stdout ' @@ -1217,7 +1217,7 @@ test_expect_success $PREREQ 'sendemail.cc works' ' --dry-run \ --from="Example " \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: Somebody " stdout ' @@ -1228,7 +1228,7 @@ test_expect_success $PREREQ '--no-cc overrides sendemail.cc' ' --no-cc \ --cc=bodies@example.com \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: bodies@example.com" stdout && ! grep "Cc: Somebody " stdout ' @@ -1240,7 +1240,7 @@ test_expect_success $PREREQ 'sendemail.bcc works' ' --from="Example " \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:" stdout ' @@ -1252,7 +1252,7 @@ test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' ' --bcc=bodies@example.com \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:" stdout && ! grep "RCPT TO:" stdout ' -- cgit v0.10.2-6-g49f6 From a8aea5db7a174c29a34b2e1fad85aa2fcf33a687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 17 May 2019 21:55:42 +0200 Subject: send-email: fix broken transferEncoding tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I fixed a bug that had broken the reading of sendmail.transferEncoding in 3494dfd3ee ("send-email: do defaults -> config -> getopt in that order", 2019-05-09), but the test I added in that commit did nothing to assert the bug had been fixed. That issue originates in 8d81408435 ("git-send-email: add --transfer-encoding option", 2014-11-25) which first added the "sendemail.transferencoding=8bit". That test has never done anything meaningful. It tested that the "--transfer-encoding=8bit" option would turn on the 8bit Transfer-Encoding, but that was the default at the time (and now). As checking out 8d81408435 and editing the test to remove that option will reveal, supplying it never did anything. So when I copied it thinking it would work in 3494dfd3ee I copied a previously broken test, although I was making sure it did the right thing via da-hoc debugger inspection, so the bug was fixed. So fix the test I added in 3494dfd3ee, as well as the long-standing test added in 8d81408435. To test if we're actually setting the Transfer-Encoding let's set it to 7bit, not 8bit, as 7bit will error out on "email-using-8bit". This means that we can remove the "sendemail.transferencoding=7bit fails on 8bit data" test, since it was redundant, we now have other tests that assert that that'll fail. While I'm at it convert "git config " in the test setup to just "-c =" on the command-line. Then we don't need to cleanup after these tests, and there's no sense in asserting where config values come from in these tests, we can take that as a given. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 461bb5b..98858e5 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1409,10 +1409,10 @@ test_expect_success $PREREQ 'setup expect' ' EOF ' -test_expect_success $PREREQ 'sendemail.transferencoding=7bit fails on 8bit data' ' +test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' clean_fake_sendmail && - git config sendemail.transferEncoding 7bit && - test_must_fail git send-email \ + test_must_fail git -c sendemail.transferEncoding=8bit \ + send-email \ --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ @@ -1421,11 +1421,10 @@ test_expect_success $PREREQ 'sendemail.transferencoding=7bit fails on 8bit data' test -z "$(ls msgtxt*)" ' -test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' +test_expect_success $PREREQ 'sendemail.transferEncoding via config' ' clean_fake_sendmail && - git config sendemail.transferEncoding 8bit && - test_must_fail git send-email \ - --transfer-encoding=7bit \ + test_must_fail git -c sendemail.transferEncoding=7bit \ + send-email \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && @@ -1433,27 +1432,15 @@ test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEnc test -z "$(ls msgtxt*)" ' -test_expect_success $PREREQ 'sendemail.transferencoding=8bit via config' ' +test_expect_success $PREREQ 'sendemail.transferEncoding via cli' ' clean_fake_sendmail && - git -c sendemail.transferencoding=8bit send-email \ - --smtp-server="$(pwd)/fake.sendmail" \ - email-using-8bit \ - 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && - sed '1,/^$/d' email-using-8bit >expected && - test_cmp expected actual -' - -test_expect_success $PREREQ 'sendemail.transferencoding=8bit via cli' ' - clean_fake_sendmail && - git send-email \ - --transfer-encoding=8bit \ + test_must_fail git send-email \ + --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && - sed '1,/^$/d' email-using-8bit >expected && - test_cmp expected actual + grep "cannot send message as 7bit" errors && + test -z "$(ls msgtxt*)" ' test_expect_success $PREREQ 'setup expect' ' -- cgit v0.10.2-6-g49f6 From 564eba4bc03325ac03c00b8769bd4a8414c4cc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 17 May 2019 21:55:43 +0200 Subject: send-email: document --no-[to|cc|bcc] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These options added in f434c083a0 ("send-email: add --no-cc, --no-to, and --no-bcc", 2010-03-07) were never documented. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 2f32dbf..01fd9d4 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -273,6 +273,10 @@ must be used for each option. Automating ~~~~~~~~~~ +--no-[to|cc|bcc]:: + Clears any list of "To:", "Cc:", "Bcc:" addresses previously + set via config. + --to-cmd=:: Specify a command to execute once per patch file which should generate patch file specific "To:" entries. -- cgit v0.10.2-6-g49f6 From 3ff15040e22676db0b369efbd8b908b8fcc9b38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 17 May 2019 21:55:44 +0200 Subject: send-email: fix regression in sendemail.identity parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a regression in my recent 3494dfd3ee ("send-email: do defaults -> config -> getopt in that order", 2019-05-09). I missed that the $identity variable needs to be extracted from the command-line before we do the config reading, as it determines which config variable we should read first. See [1] for the report. The sendemail.identity feature was added back in 34cc60ce2b ("send-email: Add support for SSL and SMTP-AUTH", 2007-09-03), there were no tests to assert that it worked properly. So let's fix both the regression, and add some tests to assert that this is being parsed properly. While I'm at it I'm adding a --no-identity option to go with --[to|cc|bcc] variable, since the semantics are similar. It's like to/cc/bcc except that unlike those we don't support multiple identities, but we could now easily add it support for it if anyone cares. In just fixing the --identity command-line parsing bug I discovered that a narrow fix to that wouldn't do. In read_config() we had a state machine that would only set config values if they weren't set already, and thus by proxy we wouldn't e.g. set "to" based on sendemail.to if we'd seen sendemail.gmail.to before, with --identity=gmail. I'd modified some of the relevant code in 3494dfd3ee, but just reverting to that wouldn't do, since it would bring back the regression fixed in that commit. Refactor read_config() do what we actually mean here. We don't want to set a given sendemail.VAR if a sendemail.$identity.VAR previously set it. The old code was conflating this desire with the hardcoded defaults for these variables, and as discussed in 3494dfd3ee that was never going to work. Instead pass along the state of whether an identity config set something before, as distinguished from the state of the default just being false, or the default being a non-bool or true (e.g. --transferencoding). I'm still not happy with the test coverage here, e.g. there's nothing testing sendemail.smtpEncryption, but I only have so much time to fix this code. 1. https://public-inbox.org/git/5cddeb61.1c69fb81.47ed4.e648@mx.google.com/ Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 01fd9d4..cf4e3d9 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -277,6 +277,10 @@ Automating Clears any list of "To:", "Cc:", "Bcc:" addresses previously set via config. +--no-identity:: + Clears the previously read value of `sendemail.identity` set + via config, if any. + --to-cmd=:: Specify a command to execute once per patch file which should generate patch file specific "To:" entries. diff --git a/git-send-email.perl b/git-send-email.perl index 46a5242..4745983 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -174,7 +174,7 @@ my (@to,@cc,@xh,$envelope_sender, $author,$sender,$smtp_authpass,$annotate,$compose,$time); # Things we either get from config, *or* are overridden on the # command-line. -my ($no_cc, $no_to, $no_bcc); +my ($no_cc, $no_to, $no_bcc, $no_identity); my (@config_to, @getopt_to); my (@config_cc, @getopt_cc); my (@config_bcc, @getopt_bcc); @@ -317,44 +317,53 @@ $SIG{INT} = \&signal_handler; # Read our sendemail.* config sub read_config { - my ($prefix) = @_; + my ($configured, $prefix) = @_; foreach my $setting (keys %config_bool_settings) { my $target = $config_bool_settings{$setting}; my $v = Git::config_bool(@repo, "$prefix.$setting"); - $$target = $v if defined $v; + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; } foreach my $setting (keys %config_path_settings) { my $target = $config_path_settings{$setting}; if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config_path(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } + my @values = Git::config_path(@repo, "$prefix.$setting"); + next unless @values; + next if $configured->{$setting}++; + @$target = @values; } else { my $v = Git::config_path(@repo, "$prefix.$setting"); - $$target = $v if defined $v; + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; } } foreach my $setting (keys %config_settings) { my $target = $config_settings{$setting}; if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } + my @values = Git::config(@repo, "$prefix.$setting"); + next unless @values; + next if $configured->{$setting}++; + @$target = @values; } else { my $v = Git::config(@repo, "$prefix.$setting"); - $$target = $v if defined $v; + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; } } if (!defined $smtp_encryption) { - my $enc = Git::config(@repo, "$prefix.smtpencryption"); + my $setting = "$prefix.smtpencryption"; + my $enc = Git::config(@repo, $setting); + return unless defined $enc; + return if $configured->{$setting}++; if (defined $enc) { $smtp_encryption = $enc; } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { @@ -363,16 +372,29 @@ sub read_config { } } +# sendemail.identity yields to --identity. We must parse this +# special-case first before the rest of the config is read. $identity = Git::config(@repo, "sendemail.identity"); -read_config("sendemail.$identity") if defined $identity; -read_config("sendemail"); +my $rc = GetOptions( + "identity=s" => \$identity, + "no-identity" => \$no_identity, +); +usage() unless $rc; +undef $identity if $no_identity; + +# Now we know enough to read the config +{ + my %configured; + read_config(\%configured, "sendemail.$identity") if defined $identity; + read_config(\%configured, "sendemail"); +} # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: my $help; -my $rc = GetOptions("h" => \$help, - "dump-aliases" => \$dump_aliases); +$rc = GetOptions("h" => \$help, + "dump-aliases" => \$dump_aliases); usage() unless $rc; die __("--dump-aliases incompatible with other options\n") if !$help and $dump_aliases and @ARGV; @@ -401,7 +423,6 @@ $rc = GetOptions( "smtp-debug:i" => \$debug_net_smtp, "smtp-domain:s" => \$smtp_domain, "smtp-auth=s" => \$smtp_auth, - "identity=s" => \$identity, "annotate!" => \$annotate, "no-annotate" => sub {$annotate = 0}, "compose" => \$compose, diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 98858e5..4be4b50 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1200,6 +1200,61 @@ test_expect_success $PREREQ 'sendemail.to works' ' grep "To: Somebody " stdout ' +test_expect_success $PREREQ 'setup sendemail.identity' ' + git config --replace-all sendemail.to "default@example.com" && + git config --replace-all sendemail.isp.to "isp@example.com" && + git config --replace-all sendemail.cloud.to "cloud@example.com" +' + +test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' ' + git -c sendemail.identity=cloud send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' ' + git -c sendemail.identity=cloud send-email \ + --identity=isp \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: isp@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' ' + git -c sendemail.identity=cloud send-email \ + --no-identity \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: default@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: bool identity variable existance overrides' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=true \ + -c sendemail.cloud.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout +' + test_expect_success $PREREQ '--no-to overrides sendemail.to' ' git send-email \ --dry-run \ @@ -1757,6 +1812,15 @@ test_expect_success '--dump-aliases must be used alone' ' test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting ' +test_expect_success $PREREQ 'aliases and sendemail.identity' ' + test_must_fail git \ + -c sendemail.identity=cloud \ + -c sendemail.aliasesfile=default-aliases \ + -c sendemail.cloud.aliasesfile=cloud-aliases \ + send-email -1 2>stderr && + test_i18ngrep "cloud-aliases" stderr +' + test_sendmail_aliases () { msg="$1" && shift && expect="$@" && -- cgit v0.10.2-6-g49f6