{"thread":{"id":"39752","subject":"[PATCH v7 00/10] send-email address management","startedAt":"2015-06-30T12:16:41Z","lastAt":"2015-07-08T07:28:38Z","messageCount":21,"participants":["Matthieu Moy","Junio C Hamano","Remi Lespinet","Torsten Bögershausen"],"isPatch":true,"patchVersion":7,"patchTotal":10},"messages":[{"id":"265212","messageId":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":null,"subject":"[PATCH v7 00/10] send-email address management","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:41Z","receivedAt":"2015-06-30T12:16:41Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This is an almost unmodified resend of Remi's patch here:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/271844/focus=272499\n\nThe last patches had trouble reaching the list, hopefully this will be\neasier to apply. Two minor changes:\n\n* Removed the Helped-by: Remi trailer in a message sent by the same\n  Remi.\n\n* Allow -> allow in the subject line of a patch.\n\nNo code change.\n\nRemi Lespinet (10):\n  t9001-send-email: move script creation in a setup test\n  send-email: allow aliases in patch header and command script outputs\n  t9001-send-email: refactor header variable fields replacement\n  send-email: refactor address list process\n  send-email: allow use of aliases in the From field of --compose mode\n  send-email: minor code refactoring\n  send-email: reduce dependencies impact on parse_address_line\n  send-email: consider quote as delimiter instead of character\n  send-email: allow multiple emails using --cc, --to and --bcc\n  send-email: suppress meaningless whitespaces in from field\n\n Documentation/git-send-email.txt |  12 +--\n git-send-email.perl              |  50 ++++++-------\n perl/Git.pm                      |  67 +++++++++++++++++\n t/t9000-addresses.sh             |  30 ++++++++\n t/t9000/test.pl                  |  67 +++++++++++++++++\n t/t9001-send-email.sh            | 154 ++++++++++++++++++++++++++++++++++++---\n 6 files changed, 336 insertions(+), 44 deletions(-)\n create mode 100755 t/t9000-addresses.sh\n create mode 100755 t/t9000/test.pl\n\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265220","messageId":"1435666611-18429-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 01/10] t9001-send-email: move script creation in a setup test","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:42Z","receivedAt":"2015-06-30T12:16:42Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nMove the creation of the scripts used in to-cmd and cc-cmd tests\nin a setup test to make them available for later tests.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n t/t9001-send-email.sh | 15 +++++++++------\n 1 file changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex db2f45e..8caf7b0 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -312,13 +312,19 @@ test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email'\n \t)\n '\n \n+test_expect_success $PREREQ 'setup tocmd and cccmd scripts' '\n+\twrite_script tocmd-sed <<-\\EOF &&\n+\tsed -n -e \"s/^tocmd--//p\" \"$1\"\n+\tEOF\n+\twrite_script cccmd-sed <<-\\EOF\n+\tsed -n -e \"s/^cccmd--//p\" \"$1\"\n+\tEOF\n+'\n+\n test_expect_success $PREREQ 'tocmd works' '\n \tclean_fake_sendmail &&\n \tcp $patches tocmd.patch &&\n \techo tocmd--tocmd@example.com >>tocmd.patch &&\n-\twrite_script tocmd-sed <<-\\EOF &&\n-\tsed -n -e \"s/^tocmd--//p\" \"$1\"\n-\tEOF\n \tgit send-email \\\n \t\t--from=\"Example <nobody@example.com>\" \\\n \t\t--to-cmd=./tocmd-sed \\\n@@ -332,9 +338,6 @@ test_expect_success $PREREQ 'cccmd works' '\n \tclean_fake_sendmail &&\n \tcp $patches cccmd.patch &&\n \techo \"cccmd--  cccmd@example.com\" >>cccmd.patch &&\n-\twrite_script cccmd-sed <<-\\EOF &&\n-\tsed -n -e \"s/^cccmd--//p\" \"$1\"\n-\tEOF\n \tgit send-email \\\n \t\t--from=\"Example <nobody@example.com>\" \\\n \t\t--to=nobody@example.com \\\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265221","messageId":"1435666611-18429-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 02/10] send-email: allow aliases in patch header and command script outputs","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:43Z","receivedAt":"2015-06-30T12:16:43Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nInterpret aliases in:\n\n  -  Header fields of patches generated by git format-patch\n     (using --to, --cc, --add-header for example) or\n     manually modified. Example of fields in header:\n\n      To: alias1\n      Cc: alias2\n      Cc: alias3\n\n  -  Outputs of command scripts specified by --cc-cmd and\n     --to-cmd. Example of script:\n\n      #!/bin/sh\n      echo alias1\n      echo alias2\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl   |  2 ++\n t/t9001-send-email.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 62 insertions(+)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex ae9f869..3cbdb1a 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1566,7 +1566,9 @@ foreach my $t (@files) {\n \t\t($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));\n \t$needs_confirm = \"inform\" if ($needs_confirm && $confirm_unconfigured && @cc);\n \n+\t@to = expand_aliases(@to);\n \t@to = validate_address_list(sanitize_address_list(@to));\n+\t@cc = expand_aliases(@cc);\n \t@cc = validate_address_list(sanitize_address_list(@cc));\n \n \t@to = (@initial_to, @to);\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex 8caf7b0..1914439 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -1624,6 +1624,66 @@ test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \\\n test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\\EOF\n \tEOF\n \n+test_expect_success $PREREQ 'alias support in To header' '\n+\tclean_fake_sendmail &&\n+\techo \"alias sbd  someone@example.org\" >.mailrc &&\n+\ttest_config sendemail.aliasesfile \".mailrc\" &&\n+\ttest_config sendemail.aliasfiletype mailrc &&\n+\tgit format-patch --stdout -1 --to=sbd >aliased.patch &&\n+\tgit send-email \\\n+\t\t--from=\"Example <nobody@example.com>\" \\\n+\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\taliased.patch \\\n+\t\t2>errors >out &&\n+\tgrep \"^!someone@example\\.org!$\" commandline1\n+'\n+\n+test_expect_success $PREREQ 'alias support in Cc header' '\n+\tclean_fake_sendmail &&\n+\techo \"alias sbd  someone@example.org\" >.mailrc &&\n+\ttest_config sendemail.aliasesfile \".mailrc\" &&\n+\ttest_config sendemail.aliasfiletype mailrc &&\n+\tgit format-patch --stdout -1 --cc=sbd >aliased.patch &&\n+\tgit send-email \\\n+\t\t--from=\"Example <nobody@example.com>\" \\\n+\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\taliased.patch \\\n+\t\t2>errors >out &&\n+\tgrep \"^!someone@example\\.org!$\" commandline1\n+'\n+\n+test_expect_success $PREREQ 'tocmd works with aliases' '\n+\tclean_fake_sendmail &&\n+\techo \"alias sbd  someone@example.org\" >.mailrc &&\n+\ttest_config sendemail.aliasesfile \".mailrc\" &&\n+\ttest_config sendemail.aliasfiletype mailrc &&\n+\tgit format-patch --stdout -1 >tocmd.patch &&\n+\techo tocmd--sbd >>tocmd.patch &&\n+\tgit send-email \\\n+\t\t--from=\"Example <nobody@example.com>\" \\\n+\t\t--to-cmd=./tocmd-sed \\\n+\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\ttocmd.patch \\\n+\t\t2>errors >out &&\n+\tgrep \"^!someone@example\\.org!$\" commandline1\n+'\n+\n+test_expect_success $PREREQ 'cccmd works with aliases' '\n+\tclean_fake_sendmail &&\n+\techo \"alias sbd  someone@example.org\" >.mailrc &&\n+\ttest_config sendemail.aliasesfile \".mailrc\" &&\n+\ttest_config sendemail.aliasfiletype mailrc &&\n+\tgit format-patch --stdout -1 >cccmd.patch &&\n+\techo cccmd--sbd >>cccmd.patch &&\n+\tgit send-email \\\n+\t\t--from=\"Example <nobody@example.com>\" \\\n+\t\t--cc-cmd=./cccmd-sed \\\n+\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\tcccmd.patch \\\n+\t\t2>errors >out &&\n+\tgrep \"^!someone@example\\.org!$\" commandline1\n+'\n+\n do_xmailer_test () {\n \texpected=$1 params=$2 &&\n \tgit format-patch -1 &&\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265214","messageId":"1435666611-18429-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 03/10] t9001-send-email: refactor header variable fields replacement","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:44Z","receivedAt":"2015-06-30T12:16:44Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nCreate a function which replaces Date, Message-Id and\nX-Mailer lines generated by git-send-email by a specific string:\n\nDate:.*$       -> Date: DATE-STRING\nMessage-Id:.*$ -> Message-Id: MESSAGE-ID-STRING\nX-Mailer:.*$   -> X-Mailer: X-MAILER-STRING\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n t/t9001-send-email.sh | 11 +++++++----\n 1 file changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex 1914439..fce081c 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -522,6 +522,12 @@ Result: OK\n EOF\n \"\n \n+replace_variable_fields () {\n+\tsed\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+}\n+\n test_suppression () {\n \tgit send-email \\\n \t\t--dry-run \\\n@@ -529,10 +535,7 @@ test_suppression () {\n \t\t--from=\"Example <from@example.com>\" \\\n \t\t--to=to@example.com \\\n \t\t--smtp-server relay.example.com \\\n-\t\t$patches |\n-\tsed\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$patches | replace_variable_fields \\\n \t\t>actual-suppress-$1${2+\"-$2\"} &&\n \ttest_cmp expected-suppress-$1${2+\"-$2\"} actual-suppress-$1${2+\"-$2\"}\n }\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265219","messageId":"1435666611-18429-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 04/10] send-email: refactor address list process","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:45Z","receivedAt":"2015-06-30T12:16:45Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nSimplify code by creating a function which transform a list of strings\ncontaining email addresses (separated by commas, comporting aliases)\ninto a clean list of valid email addresses.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl | 22 ++++++++++++----------\n 1 file changed, 12 insertions(+), 10 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 3cbdb1a..994697e 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -839,12 +839,9 @@ sub expand_one_alias {\n \treturn $aliases{$alias} ? expand_aliases(@{$aliases{$alias}}) : $alias;\n }\n \n-@initial_to = expand_aliases(@initial_to);\n-@initial_to = validate_address_list(sanitize_address_list(@initial_to));\n-@initial_cc = expand_aliases(@initial_cc);\n-@initial_cc = validate_address_list(sanitize_address_list(@initial_cc));\n-@bcclist = expand_aliases(@bcclist);\n-@bcclist = validate_address_list(sanitize_address_list(@bcclist));\n+@initial_to = process_address_list(@initial_to);\n+@initial_cc = process_address_list(@initial_cc);\n+@bcclist = process_address_list(@bcclist);\n \n if ($thread && !defined $initial_reply_to && $prompting) {\n \t$initial_reply_to = ask(\n@@ -1057,6 +1054,13 @@ sub sanitize_address_list {\n \treturn (map { sanitize_address($_) } @_);\n }\n \n+sub process_address_list {\n+\tmy @addr_list = expand_aliases(@_);\n+\t@addr_list = sanitize_address_list(@addr_list);\n+\t@addr_list = validate_address_list(@addr_list);\n+\treturn @addr_list;\n+}\n+\n # Returns the local Fully Qualified Domain Name (FQDN) if available.\n #\n # Tightly configured MTAa require that a caller sends a real DNS\n@@ -1566,10 +1570,8 @@ foreach my $t (@files) {\n \t\t($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));\n \t$needs_confirm = \"inform\" if ($needs_confirm && $confirm_unconfigured && @cc);\n \n-\t@to = expand_aliases(@to);\n-\t@to = validate_address_list(sanitize_address_list(@to));\n-\t@cc = expand_aliases(@cc);\n-\t@cc = validate_address_list(sanitize_address_list(@cc));\n+\t@to = process_address_list(@to);\n+\t@cc = process_address_list(@cc);\n \n \t@to = (@initial_to, @to);\n \t@cc = (@initial_cc, @cc);\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265213","messageId":"1435666611-18429-6-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 05/10] send-email: allow use of aliases in the From field of --compose mode","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:46Z","receivedAt":"2015-06-30T12:16:46Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nAliases were expanded before considering the From field of the\n--compose option. This is inconsistent with other fields\n(To, Cc, ...) which already support aliases.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 994697e..da1d4a4 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -561,8 +561,6 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {\n \t}\n }\n \n-($sender) = expand_aliases($sender) if defined $sender;\n-\n # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if\n # $f is a revision list specification to be passed to format-patch.\n sub is_format_patch_arg {\n@@ -807,6 +805,8 @@ if (!$force) {\n \t}\n }\n \n+($sender) = expand_aliases($sender) if defined $sender;\n+\n if (!defined $sender) {\n \t$sender = $repoauthor || $repocommitter || '';\n }\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265215","messageId":"1435666611-18429-7-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 06/10] send-email: minor code refactoring","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:47Z","receivedAt":"2015-06-30T12:16:47Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nGroup expressions in a single if statement. This avoid checking\nmultiple time if the variable $sender is defined.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex da1d4a4..49fc275 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -805,9 +805,9 @@ if (!$force) {\n \t}\n }\n \n-($sender) = expand_aliases($sender) if defined $sender;\n-\n-if (!defined $sender) {\n+if (defined $sender) {\n+\t($sender) = expand_aliases($sender);\n+} else {\n \t$sender = $repoauthor || $repocommitter || '';\n }\n \n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265222","messageId":"1435666611-18429-8-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:48Z","receivedAt":"2015-06-30T12:16:48Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nparse_address_line had not the same behavior whether the user had\nMail::Address or not. Teach parse_address_line to behave like\nMail::Address.\n\nWhen the user input is correct, this implementation behaves\nexactly like Mail::Address except when there are quotes\ninside the name:\n\n  \"Jane Do\"e <jdoe@example.com>\n\nIn this case the result of parse_address_line is:\n\n  With M::A : \"Jane Do\" e <jdoe@example.com>\n  Without   : \"Jane Do e\" <jdoe@example.com>\n\nWhen the user input is not correct, the behavior is also mostly\nthe same.\n\nUnlike Mail::Address, this doesn't parse groups and recursive\ncommentaries.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl  |  2 +-\n perl/Git.pm          | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n t/t9000-addresses.sh | 30 +++++++++++++++++++++++\n t/t9000/test.pl      | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 165 insertions(+), 1 deletion(-)\n create mode 100755 t/t9000-addresses.sh\n create mode 100755 t/t9000/test.pl\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 49fc275..4268ed9 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -478,7 +478,7 @@ sub parse_address_line {\n \tif ($have_mail_address) {\n \t\treturn map { $_->format } Mail::Address->parse($_[0]);\n \t} else {\n-\t\treturn split_addrs($_[0]);\n+\t\treturn Git::parse_mailboxes($_[0]);\n \t}\n }\n \ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 9026a7b..19ef081 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -864,6 +864,73 @@ sub ident_person {\n \treturn \"$ident[0] <$ident[1]>\";\n }\n \n+=item parse_mailboxes\n+\n+Return an array of mailboxes extracted from a string.\n+\n+=cut\n+\n+sub parse_mailboxes {\n+\tmy $re_comment = qr/\\((?:[^)]*)\\)/;\n+\tmy $re_quote = qr/\"(?:[^\\\"\\\\]|\\\\.)*\"/;\n+\tmy $re_word = qr/(?:[^][\"\\s()<>:;@\\\\,.]|\\\\.)+/;\n+\n+\t# divide the string in tokens of the above form\n+\tmy $re_token = qr/(?:$re_quote|$re_word|$re_comment|\\S)/;\n+\tmy @tokens = map { $_ =~ /\\s*($re_token)\\s*/g } @_;\n+\n+\t# add a delimiter to simplify treatment for the last mailbox\n+\tpush @tokens, \",\";\n+\n+\tmy (@addr_list, @phrase, @address, @comment, @buffer) = ();\n+\tforeach my $token (@tokens) {\n+\t\tif ($token =~ /^[,;]$/) {\n+\t\t\t# if buffer still contains undeterminated strings\n+\t\t\t# append it at the end of @address or @phrase\n+\t\t\tif (@address) {\n+\t\t\t\tpush @address, @buffer;\n+\t\t\t} else {\n+\t\t\t\tpush @phrase, @buffer;\n+\t\t\t}\n+\n+\t\t\tmy $str_phrase = join ' ', @phrase;\n+\t\t\tmy $str_address = join '', @address;\n+\t\t\tmy $str_comment = join ' ', @comment;\n+\n+\t\t\t# quote are necessary if phrase contains\n+\t\t\t# special characters\n+\t\t\tif ($str_phrase =~ /[][()<>:;@\\\\,.\\000-\\037\\177]/) {\n+\t\t\t\t$str_phrase =~ s/(^|[^\\\\])\"/$1/g;\n+\t\t\t\t$str_phrase = qq[\"$str_phrase\"];\n+\t\t\t}\n+\n+\t\t\t# add \"<>\" around the address if necessary\n+\t\t\tif ($str_address ne \"\" && $str_phrase ne \"\") {\n+\t\t\t\t$str_address = qq[<$str_address>];\n+\t\t\t}\n+\n+\t\t\tmy $str_mailbox = \"$str_phrase $str_address $str_comment\";\n+\t\t\t$str_mailbox =~ s/^\\s*|\\s*$//g;\n+\t\t\tpush @addr_list, $str_mailbox if ($str_mailbox);\n+\n+\t\t\t@phrase = @address = @comment = @buffer = ();\n+\t\t} elsif ($token =~ /^\\(/) {\n+\t\t\tpush @comment, $token;\n+\t\t} elsif ($token eq \"<\") {\n+\t\t\tpush @phrase, (splice @address), (splice @buffer);\n+\t\t} elsif ($token eq \">\") {\n+\t\t\tpush @address, (splice @buffer);\n+\t\t} elsif ($token eq \"@\") {\n+\t\t\tpush @address, (splice @buffer), \"@\";\n+\t\t} elsif ($token eq \".\") {\n+\t\t\tpush @address, (splice @buffer), \".\";\n+\t\t} else {\n+\t\t\tpush @buffer, $token;\n+\t\t}\n+\t}\n+\n+\treturn @addr_list;\n+}\n \n =item hash_object ( TYPE, FILENAME )\n \ndiff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh\nnew file mode 100755\nindex 0000000..7223d03\n--- /dev/null\n+++ b/t/t9000-addresses.sh\n@@ -0,0 +1,30 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2015\n+#\n+\n+test_description='compare address parsing with and without Mail::Address'\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL; then\n+\tskip_all='skipping perl interface tests, perl not available'\n+\ttest_done\n+fi\n+\n+perl -MTest::More -e 0 2>/dev/null || {\n+\tskip_all=\"Perl Test::More unavailable, skipping test\"\n+\ttest_done\n+}\n+\n+perl -MMail::Address -e 0 2>/dev/null || {\n+\tskip_all=\"Perl Mail::Address unavailable, skipping test\"\n+\ttest_done\n+}\n+\n+test_external_has_tap=1\n+\n+test_external_without_stderr \\\n+\t'Perl address parsing function' \\\n+\tperl \"$TEST_DIRECTORY\"/t9000/test.pl\n+\n+test_done\ndiff --git a/t/t9000/test.pl b/t/t9000/test.pl\nnew file mode 100755\nindex 0000000..8e2b760\n--- /dev/null\n+++ b/t/t9000/test.pl\n@@ -0,0 +1,67 @@\n+#!/usr/bin/perl\n+use lib (split(/:/, $ENV{GITPERLLIB}));\n+\n+use 5.008;\n+use warnings;\n+use strict;\n+\n+use Test::More qw(no_plan);\n+use Mail::Address;\n+\n+BEGIN { use_ok('Git') }\n+\n+my @success_list = (q[Jane],\n+\tq[jdoe@example.com],\n+\tq[<jdoe@example.com>],\n+\tq[Jane <jdoe@example.com>],\n+\tq[Jane Doe <jdoe@example.com>],\n+\tq[\"Jane\" <jdoe@example.com>],\n+\tq[\"Doe, Jane\" <jdoe@example.com>],\n+\tq[\"Jane@:;\\>.,()<Doe\" <jdoe@example.com>],\n+\tq[Jane!#$%&'*+-/=?^_{|}~Doe' <jdoe@example.com>],\n+\tq[\"<jdoe@example.com>\"],\n+\tq[\"Jane jdoe@example.com\"],\n+\tq[Jane Doe <jdoe    @   example.com  >],\n+\tq[Jane       Doe <  jdoe@example.com  >],\n+\tq[Jane @ Doe @ Jane @ Doe],\n+\tq[\"Jane, 'Doe'\" <jdoe@example.com>],\n+\tq['Doe, \"Jane' <jdoe@example.com>],\n+\tq[\"Jane\" \"Do\"e <jdoe@example.com>],\n+\tq[\"Jane' Doe\" <jdoe@example.com>],\n+\tq[\"Jane Doe <jdoe@example.com>\" <jdoe@example.com>],\n+\tq[\"Jane\\\" Doe\" <jdoe@example.com>],\n+\tq[Doe, jane <jdoe@example.com>],\n+\tq[\"Jane Doe <jdoe@example.com>],\n+\tq['Jane 'Doe' <jdoe@example.com>]);\n+\n+my @known_failure_list = (q[Jane\\ Doe <jdoe@example.com>],\n+\tq[\"Doe, Ja\"ne <jdoe@example.com>],\n+\tq[\"Doe, Katarina\" Jane <jdoe@example.com>],\n+\tq[Jane@:;\\.,()<>Doe <jdoe@example.com>],\n+\tq[Jane jdoe@example.com],\n+\tq[<jdoe@example.com> Jane Doe],\n+\tq[Jane <jdoe@example.com> Doe],\n+\tq[\"Jane \"Kat\"a\" ri\"na\" \",Doe\" <jdoe@example.com>],\n+\tq[Jane Doe],\n+\tq[Jane \"Doe <jdoe@example.com>\"],\n+\tq[\\\"Jane Doe <jdoe@example.com>],\n+\tq[Jane\\\"\\\" Doe <jdoe@example.com>],\n+\tq['Jane \"Katarina\\\" \\' Doe' <jdoe@example.com>]);\n+\n+foreach my $str (@success_list) {\n+\tmy @expected = map { $_->format } Mail::Address->parse(\"$str\");\n+\tmy @actual = Git::parse_mailboxes(\"$str\");\n+\tis_deeply(\\@expected, \\@actual, qq[same output : $str]);\n+}\n+\n+TODO: {\n+\tlocal $TODO = \"known breakage\";\n+\tforeach my $str (@known_failure_list) {\n+\t\tmy @expected = map { $_->format } Mail::Address->parse(\"$str\");\n+\t\tmy @actual = Git::parse_mailboxes(\"$str\");\n+\t\tis_deeply(\\@expected, \\@actual, qq[same output : $str]);\n+\t}\n+}\n+\n+my $is_passing = Test::More->builder->is_passing;\n+exit($is_passing ? 0 : 1);\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265218","messageId":"1435666611-18429-9-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 08/10] send-email: consider quote as delimiter instead of character","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:49Z","receivedAt":"2015-06-30T12:16:49Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nDo not consider quote inside a recipient name as character when\nthey are not escaped. This interprets:\n\n  \"Jane\" \"Doe\" <jdoe@example.com>\n\nas:\n\n  \"Jane Doe\" <jdoe@example.com>\n\ninstead of:\n\n  \"Jane\\\" \\\"Doe\" <jdoe@example.com>\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 4268ed9..df9d3f6 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -1034,15 +1034,17 @@ sub sanitize_address {\n \t\treturn $recipient;\n \t}\n \n+\t# remove non-escaped quotes\n+\t$recipient_name =~ s/(^|[^\\\\])\"/$1/g;\n+\n \t# rfc2047 is needed if a non-ascii char is included\n \tif ($recipient_name =~ /[^[:ascii:]]/) {\n-\t\t$recipient_name =~ s/^\"(.*)\"$/$1/;\n \t\t$recipient_name = quote_rfc2047($recipient_name);\n \t}\n \n \t# double quotes are needed if specials or CTLs are included\n \telsif ($recipient_name =~ /[][()<>@,;:\\\\\".\\000-\\037\\177]/) {\n-\t\t$recipient_name =~ s/([\"\\\\\\r])/\\\\$1/g;\n+\t\t$recipient_name =~ s/([\\\\\\r])/\\\\$1/g;\n \t\t$recipient_name = qq[\"$recipient_name\"];\n \t}\n \n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265217","messageId":"1435666611-18429-10-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 09/10] send-email: allow multiple emails using --cc, --to and --bcc","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:50Z","receivedAt":"2015-06-30T12:16:50Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nAccept a list of emails separated by commas in flags --cc, --to and\n--bcc.  Multiple addresses can already be given by using these options\nmultiple times, but it is more convenient to allow cutting-and-pasting\na list of addresses from the header of an existing e-mail message,\nwhich already lists them as comma-separated list, as a value to a\nsingle parameter.\n\nThe following format can now be used:\n\n    $ git send-email --to='Jane <jdoe@example.com>, mike@example.com'\n\nRemove the limitation imposed by 79ee555b (Check and document the\noptions to prevent mistakes, 2006-06-21) which rejected every argument\nwith comma in --cc, --to and --bcc.\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>\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-send-email.txt | 12 +++++------\n git-send-email.perl              | 17 ++--------------\n t/t9001-send-email.sh            | 44 ++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 52 insertions(+), 21 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 7ae467b..f14705e 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -49,17 +49,17 @@ Composing\n \tof 'sendemail.annotate'. See the CONFIGURATION section for\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+This option may be specified multiple times.\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+This option may be specified multiple times.\n \n --compose::\n \tInvoke a text editor (see GIT_EDITOR in linkgit:git-var[1])\n@@ -110,13 +110,13 @@ is not set, this will be prompted for.\n \tOnly necessary if --compose is also set.  If --compose\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+This option may be specified multiple times.\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 df9d3f6..4a681f5 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -460,20 +460,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@@ -1057,7 +1043,8 @@ sub sanitize_address_list {\n }\n \n sub process_address_list {\n-\tmy @addr_list = expand_aliases(@_);\n+\tmy @addr_list = map { parse_address_line($_) } @_;\n+\t@addr_list = expand_aliases(@addr_list);\n \t@addr_list = sanitize_address_list(@addr_list);\n \t@addr_list = validate_address_list(@addr_list);\n \treturn @addr_list;\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex fce081c..733431b 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -1720,4 +1720,48 @@ test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '\n \tdo_xmailer_test 1 \"--xmailer\"\n '\n \n+test_expect_success $PREREQ 'setup expected-list' '\n+\tgit send-email \\\n+\t--dry-run \\\n+\t--from=\"Example <from@example.com>\" \\\n+\t--to=\"To 1 <to1@example.com>\" \\\n+\t--to=\"to2@example.com\" \\\n+\t--to=\"to3@example.com\" \\\n+\t--cc=\"Cc 1 <cc1@example.com>\" \\\n+\t--cc=\"Cc2 <cc2@example.com>\" \\\n+\t--bcc=\"bcc1@example.com\" \\\n+\t--bcc=\"bcc2@example.com\" \\\n+\t0001-add-master.patch | replace_variable_fields \\\n+\t>expected-list\n+'\n+\n+test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '\n+\tgit send-email \\\n+\t--dry-run \\\n+\t--from=\"Example <from@example.com>\" \\\n+\t--to=\"To 1 <to1@example.com>, to2@example.com\" \\\n+\t--to=\"to3@example.com\" \\\n+\t--cc=\"Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>\" \\\n+\t--bcc=\"bcc1@example.com, bcc2@example.com\" \\\n+\t0001-add-master.patch | replace_variable_fields \\\n+\t>actual-list &&\n+\ttest_cmp expected-list actual-list\n+'\n+\n+test_expect_success $PREREQ 'aliases work with email list' '\n+\techo \"alias to2 to2@example.com\" >.mutt &&\n+\techo \"alias cc1 Cc 1 <cc1@example.com>\" >>.mutt &&\n+\ttest_config sendemail.aliasesfile \".mutt\" &&\n+\ttest_config sendemail.aliasfiletype mutt &&\n+\tgit send-email \\\n+\t--dry-run \\\n+\t--from=\"Example <from@example.com>\" \\\n+\t--to=\"To 1 <to1@example.com>, to2, to3@example.com\" \\\n+\t--cc=\"cc1, Cc2 <cc2@example.com>\" \\\n+\t--bcc=\"bcc1@example.com, bcc2@example.com\" \\\n+\t0001-add-master.patch | replace_variable_fields \\\n+\t>actual-list &&\n+\ttest_cmp expected-list actual-list\n+'\n+\n test_done\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265216","messageId":"1435666611-18429-11-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"1435666611-18429-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 10/10] send-email: suppress meaningless whitespaces in from field","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-30T12:16:51Z","receivedAt":"2015-06-30T12:16:51Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nRemove leading and trailing whitespaces in from field before\ninterepreting it to improve consistency with other options.  The\nsplit_addrs function already take care of trailing and leading\nwhitespaces for to, cc and bcc fields.\nThe from option now:\n\n - has the same behavior when passing arguments like\n   \"  jdoe@example.com \", \"\\t jdoe@example.com \" or\n   \"jdoe@example.com\".\n\n - interprets aliases in string containing leading and trailing\n   whitespaces such as \" alias\" or \"alias\\t\" like other options.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n git-send-email.perl   |  1 +\n t/t9001-send-email.sh | 24 ++++++++++++++++++++++++\n 2 files changed, 25 insertions(+)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 4a681f5..b660cc2 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -792,6 +792,7 @@ if (!$force) {\n }\n \n if (defined $sender) {\n+\t$sender =~ s/^\\s+|\\s+$//g;\n \t($sender) = expand_aliases($sender);\n } else {\n \t$sender = $repoauthor || $repocommitter || '';\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex 733431b..5b4a5ce 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -1764,4 +1764,28 @@ test_expect_success $PREREQ 'aliases work with email list' '\n \ttest_cmp expected-list actual-list\n '\n \n+test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '\n+\techo \"alias to2 to2@example.com\" >.mutt &&\n+\techo \"alias cc1 Cc 1 <cc1@example.com>\" >>.mutt &&\n+\ttest_config sendemail.aliasesfile \".mutt\" &&\n+\ttest_config sendemail.aliasfiletype mutt &&\n+\tTO1=$(echo \"QTo 1 <to1@example.com>\" | q_to_tab) &&\n+\tTO2=$(echo \"QZto2\" | qz_to_tab_space) &&\n+\tCC1=$(echo \"cc1\" | append_cr) &&\n+\tBCC1=$(echo \"Q bcc1@example.com Q\" | q_to_nul) &&\n+\tgit send-email \\\n+\t--dry-run \\\n+\t--from=\"\tExample <from@example.com>\" \\\n+\t--to=\"$TO1\" \\\n+\t--to=\"$TO2\" \\\n+\t--to=\"  to3@example.com   \" \\\n+\t--cc=\"$CC1\" \\\n+\t--cc=\"Cc2 <cc2@example.com>\" \\\n+\t--bcc=\"$BCC1\" \\\n+\t--bcc=\"bcc2@example.com\" \\\n+\t0001-add-master.patch | replace_variable_fields \\\n+\t>actual-list &&\n+\ttest_cmp expected-list actual-list\n+'\n+\n test_done\n-- \n2.5.0.rc0.10.g7792c2a\n"},{"id":"265264","messageId":"xmqqfv59ca4b.fsf@gitster.dls.corp.google.com","threadId":"39752","inReplyTo":"1435666611-18429-8-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-30T18:41:08Z","receivedAt":"2015-06-30T18:41:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> diff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh\n> new file mode 100755\n> index 0000000..7223d03\n> --- /dev/null\n> +++ b/t/t9000-addresses.sh\n> @@ -0,0 +1,30 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2015\n\nThat does not look like a valid copyright notice.\n\nIn the modern age, I'd personally perfer not to add one (I would not\nhave a strong objection to others asserting their copyright), but if\nyou want to add one, you would need the name of the copyright holder\nafter the year (I presume that it would be your school name?).\n\nIIRC, (c) in place of circle-C does no carry legal weight, but\nhaving the word \"Copyright\" spelled out there is sufficient.\n\nThanks for tying the loose ends (not just this topic, but the other\nones, too).  Very much appreciated.\n"},{"id":"265270","messageId":"vpqoajx2dka.fsf@anie.imag.fr","threadId":"39752","inReplyTo":"xmqqfv59ca4b.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-30T19:36:53Z","receivedAt":"2015-06-30T19:36:53Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>\n>> diff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh\n>> new file mode 100755\n>> index 0000000..7223d03\n>> --- /dev/null\n>> +++ b/t/t9000-addresses.sh\n>> @@ -0,0 +1,30 @@\n>> +#!/bin/sh\n>> +#\n>> +# Copyright (c) 2015\n>\n> That does not look like a valid copyright notice.\n>\n> In the modern age, I'd personally perfer not to add one\n\nI'd vote for keeping it simple and not having the copyright notice. Most\nt/*.sh do not have one. The Git history + mailing-list archives are much\nbetter than in-code comments to keep track of who wrote what.\n\nRemi: any objection on removing it?\n\nJunio: do you want me to resend?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"265271","messageId":"xmqq7fqlc78w.fsf@gitster.dls.corp.google.com","threadId":"39752","inReplyTo":"vpqoajx2dka.fsf@anie.imag.fr","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-30T19:43:11Z","receivedAt":"2015-06-30T19:43:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>>\n>>> diff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh\n>>> new file mode 100755\n>>> index 0000000..7223d03\n>>> --- /dev/null\n>>> +++ b/t/t9000-addresses.sh\n>>> @@ -0,0 +1,30 @@\n>>> +#!/bin/sh\n>>> +#\n>>> +# Copyright (c) 2015\n>>\n>> That does not look like a valid copyright notice.\n>>\n>> In the modern age, I'd personally perfer not to add one\n>\n> I'd vote for keeping it simple and not having the copyright notice. Most\n> t/*.sh do not have one. The Git history + mailing-list archives are much\n> better than in-code comments to keep track of who wrote what.\n>\n> Remi: any objection on removing it?\n>\n> Junio: do you want me to resend?\n\nIt would be simpler to amend in-place either way.  Just let me know\nif we want to drop it or add a name (and if the latter, what name).\n\nThanks.\n"},{"id":"265303","messageId":"950442683.78443.1435737112063.JavaMail.zimbra@ensimag.grenoble-inp.fr","threadId":"39752","inReplyTo":"vpqoajx2dka.fsf@anie.imag.fr","subject":"[PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Remi Lespinet","fromEmail":"remi.lespinet@ensimag.grenoble-inp.fr","sentAt":"2015-07-01T07:51:52Z","receivedAt":"2015-07-01T07:51:52Z","isPatch":true,"sender":{"key":"remi.lespinet@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/11941160?v=4"},"body":"> I'd vote for keeping it simple and not having the copyright notice. Most\n> t/*.sh do not have one. The Git history + mailing-list archives are much\n> better than in-code comments to keep track of who wrote what.\n\n> Remi: any objection on removing it?\n\nSorry for not having resent the patches myself, I currently have no\nInternet access, neither at work nor at home... Here's a try on my\nphone:\nI though the copyright line was necessary, but I did not know what\nto write after, and I forgot to ask, so I'm really happy with simply\nremoving it. :)\n\nThanks!\n"},{"id":"265310","messageId":"vpqy4j0xooo.fsf@anie.imag.fr","threadId":"39752","inReplyTo":"950442683.78443.1435737112063.JavaMail.zimbra@ensimag.grenoble-inp.fr","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-07-01T08:33:11Z","receivedAt":"2015-07-01T08:33:11Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr> writes:\n\n>> I'd vote for keeping it simple and not having the copyright notice. Most\n>> t/*.sh do not have one. The Git history + mailing-list archives are much\n>> better than in-code comments to keep track of who wrote what.\n>\n>> Remi: any objection on removing it?\n>\n> Sorry for not having resent the patches myself, I currently have no\n> Internet access, neither at work nor at home... Here's a try on my\n> phone:\n> I though the copyright line was necessary, but I did not know what\n> to write after, and I forgot to ask, so I'm really happy with simply\n> removing it. :)\n\nOK, so Junio, you can just remove it.\n\nThanks,\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"265661","messageId":"559B9DEB.9030409@web.de","threadId":"39752","inReplyTo":"1435666611-18429-8-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-07-07T09:37:47Z","receivedAt":"2015-07-07T09:37:47Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"#!/usr/bin/perl\n\nShould we have hard-coded PATH to perl here ?\n\n/usr/bin/perl --version\nThis is perl, v5.10.0 built for darwin-thread-multi-2level\n(with 2 registered patches, see perl -V for more detail)\n\n> +\n> +my $is_passing = Test::More->builder->is_passing;\n> +exit($is_passing ? 0 : 1);\n> \n\nThis seems to give problems:\ndebug=t verbose=t ./t9000-addresses.sh\n\nInitialized empty Git repository in /Users/me/projects/git/git.pu/t/trash directory.t9000-addresses/.git/\n# run 0: Perl address parsing function (perl /Users/me/projects/git/git.pu/t/t9000/test.pl)\nok 1 - use Git;\nok 2 - same output : Jane\nok 3 - same output : jdoe@example.com\nok 4 - same output : <jdoe@example.com>\nok 5 - same output : Jane <jdoe@example.com>\nok 6 - same output : Jane Doe <jdoe@example.com>\nok 7 - same output : \"Jane\" <jdoe@example.com>\nok 8 - same output : \"Doe, Jane\" <jdoe@example.com>\nok 9 - same output : \"Jane@:;\\>.,()<Doe\" <jdoe@example.com>\nok 10 - same output : Jane!\\#$%&'*+-/=?^_{|}~Doe' <jdoe@example.com>\nok 11 - same output : \"<jdoe@example.com>\"\nok 12 - same output : \"Jane jdoe@example.com\"\nok 13 - same output : Jane Doe <jdoe    @   example.com  >\nok 14 - same output : Jane       Doe <  jdoe@example.com  >\nok 15 - same output : Jane @ Doe @ Jane @ Doe\nok 16 - same output : \"Jane, 'Doe'\" <jdoe@example.com>\nok 17 - same output : 'Doe, \"Jane' <jdoe@example.com>\nok 18 - same output : \"Jane\" \"Do\"e <jdoe@example.com>\nok 19 - same output : \"Jane' Doe\" <jdoe@example.com>\nok 20 - same output : \"Jane Doe <jdoe@example.com>\" <jdoe@example.com>\nok 21 - same output : \"Jane\\\" Doe\" <jdoe@example.com>\nok 22 - same output : Doe, jane <jdoe@example.com>\nok 23 - same output : \"Jane Doe <jdoe@example.com>\nok 24 - same output : 'Jane 'Doe' <jdoe@example.com>\nnot ok 25 - same output : Jane\\ Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane\\ Doe <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Jane \\ Doe\" <jdoe@example.com>'\n#     $expected->[0] = '\"Jane\\ Doe\" <jdoe@example.com>'\nnot ok 26 - same output : \"Doe, Ja\"ne <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \"Doe, Ja\"ne <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Doe, Ja\" ne <jdoe@example.com>'\n#     $expected->[0] = '\"Doe, Ja ne\" <jdoe@example.com>'\nnot ok 27 - same output : \"Doe, Katarina\" Jane <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \"Doe, Katarina\" Jane <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Doe, Katarina\" Jane <jdoe@example.com>'\n#     $expected->[0] = '\"Doe, Katarina Jane\" <jdoe@example.com>'\nnot ok 28 - same output : Jane@:;\\.,()<>Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane@:;\\.,()<>Doe <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[1] = '\\.'\n#     $expected->[1] = '\"\\.\"'\nnot ok 29 - same output : Jane jdoe@example.com # TODO known breakage\n#   Failed (TODO) test 'same output : Jane jdoe@example.com'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = 'Janejdoe@example.com'\nnot ok 30 - same output : <jdoe@example.com> Jane Doe # TODO known breakage\n#   Failed (TODO) test 'same output : <jdoe@example.com> Jane Doe'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane Doe <jdoe@example.com>'\n#     $expected->[0] = 'jdoe@example.comJaneDoe'\nnot ok 31 - same output : Jane <jdoe@example.com> Doe # TODO known breakage\n#   Failed (TODO) test 'same output : Jane <jdoe@example.com> Doe'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane Doe <jdoe@example.com>'\n#     $expected->[0] = 'Jane <jdoe@example.comDoe>'\nnot ok 32 - same output : \"Jane \"Kat\"a\" ri\"na\" \",Doe\" <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \"Jane \"Kat\"a\" ri\"na\" \",Doe\" <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Jane \" Kat \"a\" ri \"na\" \",Doe\" <jdoe@example.com>'\n#     $expected->[0] = '\"Jane  Kat a ri na ,Doe\" <jdoe@example.com>'\nnot ok 33 - same output : Jane Doe # TODO known breakage\n#   Failed (TODO) test 'same output : Jane Doe'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = 'Jane Doe'\nnot ok 34 - same output : Jane \"Doe <jdoe@example.com>\" # TODO known breakage\n#   Failed (TODO) test 'same output : Jane \"Doe <jdoe@example.com>\"'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = '\"Jane Doe <jdoe@example.com>\"'\nnot ok 35 - same output : \\\"Jane Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \\\"Jane Doe <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\\ \" Jane Doe <jdoe@example.com>'\n#     $expected->[0] = '\"\\\"Jane Doe\" <jdoe@example.com>'\nnot ok 36 - same output : Jane\\\"\\\" Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane\\\"\\\" Doe <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane \\ \" \\ \" Doe <jdoe@example.com>'\n#     $expected->[0] = '\"Jane\\\"\\\" Doe\" <jdoe@example.com>'\nnot ok 37 - same output : 'Jane \"Katarina\\\" \\' Doe' <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : 'Jane \"Katarina\\\" \\' Doe' <jdoe@example.com>'\n#   at /Users/me/projects/git/git.pu/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = ''Jane \" Katarina \\ \" \\ ' Doe' <jdoe@example.com>'\n#     $expected->[0] = '\"'Jane  Katarina\\\" \\' Doe'\" <jdoe@example.com>'\n1..37\n# test_external test Perl address parsing function failed: perl /Users/me/projects/git/git.pu/t/t9000/test.pl\n# expecting no stderr from previous command\n# test_external_without_stderr test no stderr: Perl address parsing function failed: perl /Users/me/projects/git/git.pu/t/t9000/test.pl: \n# Stderr is:\nCan't locate object method \"is_passing\" via package \"Test::Builder\" at /Users/me/projects/git/git.pu/t/t9000/test.pl line 66.\n# Looks like your test died just after 37.\n"},{"id":"265667","messageId":"vpq8uasqeru.fsf@anie.imag.fr","threadId":"39752","inReplyTo":"559B9DEB.9030409@web.de","subject":"Re: [PATCH v7 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-07-07T13:27:17Z","receivedAt":"2015-07-07T13:27:17Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Torsten Bögershausen <tboegi@web.de> writes:\n\n> #!/usr/bin/perl\n>\n> Should we have hard-coded PATH to perl here ?\n\nThis is what is done in other tests:\n\n$ head t*/test.pl -n 1\n==> t0202/test.pl <==\n#!/usr/bin/perl\n\n==> t9000/test.pl <==\n#!/usr/bin/perl\n\n==> t9700/test.pl <==\n#!/usr/bin/perl\n\nWe actually don't use it when running the testsuite properly, since we\ncall\n\n  perl \"$TEST_DIRECTORY\"/t9000/test.pl\n\nand perl is defined as\n\n  perl () {\n  \tcommand \"$PERL_PATH\" \"$@\"\n  }\n\nSo, it's OK.\n\n> /usr/bin/perl --version\n> This is perl, v5.10.0 built for darwin-thread-multi-2level\n> (with 2 registered patches, see perl -V for more detail)\n>\n>> +\n>> +my $is_passing = Test::More->builder->is_passing;\n>> +exit($is_passing ? 0 : 1);\n>> \n>\n> This seems to give problems:\n> debug=t verbose=t ./t9000-addresses.sh\n\nIndeed, is_passing seems too recent for your version of perl. A similar\nproblem was solved in t9700 by 635155f (t9700: Use Test::More->builder,\nnot $Test::Builder::Test, 2010-06-26). I'll use the same solution:\n\nmy $is_passing = eval { Test::More->is_passing };\nexit($is_passing ? 0 : 1) unless $@ =~ /Can't locate object method/;\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"265669","messageId":"1436276295-694-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"39752","inReplyTo":"vpq8uasqeru.fsf@anie.imag.fr","subject":"[PATCH v8 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-07-07T13:38:15Z","receivedAt":"2015-07-07T13:38:15Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\n\nparse_address_line had not the same behavior whether the user had\nMail::Address or not. Teach parse_address_line to behave like\nMail::Address.\n\nWhen the user input is correct, this implementation behaves\nexactly like Mail::Address except when there are quotes\ninside the name:\n\n  \"Jane Do\"e <jdoe@example.com>\n\nIn this case the result of parse_address_line is:\n\n  With M::A : \"Jane Do\" e <jdoe@example.com>\n  Without   : \"Jane Do e\" <jdoe@example.com>\n\nWhen the user input is not correct, the behavior is also mostly\nthe same.\n\nUnlike Mail::Address, this doesn't parse groups and recursive\ncommentaries.\n\nSigned-off-by: Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\nSince v7: portability fix on the final exit() in the perl script.\n\n git-send-email.perl  |  2 +-\n perl/Git.pm          | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n t/t9000-addresses.sh | 27 +++++++++++++++++++++\n t/t9000/test.pl      | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 162 insertions(+), 1 deletion(-)\n create mode 100755 t/t9000-addresses.sh\n create mode 100755 t/t9000/test.pl\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 09ecad8..486cb36 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -478,7 +478,7 @@ sub parse_address_line {\n \tif ($have_mail_address) {\n \t\treturn map { $_->format } Mail::Address->parse($_[0]);\n \t} else {\n-\t\treturn split_addrs($_[0]);\n+\t\treturn Git::parse_mailboxes($_[0]);\n \t}\n }\n \ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 9026a7b..19ef081 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -864,6 +864,73 @@ sub ident_person {\n \treturn \"$ident[0] <$ident[1]>\";\n }\n \n+=item parse_mailboxes\n+\n+Return an array of mailboxes extracted from a string.\n+\n+=cut\n+\n+sub parse_mailboxes {\n+\tmy $re_comment = qr/\\((?:[^)]*)\\)/;\n+\tmy $re_quote = qr/\"(?:[^\\\"\\\\]|\\\\.)*\"/;\n+\tmy $re_word = qr/(?:[^][\"\\s()<>:;@\\\\,.]|\\\\.)+/;\n+\n+\t# divide the string in tokens of the above form\n+\tmy $re_token = qr/(?:$re_quote|$re_word|$re_comment|\\S)/;\n+\tmy @tokens = map { $_ =~ /\\s*($re_token)\\s*/g } @_;\n+\n+\t# add a delimiter to simplify treatment for the last mailbox\n+\tpush @tokens, \",\";\n+\n+\tmy (@addr_list, @phrase, @address, @comment, @buffer) = ();\n+\tforeach my $token (@tokens) {\n+\t\tif ($token =~ /^[,;]$/) {\n+\t\t\t# if buffer still contains undeterminated strings\n+\t\t\t# append it at the end of @address or @phrase\n+\t\t\tif (@address) {\n+\t\t\t\tpush @address, @buffer;\n+\t\t\t} else {\n+\t\t\t\tpush @phrase, @buffer;\n+\t\t\t}\n+\n+\t\t\tmy $str_phrase = join ' ', @phrase;\n+\t\t\tmy $str_address = join '', @address;\n+\t\t\tmy $str_comment = join ' ', @comment;\n+\n+\t\t\t# quote are necessary if phrase contains\n+\t\t\t# special characters\n+\t\t\tif ($str_phrase =~ /[][()<>:;@\\\\,.\\000-\\037\\177]/) {\n+\t\t\t\t$str_phrase =~ s/(^|[^\\\\])\"/$1/g;\n+\t\t\t\t$str_phrase = qq[\"$str_phrase\"];\n+\t\t\t}\n+\n+\t\t\t# add \"<>\" around the address if necessary\n+\t\t\tif ($str_address ne \"\" && $str_phrase ne \"\") {\n+\t\t\t\t$str_address = qq[<$str_address>];\n+\t\t\t}\n+\n+\t\t\tmy $str_mailbox = \"$str_phrase $str_address $str_comment\";\n+\t\t\t$str_mailbox =~ s/^\\s*|\\s*$//g;\n+\t\t\tpush @addr_list, $str_mailbox if ($str_mailbox);\n+\n+\t\t\t@phrase = @address = @comment = @buffer = ();\n+\t\t} elsif ($token =~ /^\\(/) {\n+\t\t\tpush @comment, $token;\n+\t\t} elsif ($token eq \"<\") {\n+\t\t\tpush @phrase, (splice @address), (splice @buffer);\n+\t\t} elsif ($token eq \">\") {\n+\t\t\tpush @address, (splice @buffer);\n+\t\t} elsif ($token eq \"@\") {\n+\t\t\tpush @address, (splice @buffer), \"@\";\n+\t\t} elsif ($token eq \".\") {\n+\t\t\tpush @address, (splice @buffer), \".\";\n+\t\t} else {\n+\t\t\tpush @buffer, $token;\n+\t\t}\n+\t}\n+\n+\treturn @addr_list;\n+}\n \n =item hash_object ( TYPE, FILENAME )\n \ndiff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh\nnew file mode 100755\nindex 0000000..a1ebef6\n--- /dev/null\n+++ b/t/t9000-addresses.sh\n@@ -0,0 +1,27 @@\n+#!/bin/sh\n+\n+test_description='compare address parsing with and without Mail::Address'\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL; then\n+\tskip_all='skipping perl interface tests, perl not available'\n+\ttest_done\n+fi\n+\n+perl -MTest::More -e 0 2>/dev/null || {\n+\tskip_all=\"Perl Test::More unavailable, skipping test\"\n+\ttest_done\n+}\n+\n+perl -MMail::Address -e 0 2>/dev/null || {\n+\tskip_all=\"Perl Mail::Address unavailable, skipping test\"\n+\ttest_done\n+}\n+\n+test_external_has_tap=1\n+\n+test_external_without_stderr \\\n+\t'Perl address parsing function' \\\n+\tperl \"$TEST_DIRECTORY\"/t9000/test.pl\n+\n+test_done\ndiff --git a/t/t9000/test.pl b/t/t9000/test.pl\nnew file mode 100755\nindex 0000000..2d05d3e\n--- /dev/null\n+++ b/t/t9000/test.pl\n@@ -0,0 +1,67 @@\n+#!/usr/bin/perl\n+use lib (split(/:/, $ENV{GITPERLLIB}));\n+\n+use 5.008;\n+use warnings;\n+use strict;\n+\n+use Test::More qw(no_plan);\n+use Mail::Address;\n+\n+BEGIN { use_ok('Git') }\n+\n+my @success_list = (q[Jane],\n+\tq[jdoe@example.com],\n+\tq[<jdoe@example.com>],\n+\tq[Jane <jdoe@example.com>],\n+\tq[Jane Doe <jdoe@example.com>],\n+\tq[\"Jane\" <jdoe@example.com>],\n+\tq[\"Doe, Jane\" <jdoe@example.com>],\n+\tq[\"Jane@:;\\>.,()<Doe\" <jdoe@example.com>],\n+\tq[Jane!#$%&'*+-/=?^_{|}~Doe' <jdoe@example.com>],\n+\tq[\"<jdoe@example.com>\"],\n+\tq[\"Jane jdoe@example.com\"],\n+\tq[Jane Doe <jdoe    @   example.com  >],\n+\tq[Jane       Doe <  jdoe@example.com  >],\n+\tq[Jane @ Doe @ Jane @ Doe],\n+\tq[\"Jane, 'Doe'\" <jdoe@example.com>],\n+\tq['Doe, \"Jane' <jdoe@example.com>],\n+\tq[\"Jane\" \"Do\"e <jdoe@example.com>],\n+\tq[\"Jane' Doe\" <jdoe@example.com>],\n+\tq[\"Jane Doe <jdoe@example.com>\" <jdoe@example.com>],\n+\tq[\"Jane\\\" Doe\" <jdoe@example.com>],\n+\tq[Doe, jane <jdoe@example.com>],\n+\tq[\"Jane Doe <jdoe@example.com>],\n+\tq['Jane 'Doe' <jdoe@example.com>]);\n+\n+my @known_failure_list = (q[Jane\\ Doe <jdoe@example.com>],\n+\tq[\"Doe, Ja\"ne <jdoe@example.com>],\n+\tq[\"Doe, Katarina\" Jane <jdoe@example.com>],\n+\tq[Jane@:;\\.,()<>Doe <jdoe@example.com>],\n+\tq[Jane jdoe@example.com],\n+\tq[<jdoe@example.com> Jane Doe],\n+\tq[Jane <jdoe@example.com> Doe],\n+\tq[\"Jane \"Kat\"a\" ri\"na\" \",Doe\" <jdoe@example.com>],\n+\tq[Jane Doe],\n+\tq[Jane \"Doe <jdoe@example.com>\"],\n+\tq[\\\"Jane Doe <jdoe@example.com>],\n+\tq[Jane\\\"\\\" Doe <jdoe@example.com>],\n+\tq['Jane \"Katarina\\\" \\' Doe' <jdoe@example.com>]);\n+\n+foreach my $str (@success_list) {\n+\tmy @expected = map { $_->format } Mail::Address->parse(\"$str\");\n+\tmy @actual = Git::parse_mailboxes(\"$str\");\n+\tis_deeply(\\@expected, \\@actual, qq[same output : $str]);\n+}\n+\n+TODO: {\n+\tlocal $TODO = \"known breakage\";\n+\tforeach my $str (@known_failure_list) {\n+\t\tmy @expected = map { $_->format } Mail::Address->parse(\"$str\");\n+\t\tmy @actual = Git::parse_mailboxes(\"$str\");\n+\t\tis_deeply(\\@expected, \\@actual, qq[same output : $str]);\n+\t}\n+}\n+\n+my $is_passing = eval { Test::More->is_passing };\n+exit($is_passing ? 0 : 1) unless $@ =~ /Can't locate object method/;\n-- \n2.5.0.rc0.7.ge1edd74.dirty\n"},{"id":"265808","messageId":"559CCE56.7080808@web.de","threadId":"39752","inReplyTo":"1436276295-694-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v8 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-07-08T07:16:38Z","receivedAt":"2015-07-08T07:16:38Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"\n(Thanks for the quick reply.\nSorry for the noise about\n#!/usr/bin/perl\nof course we call the right perl)\n\nThe new patch seems to be integrated in pu (I tested d08caa8e022f08d)\nTest seems to pass, but some noise is on the channel:\n\n\nInitialized empty Git repository in\n/Users/tb/NoBackup/projects/git/git.next/t/trash directory.t9000-addresses/.git/\n# run 0: Perl address parsing function (perl\n/Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl)\nok 1 - use Git;\nok 2 - same output : Jane\nok 3 - same output : jdoe@example.com\nok 4 - same output : <jdoe@example.com>\nok 5 - same output : Jane <jdoe@example.com>\nok 6 - same output : Jane Doe <jdoe@example.com>\nok 7 - same output : \"Jane\" <jdoe@example.com>\nok 8 - same output : \"Doe, Jane\" <jdoe@example.com>\nok 9 - same output : \"Jane@:;\\>.,()<Doe\" <jdoe@example.com>\nok 10 - same output : Jane!\\#$%&'*+-/=?^_{|}~Doe' <jdoe@example.com>\nok 11 - same output : \"<jdoe@example.com>\"\nok 12 - same output : \"Jane jdoe@example.com\"\nok 13 - same output : Jane Doe <jdoe    @   example.com  >\nok 14 - same output : Jane       Doe <  jdoe@example.com  >\nok 15 - same output : Jane @ Doe @ Jane @ Doe\nok 16 - same output : \"Jane, 'Doe'\" <jdoe@example.com>\nok 17 - same output : 'Doe, \"Jane' <jdoe@example.com>\nok 18 - same output : \"Jane\" \"Do\"e <jdoe@example.com>\nok 19 - same output : \"Jane' Doe\" <jdoe@example.com>\nok 20 - same output : \"Jane Doe <jdoe@example.com>\" <jdoe@example.com>\nok 21 - same output : \"Jane\\\" Doe\" <jdoe@example.com>\nok 22 - same output : Doe, jane <jdoe@example.com>\nok 23 - same output : \"Jane Doe <jdoe@example.com>\nok 24 - same output : 'Jane 'Doe' <jdoe@example.com>\nnot ok 25 - same output : Jane\\ Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane\\ Doe <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Jane \\ Doe\" <jdoe@example.com>'\n#     $expected->[0] = '\"Jane\\ Doe\" <jdoe@example.com>'\nnot ok 26 - same output : \"Doe, Ja\"ne <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \"Doe, Ja\"ne <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Doe, Ja\" ne <jdoe@example.com>'\n#     $expected->[0] = '\"Doe, Ja ne\" <jdoe@example.com>'\nnot ok 27 - same output : \"Doe, Katarina\" Jane <jdoe@example.com> # TODO known\nbreakage\n#   Failed (TODO) test 'same output : \"Doe, Katarina\" Jane <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Doe, Katarina\" Jane <jdoe@example.com>'\n#     $expected->[0] = '\"Doe, Katarina Jane\" <jdoe@example.com>'\nnot ok 28 - same output : Jane@:;\\.,()<>Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane@:;\\.,()<>Doe <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[1] = '\\.'\n#     $expected->[1] = '\"\\.\"'\nnot ok 29 - same output : Jane jdoe@example.com # TODO known breakage\n#   Failed (TODO) test 'same output : Jane jdoe@example.com'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = 'Janejdoe@example.com'\nnot ok 30 - same output : <jdoe@example.com> Jane Doe # TODO known breakage\n#   Failed (TODO) test 'same output : <jdoe@example.com> Jane Doe'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane Doe <jdoe@example.com>'\n#     $expected->[0] = 'jdoe@example.comJaneDoe'\nnot ok 31 - same output : Jane <jdoe@example.com> Doe # TODO known breakage\n#   Failed (TODO) test 'same output : Jane <jdoe@example.com> Doe'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane Doe <jdoe@example.com>'\n#     $expected->[0] = 'Jane <jdoe@example.comDoe>'\nnot ok 32 - same output : \"Jane \"Kat\"a\" ri\"na\" \",Doe\" <jdoe@example.com> # TODO\nknown breakage\n#   Failed (TODO) test 'same output : \"Jane \"Kat\"a\" ri\"na\" \",Doe\"\n<jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\"Jane \" Kat \"a\" ri \"na\" \",Doe\" <jdoe@example.com>'\n#     $expected->[0] = '\"Jane  Kat a ri na ,Doe\" <jdoe@example.com>'\nnot ok 33 - same output : Jane Doe # TODO known breakage\n#   Failed (TODO) test 'same output : Jane Doe'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = 'Jane Doe'\nnot ok 34 - same output : Jane \"Doe <jdoe@example.com>\" # TODO known breakage\n#   Failed (TODO) test 'same output : Jane \"Doe <jdoe@example.com>\"'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane'\n#     $expected->[0] = '\"Jane Doe <jdoe@example.com>\"'\nnot ok 35 - same output : \\\"Jane Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : \\\"Jane Doe <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = '\\ \" Jane Doe <jdoe@example.com>'\n#     $expected->[0] = '\"\\\"Jane Doe\" <jdoe@example.com>'\nnot ok 36 - same output : Jane\\\"\\\" Doe <jdoe@example.com> # TODO known breakage\n#   Failed (TODO) test 'same output : Jane\\\"\\\" Doe <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = 'Jane \\ \" \\ \" Doe <jdoe@example.com>'\n#     $expected->[0] = '\"Jane\\\"\\\" Doe\" <jdoe@example.com>'\nnot ok 37 - same output : 'Jane \"Katarina\\\" \\' Doe' <jdoe@example.com> # TODO\nknown breakage\n#   Failed (TODO) test 'same output : 'Jane \"Katarina\\\" \\' Doe' <jdoe@example.com>'\n#   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n#     Structures begin differing at:\n#          $got->[0] = ''Jane \" Katarina \\ \" \\ ' Doe' <jdoe@example.com>'\n#     $expected->[0] = '\"'Jane  Katarina\\\" \\' Doe'\" <jdoe@example.com>'\n1..37\n# test_external test Perl address parsing function was ok\n# expecting no stderr from previous command\n# test_external_without_stderr test no stderr: Perl address parsing function was ok\n"},{"id":"265811","messageId":"vpqfv4zjeft.fsf@anie.imag.fr","threadId":"39752","inReplyTo":"559CCE56.7080808@web.de","subject":"Re: [PATCH v8 07/10] send-email: reduce dependencies impact on parse_address_line","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-07-08T07:28:38Z","receivedAt":"2015-07-08T07:28:38Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Torsten Bögershausen <tboegi@web.de> writes:\n\n> (Thanks for the quick reply.\n> Sorry for the noise about\n> #!/usr/bin/perl\n> of course we call the right perl)\n\nNo problem.\n\n> The new patch seems to be integrated in pu (I tested d08caa8e022f08d)\n> Test seems to pass,\n\nGood.\n\n> but some noise is on the channel:\n\nAre you talking about the output of \"not ok ... # TODO known breakage\"\npart, like this:\n\n> ok 24 - same output : 'Jane 'Doe' <jdoe@example.com>\n> not ok 25 - same output : Jane\\ Doe <jdoe@example.com> # TODO known breakage\n> #   Failed (TODO) test 'same output : Jane\\ Doe <jdoe@example.com>'\n> #   at /Users/tb/NoBackup/projects/git/git.next/t/t9000/test.pl line 62.\n> #     Structures begin differing at:\n> #          $got->[0] = '\"Jane \\ Doe\" <jdoe@example.com>'\n> #     $expected->[0] = '\"Jane\\ Doe\" <jdoe@example.com>'\n\n?\n\nIf so, it seems to be the way Perl's Test::More works with TODO blocks.\nI am reluctant to try to change it for us.\n\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"}]}