Merge branch 'km/send-email-remove-cruft-in-address'
authorJunio C Hamano <gitster@pobox.com>
Thu, 29 Nov 2012 20:52:49 +0000 (12:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 29 Nov 2012 20:52:49 +0000 (12:52 -0800)
* km/send-email-remove-cruft-in-address:
git-send-email: allow edit invalid email address
git-send-email: ask what to do with an invalid email address
git-send-email: remove invalid addresses earlier
git-send-email: fix fallback code in extract_valid_address()
git-send-email: remove garbage after email address

1  2 
git-send-email.perl
diff --combined git-send-email.perl
index aca0225e56b2987b9a86c10a7b235bb904fb4ae7,f3bbc166d6fff82add7e61d0d4cb9d68a2007e34..94c7f76a156f1eaa4c622db267710f2982cf7826
@@@ -753,11 -753,16 +753,11 @@@ if (!$force) 
        }
  }
  
 -my $prompting = 0;
  if (!defined $sender) {
        $sender = $repoauthor || $repocommitter || '';
 -      $sender = ask("Who should the emails appear to be from? [$sender] ",
 -                    default => $sender,
 -                    valid_re => qr/\@.*\./, confirm_only => 1);
 -      print "Emails will be sent from: ", $sender, "\n";
 -      $prompting++;
  }
  
 +my $prompting = 0;
  if (!@initial_to && !defined $to_cmd) {
        my $to = ask("Who should the emails be sent to (if any)? ",
                     default => "",
@@@ -781,9 -786,11 +781,11 @@@ sub expand_one_alias 
  }
  
  @initial_to = expand_aliases(@initial_to);
- @initial_to = (map { sanitize_address($_) } @initial_to);
+ @initial_to = validate_address_list(sanitize_address_list(@initial_to));
  @initial_cc = expand_aliases(@initial_cc);
+ @initial_cc = validate_address_list(sanitize_address_list(@initial_cc));
  @bcclist = expand_aliases(@bcclist);
+ @bcclist = validate_address_list(sanitize_address_list(@bcclist));
  
  if ($thread && !defined $initial_reply_to && $prompting) {
        $initial_reply_to = ask(
@@@ -826,12 -833,45 +828,45 @@@ sub extract_valid_address 
        $address =~ s/^\s*<(.*)>\s*$/$1/;
        if ($have_email_valid) {
                return scalar Email::Valid->address($address);
-       } else {
-               # less robust/correct than the monster regexp in Email::Valid,
-               # but still does a 99% job, and one less dependency
-               $address =~ /($local_part_regexp\@$domain_regexp)/;
-               return $1;
        }
+       # less robust/correct than the monster regexp in Email::Valid,
+       # but still does a 99% job, and one less dependency
+       return $1 if $address =~ /($local_part_regexp\@$domain_regexp)/;
+       return undef;
+ }
+ sub extract_valid_address_or_die {
+       my $address = shift;
+       $address = extract_valid_address($address);
+       die "error: unable to extract a valid address from: $address\n"
+               if !$address;
+       return $address;
+ }
+ sub validate_address {
+       my $address = shift;
+       while (!extract_valid_address($address)) {
+               print STDERR "error: unable to extract a valid address from: $address\n";
+               $_ = ask("What to do with this address? ([q]uit|[d]rop|[e]dit): ",
+                       valid_re => qr/^(?:quit|q|drop|d|edit|e)/i,
+                       default => 'q');
+               if (/^d/i) {
+                       return undef;
+               } elsif (/^q/i) {
+                       cleanup_compose_files();
+                       exit(0);
+               }
+               $address = ask("Who should the email be sent to (if any)? ",
+                       default => "",
+                       valid_re => qr/\@.*\./, confirm_only => 1);
+       }
+       return $address;
+ }
+ sub validate_address_list {
+       return (grep { defined $_ }
+               map { validate_address($_) } @_);
  }
  
  # Usually don't need to change anything below here.
@@@ -919,6 -959,10 +954,10 @@@ sub quote_subject 
  # use the simplest quoting being able to handle the recipient
  sub sanitize_address {
        my ($recipient) = @_;
+       # remove garbage after email address
+       $recipient =~ s/(.*>).*$/$1/;
        my ($recipient_name, $recipient_addr) = ($recipient =~ /^(.*?)\s*(<.*)/);
  
        if (not $recipient_name) {
  
  }
  
+ sub sanitize_address_list {
+       return (map { sanitize_address($_) } @_);
+ }
  # Returns the local Fully Qualified Domain Name (FQDN) if available.
  #
  # Tightly configured MTAa require that a caller sends a real DNS
@@@ -1008,14 -1056,13 +1051,13 @@@ sub maildomain 
  
  sub send_message {
        my @recipients = unique_email_list(@to);
-       @cc = (grep { my $cc = extract_valid_address($_);
+       @cc = (grep { my $cc = extract_valid_address_or_die($_);
                      not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients
                    }
-              map { sanitize_address($_) }
               @cc);
        my $to = join (",\n\t", @recipients);
        @recipients = unique_email_list(@recipients,@cc,@bcclist);
-       @recipients = (map { extract_valid_address($_) } @recipients);
+       @recipients = (map { extract_valid_address_or_die($_) } @recipients);
        my $date = format_2822_time($time++);
        my $gitversion = '@@GIT_VERSION@@';
        if ($gitversion =~ m/..GIT_VERSION../) {
@@@ -1258,7 -1305,7 +1300,7 @@@ foreach my $t (@files) 
                                foreach my $addr (parse_address_line($1)) {
                                        printf("(mbox) Adding to: %s from line '%s'\n",
                                                $addr, $_) unless $quiet;
-                                       push @to, sanitize_address($addr);
+                                       push @to, $addr;
                                }
                        }
                        elsif (/^Cc:\s+(.*)$/) {
                ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
        $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc);
  
+       @to = validate_address_list(sanitize_address_list(@to));
+       @cc = validate_address_list(sanitize_address_list(@cc));
        @to = (@initial_to, @to);
        @cc = (@initial_cc, @cc);
  
@@@ -1422,14 -1472,10 +1467,10 @@@ sub unique_email_list 
        my @emails;
  
        foreach my $entry (@_) {
-               if (my $clean = extract_valid_address($entry)) {
-                       $seen{$clean} ||= 0;
-                       next if $seen{$clean}++;
-                       push @emails, $entry;
-               } else {
-                       print STDERR "W: unable to extract a valid address",
-                                       " from: $entry\n";
-               }
+               my $clean = extract_valid_address_or_die($entry);
+               $seen{$clean} ||= 0;
+               next if $seen{$clean}++;
+               push @emails, $entry;
        }
        return @emails;
  }