7 my ($committer, $patch, $author);
12 $Text::Wrap::columns = 80;
14 my ($rank, $ta, $ack, $who, $tap, $update) = (0) x 6;
15 my ($author_file, $percentage, $cumulative, $reverse);
16 my (%authors, %untraced, %patchers, %committers, %real_names);
17 my ( $from_commit, $to_commit );
19 my $result = GetOptions (
23 "thanks-applied" => \$ta,
29 "authors=s" => \$author_file,
30 "percentage" => \$percentage, # show as %age
31 "cumulative" => \$cumulative,
32 "reverse" => \$reverse,
33 "from=s" => \$from_commit,
34 "to=s" => \$to_commit,
39 my $has_from_commit = defined $from_commit ? 1 : 0;
41 if ( !$result # GetOptions failed
42 or ( $rank + $ta + $who + $ack + $tap + $update != 1 ) # use one and one exactly 'mode'
43 or !( scalar @ARGV + $has_from_commit ) # gitlog provided from --from or stdin
48 $author_file ||= './AUTHORS';
49 die "Can't locate '$author_file'. Specify it with '--authors <path>'."
50 unless -f $author_file;
52 my ( $map, $preferred_email_or_github ) = generate_known_author_map();
54 my $preserve_case = $update ? 1 : 0;
55 my $AUTHORS_header = read_authors_file($author_file, $preserve_case);
59 display_ordered(\%patchers);
62 display_ordered(\%committers);
64 parse_commits_authors();
65 display_test_output(\%patchers, \%authors, \%real_names);
68 display_missing_authors(\%patchers, \%authors, \%real_names);
71 list_authors(\%patchers, \%authors);
73 update_authors_files( \%authors, $map, $preferred_email_or_github, $author_file );
83 Usage: $0 [modes] [modifiers] <git-log-output-file>
86 --who # show list of unique authors by full name
87 --rank # rank authors by patches
88 --thanks-applied # ranks committers of others' patches
89 --missing # display authors not in AUTHORS
90 --tap # show authors present/missing as TAP
91 --update # update the AUTHORS file with missing
94 --authors <authors-file> # path to authors file (default: ./AUTHORS)
95 --percentage # show rankings as percentages
96 --cumulative # show rankings cumulatively
97 --reverse # show rankings in reverse
98 --from # git commit ID used for 'git log' source (use file from STDIN when missing)
99 --to[=HEAD] # git commit ID used for 'git log' destination, default to HEAD.
103 \$ perl Porting/checkAUTHORS.pl --who --from=v5.31.6 --to=v5.31.7
104 \$ perl Porting/checkAUTHORS.pl --rank --percentage --from=v5.31.6
105 \$ perl Porting/checkAUTHORS.pl --thanks-applied --from=v5.31.6
106 \$ perl Porting/checkAUTHORS.pl --missing --from=v5.31.6
107 \$ perl Porting/checkAUTHORS.pl --tap --from=v5.31.6
108 \$ perl Porting/checkAUTHORS.pl --update --from=v5.31.6
110 or the split int two and generate your own git log output
112 Generate git-log-output-file with git log --pretty=fuller rev1..rev2
113 (or pipe by specifying '-' for stdin). For example:
114 \$ git log --pretty=fuller v5.31.6..v5.31.7 > gitlog
115 \$ perl Porting/checkAUTHORS.pl --rank --percentage gitlog
122 my ($patchers, $authors) = @_;
123 binmode(STDOUT, ":utf8");
124 print wrap '', '', join(', ', Unicode::Collate->new(level => 1)->sort(
125 map { $authors->{$_} }
126 grep { length $_ > 1 } # skip the exception '!' and '?'
127 keys %$patchers)) . ".\n";
130 # use --from [and --to] if provided
131 # otherwise fallback to stdin for backward compatibility
133 if ( length $from_commit ) {
134 my ( $from, $to ) = ( $from_commit, $to_commit );
136 my $gitlog = [ qx{git log --pretty=fuller $from..$to} ];
137 die "git log failed: $!" unless $? == 0;
145 my ( $process ) = @_;
147 $process //= \&process; # default processor
149 my $git_log = _git_log();
151 my @lines = split( /^commit\s*/sm, join( '', $git_log->@* ) );
154 next if m/^(\S*?)^Merge:/ism; # skip merge commits
155 if (m/^(.*?)^Author:\s*(.*?)^AuthorDate:\s*.*?^Commit:\s*(.*?)^(.*)$/gism) {
158 ( $patch, $author, $committer ) = ( $1, $2, $3 );
160 unless ($author) { die $_ }
162 unless ($committer) { die $_ }
164 $process->( $committer, $patch, $author );
166 die "XXX $_ did not match";
173 # just grab authors. Quicker than parse_commits
175 sub parse_commits_authors {
177 my $git_log = _git_log();
179 foreach ($git_log->@*) {
180 next unless /^Author:\s*(.*)$/;
182 $author = _raw_address($author);
183 $patchers{$author}++;
189 sub generate_known_author_map {
192 my %preferred_email_or_github;
194 my $previous_name = "";
195 my $previous_preferred_contact = "";
203 if ( my ( $name, $contact ) = /^\s*([^#\s]\S*)\s+(.*\S)/ ) {
205 $name =~ s/^\\043/#/;
206 # use the previous stored email if the line starts by a '+'
207 if ( $name eq '+' ) {
208 $name = $previous_name;
211 $previous_name = $name;
212 $previous_preferred_contact = $contact;
213 if ( index($name, '@' ) > 0 ) {
214 # if name is an email, then this is our preferred email... legacy list
215 $previous_preferred_contact = $name;
219 $map{$contact} = $name;
221 if ( $contact ne $previous_preferred_contact ) {
222 $preferred_email_or_github{$contact} = $previous_preferred_contact;
224 if ( $name ne '+' ) {
225 $preferred_email_or_github{$name} = $previous_preferred_contact;
231 # Email addresses for we do not have names.
235 "bah\100longitude.com",
236 "bbucklan\100jpl-devvax.jpl.nasa.gov",
238 "bob\100starlabs.net",
239 "cygwin\100cygwin.com",
240 "david\100dhaller.de", "erik\100cs.uni-jena.de", "info\100lingo.kiev.ua", # Lingo Translation agency
241 "jms\100mathras.comcast.net",
242 "premchai21\100yahoo.com",
244 "raf\100tradingpost.com.au",
245 "smoketst\100hp46t243.cup.hp.com", "root\100chronos.fi.muni.cz", # no clue - jrv 20090803
246 "gomar\100md.media-web.de", # no clue - jrv 20090803
247 "data-drift\100so.uio.no", # no data. originally private message from 199701282014.VAA12645@selters.uio.no
248 "arbor\100al37al08.telecel.pt"
249 , # reported perlbug ticket 5196 - no actual code contribution. no real name - jrv 20091006
250 "oracle\100pcr8.pcr.com", # Reported perlbug ticket 1015 - no patch - Probably Ed Eddington ed@pcr.com
251 "snaury\100gmail.com", # Reported cpan ticket 35943, with patch for fix
255 # Email addresses for people that don't have an email address in AUTHORS
256 # Presumably deliberately?
261 # Nick Ing-Simmons has passed away (2006-09-25).
262 "nick\100ing-simmons.net",
263 "nik\100tiuk.ti.com",
264 "nick.ing-simmons\100elixent.com",
265 "nick\100ni-s.u-net.com",
266 "nick.ing-simmons\100tiuk.ti.com",
268 # Iain Truskett has passed away (2003-12-29).
269 "perl\100dellah.anu.edu.au", "spoon\100dellah.org", "spoon\100cpan.org",
272 "me-02\100ton.iguana.be", "perl-5.8.0\100ton.iguana.be", "perl5-porters\100ton.iguana.be",
275 "beau\100beaucox.com",
278 "ml-perl\100thepierianspring.org",
281 "pravus\100cpan.org",
283 # perl internal addresses
284 "perl5-porters\100africa.nicoh.com",
285 "perlbug\100perl.org",,
286 "perl5-porters.nicoh.com",
287 "perlbug-followup\100perl.org",
288 "perlbug-comment\100perl.org",
289 "bug-module-corelist\100rt.cpan.org",
290 "bug-storable\100rt.cpan.org",
291 "bugs-perl5\100bugs6.perl.org",
293 "unknown\100unknown",
294 "unknown\100longtimeago",
295 "unknown\100perl.org",
300 return ( \%map, \%preferred_email_or_github );
303 sub read_authors_file {
304 my ( $filename, $preserve_case ) = @_;
305 return unless defined $filename;
311 open my $fh, '<', $filename or die "Can't open $filename: $!";
312 binmode $fh, ':encoding(UTF-8)';
316 do { $in_header = 0; next } if /^-- /;
317 if (/^([^<]+)<([^>]+)>/) {
319 my ($name, $email) = ($1, $2);
321 $raw{$email} = $name;
323 } elsif ( /^([^@]+)\s+(\@\S+)\s*$/ ) {
324 my ($name, $github) = ($1, $2);
326 $raw{$github} = $name;
328 } elsif (/^([- .'\w]+)[\t\n]/) {
332 } elsif ( length $_ ) {
334 warn "Can't parse line '$_'";
340 push @headers, $_ if $in_header;
343 foreach my $contact ( sort keys %raw ) {
344 print "E-mail $contact occurs $count{$contact} times\n" if $count{$contact} > 1;
345 my $lc = lc $contact;
346 my $key = $preserve_case ? $contact : $lc;
347 $authors{ $map->{$lc} || $key } = $raw{$contact};
349 $authors{$_} = $_ for qw(? !);
351 push @headers, '-- ', "\n";
353 return join( '', @headers );
356 sub update_authors_files {
357 my ( $authors, $known_authors, $preferred_email_or_github, $author_file ) = @_;
359 die qq[Cannot find AUTHORS file '$author_file'] unless -f $author_file;
360 binmode(STDOUT, ":utf8");
362 # add missing authors from the recent commits
363 _detect_new_authors_from_recent_commit( $authors, $known_authors );
365 my @author_names = sort { $a cmp $b } values %$authors;
366 my $maxlen = length [ sort { length $b <=> length $a } @author_names ]->[0];
369 foreach my $github_or_email ( sort keys %authors ) {
371 next if length $github_or_email == 1;
373 my $name = $authors{$github_or_email};
376 #$github_or_email = $known_authors->{ $github_or_email } // $github_or_email;
377 $github_or_email = $preferred_email_or_github->{ $github_or_email } // $github_or_email;
379 if ( index( $github_or_email, '@' ) != 0 ) { # preserve '<>' for unicode consortium
380 $github_or_email = '<' . $github_or_email . '>';
383 push @list, sprintf( "%-${maxlen}s %s\n", $name, $github_or_email);
386 # preserve the untraced authors :-) [without email or GitHub account]
387 push @list, map { "$_\n" } keys %untraced;
390 open my $fh, '>', $author_file or die "Can't open $author_file: $!";
391 binmode $fh, ':raw:encoding(UTF-8)';
393 print {$fh} $AUTHORS_header;
395 map { print {$fh} $_ } sort { lc $a cmp lc $b } @list;
404 # read all recent commits and check if the author email is known
405 # if the email is unknown add the author's GitHub account if possible or his email
406 sub _detect_new_authors_from_recent_commit {
407 my ( $authors, $known_authors ) = @_;
409 my $check_if_email_known = sub {
412 my $preferred = $map->{$email} // $map->{lc $email}
413 // $preferred_email_or_github->{$email}
414 // $preferred_email_or_github->{lc $email}
417 return $authors{$preferred} || $authors{ lc $preferred } ? 1 : 0;
420 my $already_checked = {};
422 my ( $committer, $patch, $author ) = @_;
424 foreach my $person ( $author, $committer ) {
425 next unless length $person;
426 next if $already_checked->{$person};
427 $already_checked->{$person} = 1;
429 my $is_author = $person eq $author;
431 if ( $person =~ m{^(.+)\s+<(.+)>$} ) {
432 my ( $name, $email ) = ( $1, $2 );
434 # skip unicode consortium and bad emails
435 if ( index( $email, '@' ) <= 0 ) {
436 warn "# Skipping new author: $person - bad email";
440 next if $check_if_email_known->( $email );
442 # for new users we would prefer using the GitHub account
443 my $github_or_email = _commit_to_github_id( $patch, $is_author ) // $email;
445 next if $check_if_email_known->( $github_or_email );
447 print "# Detected a new author: $name using email $email [ $github_or_email ]\n";
448 $authors{$github_or_email} = $name; # add it to the list of authors
450 warn "Fail to parse author: $person";
455 parse_commits( $process );
460 sub _commit_to_github_id {
461 my ( $commit, $is_author ) = @_;
463 chomp $commit if defined $commit;
464 return unless length $commit;
466 eval { require HTTP::Tiny; 1 } or do {
467 warn "HTTP::Tiny is missing, cannot detect GitHub account from commit id.";
469 *_commit_to_github_id = sub {};
473 my $github_url_for_commit = q[https://github.com/Perl/perl5/commit/] . $commit;
474 my $response = HTTP::Tiny->new->get( $github_url_for_commit );
476 if ( ! $response->{success} ) {
477 warn "HTTP Request Failed: '$github_url_for_commit'";
481 my $content = $response->{content} // '';
483 # poor man scrapping - probably have to be improved over time
484 # try to parse something like: <a href="/Perl/perl5/commits?author=ThisIsMyGitHubID"
485 my @github_ids; # up to two entries author and committer
486 while ( $content =~ s{\Q<a href="/Perl/perl5/commits?author=\E(.+)"}{} ) {
487 push @github_ids, '@' . $1;
490 warn "Found more than two github ids for $github_url_for_commit" if scalar @github_ids > 2;
492 return $github_ids[0] if $is_author;
493 if ( !$is_author && scalar @github_ids >= 2 ) {
494 return $github_ids[1]; # committer is the second entry
497 return $github_ids[0];
501 sub display_test_output {
502 my $patchers = shift;
504 my $real_names = shift;
506 printf "1..%d\n", scalar keys %$patchers;
508 foreach my $email ( sort keys %$patchers ) {
510 if ($authors->{$email}) {
511 print "ok $count - ".$real_names->{$email} ." $email\n";
513 print "not ok $count - Contributor not found in AUTHORS: $email ".($real_names->{$email} || '???' )."\n";
514 print STDERR ($real_names->{$email} || '???' )." <$email> not found in AUTHORS\n";
521 sub display_missing_authors {
522 my $patchers = shift;
524 my $real_names = shift;
526 foreach ( sort keys %$patchers ) {
527 next if $authors->{$_};
529 # Sort by number of patches, then name.
530 $missing{ $patchers{$_} }->{$_}++;
532 foreach my $patches ( sort { $b <=> $a } keys %missing ) {
533 print "\n\n=head1 $patches patch(es)\n\n";
534 foreach my $author ( sort keys %{ $missing{$patches} } ) {
535 my $xauthor = $author;
536 $xauthor =~ s/@/\\100/g; # xxx temp hack
537 print "" . ( $real_names->{$author} || $author ) . "\t\t\t<" . $xauthor . ">\n";
544 sub display_ordered {
549 while ( my ( $name, $count ) = each %$what ) {
550 push @{ $sorted[$count] }, $name;
555 return unless @sorted;
557 foreach my $i ( $reverse ? 0 .. $#sorted : reverse 0 .. $#sorted ) {
558 next unless $sorted[$i];
560 $sum += $i * @{ $sorted[$i] };
562 # Value to display is either this one, or the cumulative sum.
563 my $value = $cumulative ? $sum : $i;
565 $prefix = sprintf "%6.2f:\t", 100 * $value / $total;
567 $prefix = "$value:\t";
569 print wrap ( $prefix, "\t", join( " ", sort @{ $sorted[$i] } ), "\n" );
576 my ( $committer, $patch, $author ) = @_;
577 return unless $author;
578 return unless $committer;
580 $author = _raw_address($author);
581 $patchers{$author}++;
583 $committer = _raw_address($committer);
584 if ( $committer ne $author ) {
586 # separate commit credit only if committing someone else's patch
587 $committers{$committer}++;
596 if ($addr =~ /(?:\\?")?\s*\(via RT\) <perlbug-followup\@perl\.org>$/p) {
597 my $name = ${^PREMATCH};
598 $addr = 'perlbug-followup@perl.org';
600 # Try to find the author
602 if (exists $map->{$name}) {
603 $addr = $map->{$name};
604 $real_name = $authors{$addr};
607 while (my ($email, $author_name) = each %authors) {
608 if ($name eq $author_name) {
616 elsif ( $addr =~ /<.*>/ ) {
617 $addr =~ s/^\s*(.*)\s*<\s*(.*?)\s*>.*$/$2/;
620 $addr =~ s/\[mailto://;
623 $addr = $map->{$addr} || $addr;
624 $addr =~ s/\\100/@/g; # Sometimes, there are encoded @ signs in the git log.
626 if ($real_name) { $real_names{$addr} = $real_name }
635 # List of mappings. First entry the "correct" email address or GitHub account,
636 # as appears in the AUTHORS file. Other lines are "alias" mapped to it.
638 # If the "correct" email address is a '+', the entry above it is reused;
639 # this for addresses with more than one alias.
641 # Note that all entries are in lowercase. Further, no '@' signs should
642 # appear; use \100 instead.
648 + bytesguy\100users.noreply.github.com
649 + git\100ahartley.com
650 adi enache\100rdslink.ro
651 alanbur alan.burlison\100sun.com
652 + alan.burlison\100uk.sun.com
653 + aburlison\100cix.compulink.co.uk
654 ams ams\100toroid.org
657 + atoomic\100cpan.org
658 + cpan\100atoomic.org
659 + nicolas\100atoomic.org
660 chip chip\100pobox.com
662 + salzench\100nielsenmedia.com
663 + chip\100atlantic.net
664 + chip\100rio.atlantic.net
665 + salzench\100dun.nielsen.com
666 + chip\100ci005.sv2.upperbeyond.com
667 craigb craigberry\100mac.com
668 + craig.berry\100metamorgs.com
669 + craig.berry\100signaltreesolutions.com
670 + craig.berry\100psinetcs.com
671 + craig.a.berry\100gmail.com
673 davem davem\100iabyn.nospamdeletethisbit.com
674 + davem\100fdgroup.com
676 + davem\100fdgroup.co.uk
677 + davem\100fdisolutions.com
679 demerphq demerphq\100gmail.com
680 + yves.orton\100de.mci.com
681 + yves.orton\100mciworldcom.de
682 + yves.orton\100booking.com
683 + demerphq\100dromedary.booking.com
684 + demerphq\100gemini.(none)
685 + demerphq\100camel.booking.com
686 + demerphq\100hotmail.com
687 doughera doughera\100lafayette.edu
688 + doughera\100lafcol.lafayette.edu
689 + doughera\100fractal.phys.lafayette.edu
690 + doughera.lafayette.edu
691 + doughera\100newton.phys.lafayette.edu
693 gbarr gbarr\100pobox.com
694 + bodg\100tiuk.ti.com
696 + graham.barr\100tiuk.ti.com
697 + gbarr\100monty.mutatus.co.uk
698 gisle gisle\100aas.no
699 + gisle\100activestate.com
701 + aas\100bergen.sn.no
702 gsar gsar\100cpan.org
703 + gsar\100activestate.com
704 + gsar\100engin.umich.edu
706 + hv\100crypt.compulink.co.uk
709 + jhietaniemi\100gmail.com
711 + jhi\100alpha.hut.fi
714 + jarkko.hietaniemi\100nokia.com
715 + jarkko.hietaniemi\100cc.hut.fi
716 + jarkko.hietaniemi\100booking.com
717 jesse jesse\100fsck.com
718 + jesse\100bestpractical.com
720 merijn h.m.brand\100xs4all.nl
721 + h.m.brand\100procura.nl
722 + merijn.brand\100procura.nl
723 + h.m.brand\100hccnet.nl
724 + merijn\100l1.procura.nl
725 + merijn\100a5.(none)
726 + perl5\100tux.freedom.nl
727 mhx mhx-perl\100gmx.net
730 mst mst\100shadowcat.co.uk
731 + matthewt\100hercule.scsys.co.uk
732 nicholas nick\100ccl4.org
733 + nick\100unfortu.net
734 + nick\100talking.bollo.cx
735 + nick\100plum.flirble.org
736 + nick\100babyhippo.co.uk
737 + nick\100bagpuss.unfortu.net
738 + nick\100babyhippo.com
739 + nicholas\100dromedary.ams6.corp.booking.com
740 + Nicholas Clark (sans From field in mail header)
741 pudge pudge\100pobox.com
742 rgs rgs@consttype.org
743 + rgarciasuarez\100free.fr
744 + rgarciasuarez\100mandrakesoft.com
745 + rgarciasuarez\100mandriva.com
746 + rgarciasuarez\100gmail.com
747 + raphel.garcia-suarez\100hexaflux.com
748 sky artur\100contiller.se
750 + arthur\100contiller.se
751 smueller smueller\100cpan.org
752 + 7k8lrvf02\100sneakemail.com
753 + kjx9zthh3001\100sneakemail.com
754 + dtr8sin02\100sneakemail.com
755 + rt8363b02\100sneakemail.com
756 + o6hhmk002\100sneakemail.com
757 + l2ot9pa02\100sneakemail.com
758 + wyp3rlx02\100sneakemail.com
759 + 0mgwtfbbq\100sneakemail.com
760 + xyey9001\100sneakemail.com
761 steveh steve.m.hay\100googlemail.com
762 + stevehay\100planit.com
763 + steve.hay\100uk.radan.com
764 stevep steve\100fisharerojo.org
765 + steve.peters\100gmail.com
766 + root\100dixie.cscaper.com
767 timb Tim.Bunce\100pobox.com
768 + tim.bunce\100ig.co.uk
769 tonyc tony\100develop-help.com
770 + tony\100openbsd32.tony.develop-help.com
771 + tony\100saturn.(none)
776 \043####\100juerd.nl juerd\100cpan.org
777 + juerd\100c3.convolution.nl
778 + juerd\100convolution.nl
779 a.r.ferreira\100gmail.com aferreira\100shopzilla.com
780 abe\100ztreet.demon.nl abeltje\100cpan.org
781 abela\100hsc.fr abela\100geneanet.org
782 abigail\100abigail.be abigail\100foad.org
783 + abigail\100abigail.nl
785 aburt\100isis.cs.du.edu isis!aburt
786 ach\100mpe.mpg.de ach\100rosat.mpe-garching.mpg.de
787 adavies\100ptc.com alex.davies\100talktalk.net
788 ajohnson\100nvidia.com ajohnson\100wischip.com
789 + anders\100broadcom.com
790 alexm\100netli.com alexm\100w-m.ru
791 alex-p5p\100earth.li alex\100rcon.rog
792 alexmv\100mit.edu alex\100chmrr.net
793 alian\100cpan.org alian\100alianwebserver.com
794 allen\100grumman.com allen\100gateway.grumman.com
795 allen\100huarp.harvard.edu nort\100bottesini.harvard.edu
797 allens\100cpan.org easmith\100beatrice.rutgers.edu
798 + root\100dogberry.rutgers.edu
799 ambs\100cpan.org hashashin\100gmail.com
800 andrea a.koenig@mind.de
801 + andreas.koenig\100anima.de
802 + andreas.koenig.gmwojprw\100franz.ak.mind.de
803 + andreas.koenig.7os6vvqr\100franz.ak.mind.de
804 + a.koenig\100mind.de
805 + k\100anna.in-berlin.de
807 + koenig\100anna.mind.de
809 + root\100ak-71.mind.de
810 + root\100ak-75.mind.de
811 + k\100sissy.in-berlin.de
812 + a.koenig\100kulturbox.de
813 + k\100sissy.in-berlin.de
814 + root\100dubravka.in-berlin.de
815 anno4000\100lublin.zrz.tu-berlin.de anno4000\100mailbox.tu-berlin.de
816 + siegel\100zrz.tu-berlin.de
817 apocal@cpan.org perl\1000ne.us
818 arnold\100gnu.ai.mit.edu arnold\100emoryu2.arpa
819 + gatech!skeeve!arnold
820 arodland\100cpan.org andrew\100hbslabs.com
821 arussell\100cs.uml.edu adam\100adam-pc.(none)
822 ash\100cpan.org ash_cpan\100firemirror.com
823 avar avar\100cpan.org
824 + avarab\100gmail.com
825 bailey\100newman.upenn.edu bailey\100hmivax.humgen.upenn.edu
826 + bailey\100genetics.upenn.edu
827 + bailey.charles\100gmail.com
828 bah\100ecnvantage.com bholzman\100longitude.com
829 barries\100slaysys.com root\100jester.slaysys.com
830 bkedryna\100home.com bart\100cg681574-a.adubn1.nj.home.com
831 bcarter\100gumdrop.flyinganvil.org q.eibcartereio.=~m-b.{6}-cgimosx\100gumdrop.flyinganvil.org
832 ben_tilly\100operamail.com btilly\100gmail.com
833 + ben_tilly\100hotmail.com
834 ben\100morrow.me.uk mauzo\100csv.warwick.ac.uk
836 bepi\100perl.it enrico.sorcinelli\100gmail.com
837 bert\100alum.mit.edu bert\100genscan.com
838 bigbang7\100gmail.com ddascalescu+github\100gmail.com
839 blgl\100stacken.kth.se blgl\100hagernas.com
840 + 2bfjdsla52kztwejndzdstsxl9athp\100gmail.com
841 brian.d.foy\100gmail.com bdfoy\100cpan.org
842 BQW10602\100nifty.com sadahiro\100cpan.org
843 bulk88\100hotmail.com bulk88
845 chad.granum\100dreamhost.com exodist7\100gmail.com
846 choroba\100cpan.org choroba\100weed.(none)
847 + choroba\100matfyz.cz
848 chromatic\100wgz.org chromatic\100rmci.net
849 ckuskie\100cadence.com colink\100perldreamer.com
850 claes\100surfar.nu claes\100versed.se
851 clintp\100geeksalad.org cpierce1\100ford.com
852 clkao\100clkao.org clkao\100bestpractical.com
853 corion\100corion.net corion\100cpan.org
855 cp\100onsitetech.com publiustemp-p5p\100yahoo.com
856 + publiustemp-p5p3\100yahoo.com
858 cpan\100audreyt.org autrijus\100egb.elixus.org
859 + autrijus\100geb.elixus.org
860 + autrijus\100gmail.com
861 + autrijus\100ossf.iis.sinica.edu.tw
862 + autrijus\100autrijus.org
863 + audreyt\100audreyt.org
864 cpan\100ton.iguana.be me-01\100ton.iguana.be
865 crt\100kiski.net perl\100ctweten.amsite.com
866 cp\100onsitetech.com ovid\100cpan.org
867 dairiki\100dairiki.org dairiki at dairiki.org
868 dagolden\100cpan.org xdaveg\100gmail.com
870 damian\100conway.org damian\100cs.monash.edu.au
871 dan\100sidhe.org sugalsd\100lbcc.cc.or.us
872 + sugalskd\100osshe.edu
873 daniel\100bitpusher.com daniel\100biz.bitpusher.com
874 dave\100mag-sol.com dave\100dave.org.uk
875 + dave\100perlhacks.com
876 david.dyck\100fluke.com dcd\100tc.fluke.com
877 david\100justatheory.com david\100wheeler.net
878 + david\100kineticode.com
879 + david\100wheeler.com
880 + david\100wheeler.net
881 whatever\100davidnicol.com davidnicol\100gmail.com
882 dennis\100booking.com dennis\100camel.ams6.corp.booking.com
883 + dennis.kaarsemaker\100booking.com
884 + dennis\100kaarsemaker.net
885 dev-perl\100pimb.org knew-p5p\100pimb.org
886 + lists-p5p\100pimb.org
887 djberg86\100attbi.com djberg96\100attbi.com
888 dk\100tetsuo.karasik.eu.org dmitry\100karasik.eu.org
889 dma+github@stripysock.com dominichamon@users.noreply.github.com
890 dom\100earth.li dom\100semmle.com
891 domo\100computer.org shouldbedomo\100mac.com
892 + domo\100slipper.ip.lu
894 dougm\100covalent.net dougm\100opengroup.org
896 dougw\100cpan.org doug_wilson\100intuit.com
897 dwegscheid\100qtm.net wegscd\100whirlpool.com
898 edwardp\100excitehome.net epeschko\100den-mdev1
899 + epeschko\100elmer.tci.com
901 egf7\100columbia.edu efifer\100sanwaint.com
902 eggert\100twinsun.com eggert\100sea.sm.unisys.com
903 etj\100cpan.org mohawk2\100users.noreply.github.com
905 fugazi\100zyx.net larrysh\100cpan.org
906 + lshatzer\100islanddata.com
908 gbacon\100itsc.uah.edu gbacon\100adtrn-srv4.adtran.com
909 gerberb\100zenez.com root\100devsys0.zenez.com
910 gfuji\100cpan.org g.psy.va\100gmail.com
911 genesullivan50\100yahoo.com gsullivan\100cpan.org
912 gerard\100ggoossen.net gerard\100tty.nl
913 gibreel\100pobox.com stephen.zander\100interlock.mckesson.com
915 gideon\100cpan.org gidisrael\100gmail.com
916 gnat\100frii.com gnat\100prometheus.frii.com
917 gp\100familiehaase.de gerrit\100familiehaase.de
918 grazz\100pobox.com grazz\100nyc.rr.com
919 gward\100ase.com greg\100bic.mni.mcgill.ca
920 haggai\100cpan.org alanhaggai\100alanhaggai.org
921 + alanhaggai\100gmail.com
922 hansmu\100xs4all.nl hansm\100icgroup.nl
926 + hansm\100euronet.nl
928 hio\100ymir.co.jp hio\100hio.jp
929 hops\100sco.com hops\100scoot.pdev.sco.com
931 ian.goodacre\100xtra.co.nz ian\100debian.lan
932 ingo_weinhold\100gmx.de bonefish\100cs.tu-berlin.de
934 james\100mastros.biz theorb\100desert-island.me.uk
935 jan\100jandubois.com jand\100activestate.com
936 + jan.dubois\100ibm.net
937 japhy\100pobox.com japhy\100pobox.org
938 + japhy\100perlmonk.org
940 + jeffp\100crusoe.net
941 jari.aalto\100poboxes.com jari.aalto\100cante.net
942 jarausch\100numa1.igpm.rwth-aachen.de helmutjarausch\100unknown
943 jasons\100cs.unm.edu jasons\100sandy-home.arc.unm.edu
944 jbuehler\100hekimian.com jhpb\100hekimian.com
945 jcromie\100cpan.org jcromie\100100divsol.com
946 + jim.cromie\100gmail.com
947 jd\100cpanel.net lightsey\100debian.org
949 + john\100nixnuts.net
950 jdhedden\100cpan.org jerry\100hedden.us
951 + jdhedden\1001979.usna.com
952 + jdhedden\100gmail.com
953 + jdhedden\100yahoo.com
954 + jhedden\100pn100-02-2-356p.corp.bloomberg.com
955 + jdhedden\100solydxk
956 jeremy\100zawodny.com jzawodn\100wcnet.org
957 jesse\100sig.bsh.com jesse\100ginger
958 jfriedl\100yahoo.com jfriedl\100yahoo-inc.com
959 jfs\100fluent.com jfs\100jfs.fluent.com
960 jhannah\100mutationgrid.com jay\100jays.net
961 + jhannah\100omnihotels.com
962 jidanni\100jidanni.org jidanni\100hoffa.dreamhost.com
963 jjore\100cpan.org twists\100gmail.com
964 jkeenan\100cpan.org jkeen\100verizon.net
965 + jkeenan\100dromedary-001.ams6.corp.booking.com
966 jns\100integration-house.com jns\100gellyfish.com
967 + gellyfish\100gellyfish.com
968 john\100atlantech.com john\100titanic.atlantech.com
969 john\100johnwright.org john.wright\100hp.com
970 joseph\100cscaper.com joseph\1005sigma.com
971 joshua\100rodd.us jrodd\100pbs.org
972 jtobey\100john-edwin-tobey.org jtobey\100user1.channel1.com
973 jpeacock\100messagesystems.com john.peacock\100havurah-software.org
974 + jpeacock\100havurah-software.org
975 + jpeacock\100dsl092-147-156.wdc1.dsl.speakeasy.net
976 + jpeacock\100jpeacock-hp.doesntexist.org
977 + jpeacock\100cpan.org
978 + jpeacock\100rowman.com
979 james.schneider\100db.com jschneid\100netilla.com
980 jpl.jpl\100gmail.com jpl\100research.att.com
981 jql\100accessone.com jql\100jql.accessone.com
982 jsm28\100hermes.cam.ac.uk jsm28\100cam.ac.uk
984 kane\100dwim.org kane\100xs4all.net
989 keith.s.thompson\100gmail.com kst\100mib.org
990 ken\100mathforum.org kenahoo\100gmail.com
991 + ken.williams\100thomsonreuters.com
992 kentfredric\100gmail.com kentnl\100cpan.org
993 kmx\100volny.cz kmx\100volny.cz
995 kroepke\100dolphin-services.de kay\100dolphin-services.de
996 kst\100mib.org kst\100cts.com
998 kstar\100wolfetech.com kstar\100cpan.org
999 + kurt_starsinic\100ml.com
1000 + kstar\100www.chapin.edu
1001 + kstar\100chapin.edu
1002 larry\100wall.org lwall\100jpl-devvax.jpl.nasa.gov
1003 + lwall\100netlabs.com
1004 + larry\100netlabs.com
1006 + lwall\100scalpel.netlabs.com
1007 laszlo.molnar\100eth.ericsson.se molnarl\100cdata.tvnet.hu
1008 + ml1050\100freemail.hu
1009 lewart\100uiuc.edu lewart\100vadds.cvm.uiuc.edu
1010 + d-lewart\100uiuc.edu
1011 lindblad@gmx.com 52227507+apparluk\100users.noreply.github.com
1012 lkundrak\100v3.sk lubo.rintel\100gooddata.com
1013 lstein\100cshl.org lstein\100formaggio.cshl.org
1014 + lstein\100genome.wi.mit.edu
1015 l.mai\100web.de plokinom\100gmail.com
1016 lupe\100lupe-christoph.de lupe\100alanya.m.isar.de
1017 lutherh\100stratcom.com lutherh\100infinet.com
1018 mab\100wdl.loral.com markb\100rdcf.sm.unisys.com
1019 marcel\100codewerk.com gr\100univie.ac.at
1020 + hanekomu\100gmail.com
1021 marcgreen\100cpan.org marcgreen\100wpi.edu
1022 markleightonfisher\100gmail.com fisherm\100tce.com
1023 + mark-fisher\100mindspring.com
1024 mark.p.lutz\100boeing.com tecmpl1\100triton.ca.boeing.com
1025 marnix\100gmail.com pttesac!marnix!vanam
1026 marty+p5p\100kasei.com marty\100martian.org
1027 mats\100sm6sxl.net mats\100sm5sxl.net
1028 mbarbon\100dsi.unive.it mattia.barbon\100libero.it
1029 + mattia\100barbon.org
1030 mcmahon\100ibiblio.org mcmahon\100metalab.unc.edu
1031 me\100davidglasser.net glasser\100tang-eleven-seventy-nine.mit.edu
1032 merijnb\100iloquent.nl merijnb\100ms.com
1033 + merijnb\100iloquent.com
1034 merlyn\100stonehenge.com merlyn\100gadget.cscaper.com
1035 mestre.smash\100gmail.com smash\100cpan.org
1036 mgjv\100comdyn.com.au mgjv\100tradingpost.com.au
1037 mlh\100swl.msd.ray.com webtools\100uewrhp03.msd.ray.com
1038 michael.schroeder\100informatik.uni-erlangen.de mls\100suse.de
1039 mike\100stok.co.uk mike\100exegenix.com
1040 61100689+mikefultondev\100users.noreply.github.com mikefultonpersonal\100gmail.com
1041 miyagawa\100bulknews.net miyagawa\100edge.co.jp
1042 mjtg\100cam.ac.uk mjtg\100cus.cam.ac.uk
1043 mikedlr\100tardis.ed.ac.uk mikedlr\100it.com.pl
1044 moritz\100casella.verplant.org moritz\100faui2k3.org
1047 neale\100VMA.TABNSW.COM.AU neale\100pucc.princeton.edu
1048 neeracher\100mac.com neeri\100iis.ee.ethz.ch
1049 neilb\100neilb.org neilb\100cre.canon.co.uk
1050 + neil\100bowers.com
1052 nospam-abuse\100bloodgate.com tels\100bloodgate.com
1053 + perl_dummy\100bloodgate.com
1055 ian.phillipps\100iname.com ian_phillipps\100yahoo.co.uk
1056 + ian\100dial.pipex.com
1057 ignasi.roca\100fujitsu-siemens.com ignasi.roca\100fujitsu.siemens.es
1058 ikegami\100adaelis.com eric\100fmdev10.(none)
1059 ilmari\100ilmari.org ilmari\100vesla.ilmari.org
1060 illpide\100telecel.pt arbor\100al37al08.telecel.pt
1061 # see http://www.nntp.perl.org/group/perl.perl5.porters/2001/01/msg28925.html
1063 ilya\100math.berkeley.edu ilya\100math.ohio-state.edu
1064 + nospam-abuse\100ilyaz.org
1065 + [9]ilya\100math.ohio-state.edu
1066 ilya\100martynov.org ilya\100juil.nonet
1068 joshua\100paloalto.com joshua.pritikin\100db.com
1070 litt\100acm.org tlhackque\100yahoo.com
1072 meyering@asic.sc.ti.com jim\100meyering.net
1074 okamoto\100corp.hp.com okamoto\100hpcc123.corp.hp.com
1075 orwant\100oreilly.com orwant\100media.mit.edu
1077 p5-authors\100crystalflame.net perl\100crystalflame.net
1078 + rs\100crystalflame.net
1079 + coral\100eekeek.org
1080 + coral\100moonlight.crystalflame.net
1081 + rs\100oregonnet.com
1083 paul.green\100stratus.com paul_greenvos\100vos.stratus.com
1084 + pgreen\100seussnt.stratus.com
1085 pmqs pmqs\100cpan.org
1086 + paul.marquess\100btinternet.com
1087 + paul_marquess\100yahoo.co.uk
1088 + paul.marquess\100ntlworld.com
1089 + paul.marquess\100openwave.com
1090 + pmarquess\100bfsec.bt.co.uk
1092 + paul\100paul-desktop.(none)
1093 Pavel.Zakouril\100mff.cuni.cz root\100egg.karlov.mff.cuni.cz
1094 pcg\100goof.com schmorp\100schmorp.de
1095 perl\100cadop.com cdp\100hpescdp.fc.hp.com
1096 perl\100greerga.m-l.org greerga\100m-l.org
1097 perl\100profvince.com vince\100profvince.com
1098 perl-rt\100wizbit.be p5p\100perl.wizbit.be
1099 # Maybe we should special case this to get real names out?
1100 Peter.Dintelmann\100Dresdner-Bank.com peter.dintelmann\100dresdner-bank.com
1101 # NOTE: There is an intentional trailing space in the line above
1102 pfeifer\100wait.de pfeifer\100charly.informatik.uni-dortmund.de
1104 pjacklam\100online.no pjacklam\100gmail.com
1105 ribasushi@cpan.org rabbit\100rabbit.us
1106 + rabbit+bugs\100rabbit.us
1107 arc\100cpan.org perl\100aaroncrane.co.uk
1108 + arc@users.noreply.github.com
1109 phil\100perkpartners.com phil\100finchcomputer.com
1110 pimlott\100idiomtech.com andrew\100pimlott.net
1111 + pimlott\100abel.math.harvard.edu
1112 pixel\100mandriva.com pixel\100mandrakesoft.com
1113 pne\100cpan.org philip.newton\100gmx.net
1114 + philip.newton\100datenrevision.de
1116 pprymmer\100factset.com pvhp\100forte.com
1117 khw\100cpan.org khw\100karl.(none)
1118 + public\100khwilliamson.com
1119 + khw\100khw-desktop.(none)
1121 radu\100netsoft.ro rgreab\100fx.ro
1123 + raiph.mellor\100gmail.com
1124 rajagopa\100pauline.schrodinger.com rajagopa\100schrodinger.com
1125 raphael.manfredi\100pobox.com raphael_manfredi\100grenoble.hp.com
1126 info\100perl-services.de renee.baecker\100smart-websolutions.de
1127 + reneeb\100reneeb-desktop.(none)
1128 + github\100renee-baecker.de
1129 + otrs\100ubuntu.(none)
1130 + perl\100renee-baecker.de
1131 + reb\100perl-services.de
1132 + module\100renee-baecker.de
1133 rich+perl\100hyphen-dash-hyphen.info richardleach\100users.noreply.github.com
1134 richard.foley\100rfi.net richard.foley\100t-online.de
1135 + richard.foley\100ubs.com
1136 + richard.foley\100ubsw.com
1137 rick\100consumercontact.com rick\100bort.ca
1138 + rick.delaney\100rogers.com
1140 + rick.delaney\100home.com
1141 rjbs\100cpan.org rjbs-perl-p5p\100lists.manxome.org
1142 + perl.p5p\100rjbs.manxome.org
1143 + rjbs\100semiotic.systems
1144 + rjbs\100users.noreply.github.com
1145 rjk\100linguist.dartmouth.edu rjk\100linguist.thayer.dartmouth.edu
1146 + rjk-perl-p5p\100tamias.net
1148 rjray\100redhat.com rjray\100uswest.com
1149 rmgiroux\100acm.org rmgiroux\100hotmail.com
1150 + mgiroux\100bear.com
1151 rmbarker\100cpan.org rmb1\100cise.npl.co.uk
1152 + robin.barker\100npl.co.uk
1153 + rmb\100cise.npl.co.uk
1154 + robin\100spade-ubuntu.(none)
1155 + r.m.barker\100btinternet.com
1156 + rmbarker.cpan\100btinternet.com
1157 robertmay\100cpan.org rob\100themayfamily.me.uk
1158 roberto\100keltia.freenix.fr roberto\100eurocontrol.fr
1159 robin\100cpan.org robin\100kitsite.com
1160 roderick\100argon.org roderick\100gate.net
1161 + roderick\100ibcinc.com
1162 argrath\100ub32.org root\100ub32.org
1163 rootbeer\100teleport.com rootbeer\100redcat.com
1164 + tomphoenix\100unknown
1165 rra\100stanford.edu rra\100cpan.org
1166 rurban\100cpan.org rurban\100x-ray.at
1167 + rurban\100cpanel.net
1168 rvtol+news\100isolution.nl rvtol\100isolution.nl
1169 sartak\100gmail.com sartak\100bestpractical.com
1170 + code\100sartak.org
1171 danny-cpan\100sadinoff.com sadinoff\100olf.com
1172 schubiger\100cpan.org steven\100accognoscere.org
1173 + sts\100accognoscere.org
1174 + schubiger\100gmail.com
1175 + stsc\100refcnt.org
1176 schwern\100pobox.com schwern\100gmail.com
1177 + schwern\100athens.arena-i.com
1178 + schwern\100blackrider.aocn.com
1179 + schwern\100ool-18b93024.dyn.optonline.net
1180 scop\100cs132170.pp.htv.fi ville.skytta\100iki.fi
1181 scotth\100sgi.com author scotth\100sgi.com 842220273 +0000
1182 + schotth\100sgi.com
1183 schwab\100suse.de schwab\100issan.informatik.uni-dortmund.de
1184 + schwab\100ls5.informatik.uni-dortmund.de
1185 sebastien\100aperghis.net maddingue\100free.fr
1187 shigeya\100wide.ad.jp shigeya\100foretune.co.jp
1188 shlomif\100cpan.org shlomif\100vipe.technion.ac.il
1189 + shlomif\100iglu.org.il
1190 + shlomif+processed-by-perl\100gmail.com
1191 + shlomif\100shlomifish.org
1192 simon\100netthink.co.uk simon\100simon-cozens.org
1193 + simon\100pembro4.pmb.ox.ac.uk
1194 + simon\100brecon.co.uk
1195 + simon\100othersideofthe.earth.li
1196 + simon\100cozens.net
1198 sisyphus\100cpan.org sisyphus1\100optusnet.com.au
1199 + sisyphus359\100gmail.com
1200 lannings\100who.int lannings\100gmail.com
1201 + slanning\100cpan.org
1202 slaven\100rezic.de slaven.rezic\100berlin.de
1203 + srezic\100iconmobile.com
1204 + srezic\100cpan.org
1205 + eserte\100cs.tu-berlin.de
1206 + eserte\100vran.herceg.de
1207 smcc\100mit.edu smcc\100ocf.berkeley.edu
1208 + smcc\100csua.berkeley.edu
1210 + smccam\100uclink4.berkeley.edu
1211 spider\100orb.nashua.nh.us spider\100web.zk3.dec.com
1212 + spider\100leggy.zk3.dec.com
1213 + spider-perl\100orb.nashua.nh.us
1214 + spider\100peano.zk3.dec.com
1215 + spider.boardman\100orb.nashua.nh.us>
1217 + spider.boardman\100orb.nashua.nh.us
1218 + root\100peano.zk3.dec.com
1219 s.denaxas\100gmail.com spiros\100lokku.com
1220 spp\100ds.net spp\100psa.pencom.com
1221 + spp\100psasolar.colltech.com
1222 + spp\100spotter.yi.org
1223 stef\100mongueurs.net stef\100payrard.net
1224 + s.payrard\100wanadoo.fr
1225 + properler\100freesurf.fr
1226 + stef\100francenet.fr
1227 stevan\100cpan.org stevan.little\100gmail.com
1228 + stevan.little\100iinteractive.com
1229 sthoenna\100efn.org ysth\100raven.shiftboard.com
1231 tassilo.parseval\100post.rwth-aachen.de tassilo.von.parseval\100rwth-aachen.de
1232 tchrist\100perl.com tchrist\100mox.perl.com
1233 + tchrist\100jhereg.perl.com
1234 thomas.dorner\100start.de tdorner\100amadeus.net
1235 tjenness\100cpan.org t.jenness\100jach.hawaii.edu
1236 + timj\100jach.hawaii.edu
1237 tobez\100tobez.org tobez\100plab.ku.dk
1238 toddr\100cpan.org toddr\100cpanel.net
1239 tom\100compton.nu thh\100cyberscience.com
1240 tom.horsley\100mail.ccur.com tom.horsley\100ccur.com
1241 + tom\100amber.ssd.hcsc.com
1243 vkonovalov\100lucent.com vkonovalov\100peterstar.ru
1244 + konovalo\100mail.wplus.net
1245 + vadim\100vkonovalov.ru
1246 + vkonovalov\100spb.lucent.com
1247 + vkonovalov\100alcatel-lucent.com
1248 + vadim.konovalov\100alcatel-lucent.com
1250 whatever\100davidnicol.com davidnicol\100gmail.com
1251 wolfgang.laun\100alcatel.at wolfgang.laun\100chello.at
1252 + wolfgang.laun\100thalesgroup.com
1253 + wolfgang.laun\100gmail.com
1254 wolfsage\100gmail.com mhorsfall\100darmstadtium.(none)
1255 yath\100yath.de yath-perlbug\100yath.de