{"thread":{"id":"34220","subject":"[PATCH v2] send-email: allow use of basic email list in --cc --to and --bcc","startedAt":"2013-06-19T11:34:00Z","lastAt":"2013-06-19T11:51:02Z","messageCount":2,"participants":["jorge-juan.garcia-garcia@ensimag.imag.fr","Matthieu Moy"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"221375","messageId":"1371641640-3897-1-git-send-email-Jorge-Juan.Garcia-Garcia@ensimag.imag.fr","threadId":"34220","inReplyTo":null,"subject":"[PATCH v2] send-email: allow use of basic email list in --cc --to and --bcc","fromName":"","fromEmail":"jorge-juan.garcia-garcia@ensimag.imag.fr","sentAt":"2013-06-19T11:34:00Z","receivedAt":"2013-06-19T11:34:00Z","isPatch":true,"sender":{"key":"jorge-juan.garcia-garcia@ensimag.imag.fr","avatar":null},"body":"From: Jorge Juan Garcia Garcia <Jorge-Juan.Garcia-Garcia@ensimag.imag.fr>\n\nMake it so that we can use a list of email in flags\ninstead of having to use one flag per email address.\n\nThe use-case is to copy-paste a list of addresses from an email.\nThis change makes it so that we no longer need to cut the list.\n\nThe format of email list handled is pretty basic for now:\n\t$ git send-email --to='Foo <foo@example.com>, bar@example.com'\nWe thought it would be nice to have a \"first-step\" version which works\nbefore handling more complex ones such as names with commas:\n\t$ git send-email --to='Foo, Bar <foobar@example.com>'\n\nThis artificial limitation is imposed by 79ee555b (Check and document\nthe options to prevent mistakes, 2006-06-21).\n\nSigned-off-by: Mathieu Lienard--Mayor <Mathieu.Lienard--Mayor@ensimag.imag.fr>\nSigned-off-by: Jorge Juan Garcia Garcia <Jorge-Juan.Garcia-Garcia@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n\nChanges since v1:\n - more detailed commit message, explaining the most common use-case,\n   and referring to the commit which introduced the comma limitation\n - use of map in the function, to match sanitize_address_list\n - did not change the two regexp into one, because it's faster with two\n\n Documentation/git-send-email.txt |   21 +++++++++++++++------\n git-send-email.perl              |   36 ++++++++++++++++++++++--------------\n t/t9001-send-email.sh            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 73 insertions(+), 21 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 40a9a9a..e3444cf 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -50,16 +50,22 @@ Composing\n \t'sendemail.multiedit'.\n \n --bcc=<address>::\n+--bcc=\"[<address>,...]\"::\n \tSpecify a \"Bcc:\" value for each email. Default is the value of\n \t'sendemail.bcc'.\n-+\n-The --bcc option must be repeated for each user you want on the bcc list.\n+\tThe format supported for email list is the following:\n+\t\"Foo <foo@example.com>, bar@example.com\".\n+\tPlease notice that the email list does not handle commas in\n+\temail names such as \"Foo, Bar <foobar@example.com>\".\n \n --cc=<address>::\n+--cc=\"[<address>,...]\"::\n \tSpecify a starting \"Cc:\" value for each email.\n \tDefault is the value of 'sendemail.cc'.\n-+\n-The --cc option must be repeated for each user you want on the cc list.\n+\tThe format supported for email list is the following:\n+\t\"Foo <foo@example.com>, bar@example.com\".\n+\tPlease notice that the email list does not handle commas in\n+\temail names such as \"Foo, Bar <foobar@example.com>\".\n \n --compose::\n \tInvoke a text editor (see GIT_EDITOR in linkgit:git-var[1])\n@@ -111,12 +117,15 @@ is not set, this will be prompted for.\n \tis not set, this will be prompted for.\n \n --to=<address>::\n+--to=\"[<address>,...]\"::\n \tSpecify the primary recipient of the emails generated. Generally, this\n \twill be the upstream maintainer of the project involved. Default is the\n \tvalue of the 'sendemail.to' configuration value; if that is unspecified,\n \tand --to-cmd is not specified, this will be prompted for.\n-+\n-The --to option must be repeated for each user you want on the to list.\n+\tThe format supported for email list is the following:\n+\t\"Foo <foo@example.com>, bar@example.com\".\n+\tPlease notice that the email list does not handle commas in\n+\temail names such as \"Foo, Bar <foobar@example.com>\".\n \n --8bit-encoding=<encoding>::\n \tWhen encountering a non-ASCII message or subject that does not\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 671762b..03f3876 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -426,20 +426,6 @@ my ($repoauthor, $repocommitter);\n ($repoauthor) = Git::ident_person(@repo, 'author');\n ($repocommitter) = Git::ident_person(@repo, 'committer');\n \n-# Verify the user input\n-\n-foreach my $entry (@initial_to) {\n-\tdie \"Comma in --to entry: $entry'\\n\" unless $entry !~ m/,/;\n-}\n-\n-foreach my $entry (@initial_cc) {\n-\tdie \"Comma in --cc entry: $entry'\\n\" unless $entry !~ m/,/;\n-}\n-\n-foreach my $entry (@bcclist) {\n-\tdie \"Comma in --bcclist entry: $entry'\\n\" unless $entry !~ m/,/;\n-}\n-\n sub parse_address_line {\n \tif ($have_mail_address) {\n \t\treturn map { $_->format } Mail::Address->parse($_[0]);\n@@ -1079,6 +1065,25 @@ sub smtp_auth_maybe {\n \treturn $auth;\n }\n \n+sub split_emails {\n+    my ($emails) = @_;\n+    my @split_list;\n+    if ($emails =~ /,/) {\n+\t@split_list = split(/,/, $emails);\n+    } else {\n+\t@split_list = $emails;\n+    }\n+    # Removal of unwanted spaces\n+    for (my $j = 0; $j <= $#split_list; $j++) {\n+\t$split_list[$j] =~ s/^\\s+//;\n+\t$split_list[$j] =~ s/\\s+$//;\n+    }\n+    return @split_list;\n+}\n+\n+sub split_emails_list {\n+\treturn (map { split_emails($_) } @_);\n+}\n # Returns 1 if the message was sent, and 0 otherwise.\n # In actuality, the whole program dies when there\n # is an error sending a message.\n@@ -1089,6 +1094,9 @@ sub send_message {\n \t\t      not grep { $cc eq $_ || $_ =~ /<\\Q${cc}\\E>$/ } @recipients\n \t\t    }\n \t       @cc);\n+\t@cc = split_emails_list(@cc);\n+\t@bcclist = split_emails_list(@bcclist);\n+\t@recipients = split_emails_list(@recipients);\n \tmy $to = join (\",\\n\\t\", @recipients);\n \t@recipients = unique_email_list(@recipients,@cc,@bcclist);\n \t@recipients = (map { extract_valid_address_or_die($_) } @recipients);\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex 9f46f22..87641bc 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -1349,4 +1349,39 @@ test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' '\n \tgrep \"^!someone@example\\.org!$\" commandline1\n '\n \n-test_done\n+test_expect_success $PREREQ 'setup expected-list' '\n+\tgit send-email \\\n+\t\t--dry-run \\\n+\t\t--suppress-cc=sob \\\n+\t\t--from=\"Example <from@example.com>\" \\\n+\t\t--to=\"to1@example.com\" --to=\"to2@example.com\" \\\n+\t\t--to=\"to3@example.com\" --cc=\"cc0@example.com\" \\\n+\t\t--cc=\"Cc 1 <cc1@example.com>\" --cc=\"Cc 2 <cc2@example.com>\" \\\n+\t\t--bcc=\"bcc1@example.com\" --bcc=\"bcc2@example.com\" \\\n+\t\t-1 >output\n+\tsed\t-e \"s/^\\(\\/tmp\\/\\).*/\\1patch/\" \\\n+\t\t-e \"s/^\\(Date:\\).*/\\1 DATE-STRING/\" \\\n+\t\t-e \"s/^\\(Message-Id:\\).*/\\1 MESSAGE-ID-STRING/\" \\\n+\t\t-e \"s/^\\(X-Mailer:\\).*/\\1 X-MAILER-STRING/\" \\\n+\t\t<output >expected-list\n+'\n+\n+test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '\n+\tgit send-email \\\n+\t\t--dry-run \\\n+\t\t--suppress-cc=sob \\\n+\t\t--from=\"Example <from@example.com>\" \\\n+\t\t--to=\"to1@example.com, to2@example.com,to3@example.com\" \\\n+\t\t--cc=\"cc0@example.com\" \\\n+\t\t--cc=\"Cc 1 <cc1@example.com>, Cc 2 <cc2@example.com>\" \\\n+\t\t--bcc=\"bcc1@example.com, bcc2@example.com\" \\\n+\t\t-1 >output\n+\tsed\t-e \"s/^\\(\\/tmp\\/\\).*/\\1patch/\" \\\n+\t\t-e \"s/^\\(Date:\\).*/\\1 DATE-STRING/\" \\\n+\t\t-e \"s/^\\(Message-Id:\\).*/\\1 MESSAGE-ID-STRING/\" \\\n+\t\t-e \"s/^\\(X-Mailer:\\).*/\\1 X-MAILER-STRING/\" \\\n+\t\t<output >actual-list &&\n+\ttest_cmp expected-list actual-list\n+'\n+\n+test_done\n\\ No newline at end of file\n-- \n1.7.8\n"},{"id":"221377","messageId":"vpqwqpqjp3t.fsf@anie.imag.fr","threadId":"34220","inReplyTo":"1371641640-3897-1-git-send-email-Jorge-Juan.Garcia-Garcia@ensimag.imag.fr","subject":"Re: [PATCH v2] send-email: allow use of basic email list in --cc --to and --bcc","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2013-06-19T11:51:02Z","receivedAt":"2013-06-19T11:51:02Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Jorge-Juan.Garcia-Garcia@ensimag.imag.fr writes:\n\n> Changes since v1:\n> [...]\n>  - did not change the two regexp into one, because it's faster with two\n\n(I find it strange to describe non-change in a list of changes)\n\nI don't think speed is an argument here: it's a one-time operation and\nwill be instantaneous for the user in any case.\n\n> +sub split_emails {\n> +    my ($emails) = @_;\n> +    my @split_list;\n> +    if ($emails =~ /,/) {\n> +\t@split_list = split(/,/, $emails);\n> +    } else {\n> +\t@split_list = $emails;\n> +    }\n\nDo you need this \"if\"? Wouldn't split do the right thing if $emails does\nnot contain comma?\n\n> +    # Removal of unwanted spaces\n> +    for (my $j = 0; $j <= $#split_list; $j++) {\n\nSounds very un-perl-ish. Something like this maybe?\n\nforeach $email (@emails) {\n\t$email =~ s/^\\s+|\\s+$//;\n}\n\n> +    return @split_list;\n> +}\n\nThis is indented with tab/spaces mix. Please, use tabs only in Git's\nsource.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"}]}