4 # Modules - show information about modules and their maintainers
9 use vars qw($Maintainers $Modules);
13 'ams' => 'Abhijit Menon-Sen <ams@wiw.org>',
14 'andreas' => 'Andreas J. Koenig <andreas.koenig@anima.de>',
15 'arthur' => 'Arthur Bergman <sky@nanisky.com>',
16 'bbb' => 'Rob Brown <bbb@cpan.org>',
17 'damian' => 'Damian Conway <damian@conway.org>',
18 'dankogai' => 'Dan Kogai <dankogai@dan.co.jp>',
19 'gbarr' => 'Graham Barr <gbarr@pobox.com>',
20 'gisle' => 'Gisle Aas <gisle@activestate.com>',
21 'ilyaz' => 'Ilya Zakharevich <ilyaz@cpan.org>',
22 'jhi' => 'Jarkko Hietaniemi <jhi@iki.fi>',
23 'jns' => 'Jonathan Stowe <jns@gellyfish.com>',
24 'jvromans' => 'Johan Vromans <jvromans@squirrel.nl>',
25 'lstein' => 'Lincoln D. Stein <lstein@cshl.org>',
26 'mjd' => 'Mark-Jason Dominus <mjd@plover.com>',
27 'muir' => 'David Muir Sharnoff <muir@idiom.com>',
28 'neilb' => 'Neil Bowers <neil@bowers.com>',
29 'rra' => 'Russ Allbery <rra@stanford.edu>',
30 'pmarquess' => 'Paul Marquess <Paul.Marquess@btinternet.com>',
31 'sadahiro' => 'SADAHIRO Tomoyuki <SADAHIRO@cpan.org>',
32 'sburke' => 'Sean Burke <sburke@cpan.org>',
33 'smcc' => 'Stephen McCamant <smcc@CSUA.Berkeley.EDU>',
34 'schwern' => 'Michael Schwern <schwern@pobox.com>',
35 'tels' => 'Tels a-t bloodgate.com',
36 'tjenness' => 'Tim Jenness <t.jenness@jach.hawaii.edu>'
41 'Attribute::Handlers' =>
43 'MAINTAINER' => 'arthur',
45 q[lib/Attribute/Handlers.pm lib/Attribute/Handlers],
50 'MAINTAINER' => 'smcc',
51 'FILES' => q[ext/B/B/Concise.pm ext/B/t/concise.t],
56 'MAINTAINER' => 'tels',
57 'FILES' => q[lib/big{int,num,rat}.pm lib/bignum],
62 'MAINTAINER' => 'lstein',
63 'FILES' => q[lib/CGI.pm lib/CGI],
68 'MAINTAINER' => 'sburke',
69 'FILES' => q[lib/Class/ISA.pm lib/Class/ISA],
74 'MAINTAINER' => 'andreas',
75 'FILES' => q[lib/CPAN.pm lib/CPAN],
78 # Data::Dumper is not here, Sarathy has given up the maintenance
79 # and Data::Dumper should be considered a part of the Perl core.
83 'MAINTAINER' => 'pmarquess',
84 'FILES' => q[ext/DB_File],
89 'MAINTAINER' => 'pmarquess',
90 'FILES' => q[ext/Devel/PPPort],
95 'MAINTAINER' => 'gisle',
96 'FILES' => q[lib/Digest.{pm,t}],
101 'MAINTAINER' => 'gisle',
102 'FILES' => q[ext/Digest/MD5],
107 'MAINTAINER' => 'dankogai',
108 'FILES' => q[ext/Encode],
111 # Errno is not here, Graham has given up the maintenance
112 # and Errno should be considered a part of the Perl core.
114 'ExtUtils::MakeMaker' =>
116 'MAINTAINER' => 'schwern',
117 'FILES' => q[lib/ExtUtils/MakeMaker],
122 'MAINTAINER' => 'tjenness',
123 'FILES' => q[lib/File/Temp.pm lib/File/Temp],
128 'MAINTAINER' => 'damian',
129 'FILES' => q[lib/Filter/Simple.pm lib/Filter/Simple],
132 'Filter::Util::Call' =>
134 'MAINTAINER' => 'pmarquess',
135 'FILES' => q[ext/Filter/Util/Call],
140 'MAINTAINER' => 'jvromans',
141 'FILES' => q[lib/Getopt/Long.pm lib/Getopt/Long],
146 'MAINTAINER' => 'sburke',
147 'FILES' => q[lib/I18N/LangTags.pm lib/I18N/LangTags],
152 'MAINTAINER' => 'ilyaz',
153 'FILES' => q[lib/if.{pm,t}],
156 # IO is not here, Graham has given up the maintenance
157 # and IO should be considered a part of the Perl core.
161 'MAINTAINER' => 'gbarr',
163 q[lib/Net/{Cmd,Domain,FTP,Netrc,NNTP,POP3,SMTP,Time}.pm lib/Net/ChangeLog.libnet lib/Net/FTP lib/Net/*.eg lib/Net/libnetFAQ.pod lib/Net/README.libnet lib/Net/t],
166 'Scalar-List-Util' =>
168 'MAINTAINER' => 'gbarr',
169 'FILES' => q[ext/List/Util],
174 'MAINTAINER' => 'neilb',
175 'FILES' => q[lib/Locale/{Codes,Constants,Country,Currency,Language,Script}*],
178 'Locale::Maketext' =>
180 'MAINTAINER' => 'sburke',
181 'FILES' => q[lib/Locale/Maketext.pm lib/Locale/Maketext],
186 'MAINTAINER' => 'tels',
187 'FILES' => q[lib/Math/BigFloat.pm lib/Math/BigFloat],
192 'MAINTAINER' => 'tels',
193 'FILES' => q[lib/Math/BigInt.pm lib/Math/BigInt],
198 'MAINTAINER' => 'tels',
199 'FILES' => q[lib/Math/BigRat.pm lib/Math/BigRat],
204 'MAINTAINER' => 'mjd',
205 'FILES' => q[lib/Memoize.pm lib/Memoize],
210 'MAINTAINER' => 'gisle',
211 'FILES' => q[ext/MIME/Base64],
216 'MAINTAINER' => 'bbb',
217 'FILES' => q[lib/Net/Ping.pm lib/Net/Ping],
222 'MAINTAINER' => 'damian',
223 'FILES' => q[lib/NEXT.pm lib/NEXT],
226 # The PerlIO::* are part of Perl core.
230 'MAINTAINER' => 'rra',
231 'FILES' => q[lib/Pod/{Html,Man,ParseLink,Text,Text/{Color,Overstrike,Termcap}}.pm pod/pod2man.PL pod/pod2text.PL lib/Pod/t/{basic.*,{basic,man,parselink,text*}.t}],
236 'MAINTAINER' => 'ams',
237 'FILES' => q[ext/Storable],
242 'MAINTAINER' => 'damian',
243 'FILES' => q[lib/Switch.pm lib/Switch],
248 'MAINTAINER' => 'muir',
250 q[lib/Text/{Tabs,Wrap}.pm lib/Text/TabsWrap],
255 'MAINTAINER' => 'damian',
256 'FILES' => q[lib/Text/Balanced.pm lib/Text/Balanced],
261 'MAINTAINER' => 'rra',
262 'FILES' => q[lib/Term/ANSIColor.pm lib/Term/ANSIColor],
267 'MAINTAINER' => 'schwern',
268 'FILES' => q[lib/Test/Builder.pm],
273 'MAINTAINER' => 'schwern',
274 'FILES' => q[lib/Test/Harness.pm lib/Test/Harness],
279 'MAINTAINER' => 'schwern',
280 'FILES' => q[lib/Test/More.pm],
285 'MAINTAINER' => 'schwern',
286 'FILES' => q[lib/Test/Simple.pm lib/Test/Simple],
291 'MAINTAINER' => 'jns',
292 'FILES' => q[lib/Term/Cap.{pm,t}],
298 'MAINTAINER' => 'arthur',
299 'FILES' => q[ext/threads],
304 'MAINTAINER' => 'mjd',
305 'FILES' => q[lib/Tie/File.pm lib/Tie/File],
310 'MAINTAINER' => 'jhi',
311 'FILES' => q[ext/Time/HiRes],
314 'Unicode::Collate' =>
316 'MAINTAINER' => 'sadahiro',
318 q[lib/Unicode/Collate.pm lib/Unicode/Collate],
321 'Unicode::Normalize' =>
323 'MAINTAINER' => 'sadahiro',
324 'FILES' => q[ext/Unicode/Normalize],
329 'MAINTAINER' => 'pmarquess',
331 q[warnings.pl lib/warnings.{pm,t}
332 lib/warnings t/lib/warnings],
342 $0: Usage: $0 [[--maintainer M --module M --files]|file ...]
343 $0 --maintainer M list all maintainers matching M
344 $0 --module M list all modules matching M
345 $0 --files list all files of the module
346 Matching is case-ignoring regexp, author matching is both by
347 the short id and by the full name and email.
348 $0 file ... list the module and maintainer
360 'maintainer=s' => \$Maintainer,
361 'module=s' => \$Module,
367 usage() if @Files && ($Maintainer || $Module || $Files);
369 for my $mean ($Maintainer, $Module) {
370 warn "$0: Did you mean '$0 $mean'?\n"
371 if $mean && -e $mean && $mean ne '.';
374 warn "$0: Did you mean '$0 -mo $Maintainer'?\n"
375 if defined $Maintainer && exists $Modules->{$Maintainer};
377 warn "$0: Did you mean '$0 -ma $Module'?\n"
378 if defined $Module && exists $Maintainers->{$Module};
382 split ' ', $Modules->{$m}->{FILES};
385 sub get_module_files {
387 sort { lc $a cmp lc $b }
389 -f $_ ? # Files as-is.
391 -d _ ? # Recurse into directories.
396 push @files, $File::Find::name
401 : glob($_) # The rest are globbable patterns.
402 } get_module_pat($m);
405 sub get_maintainer_modules {
407 sort { lc $a cmp lc $b }
408 grep { $Modules->{$_}->{MAINTAINER} eq $m }
413 for my $m (sort keys %$Maintainers) {
414 if ($m =~ /$Maintainer/io) {
415 my @modules = get_maintainer_modules($m);
417 @modules = grep { /$Module/io } @modules;
421 for my $module (@modules) {
422 push @files, get_module_files($module);
424 printf "%-15s @files\n", $m;
427 printf "%-15s @modules\n", $m;
429 printf "%-15s $Maintainers->{$m}\n", $m;
435 for my $m (sort { lc $a cmp lc $b } keys %$Modules) {
436 if ($m =~ /$Module/io) {
438 my @files = get_module_files($m);
439 printf "%-15s @files\n", $m;
441 printf "%-15s $Modules->{$m}->{MAINTAINER}\n", $m;
448 @ModuleByFile{@Files} = ();
450 # First try fast match.
453 for my $module (keys %$Modules) {
454 for my $pat (get_module_pat($module)) {
455 $ModuleByPat{$pat} = $module;
460 for my $pat (keys %ModuleByPat) {
462 $ExpModuleByPat{$pat} = $ModuleByPat{$pat};
464 for my $exp (glob($pat)) {
465 $ExpModuleByPat{$exp} = $ModuleByPat{$pat};
469 %ModuleByPat = %ExpModuleByPat;
470 for my $file (@Files) {
471 $ModuleByFile{$file} = $ModuleByPat{$file}
472 if exists $ModuleByPat{$file};
475 # If still unresolved files..
476 if (my @ToDo = grep { !defined $ModuleByFile{$_} } keys %ModuleByFile) {
478 # Cannot match what isn't there.
479 @ToDo = grep { -e $_ } @ToDo;
482 # Try prefix matching.
484 # Remove trailing slashes.
485 for (@ToDo) { s|/$|| }
490 for my $pat (keys %ModuleByPat) {
491 last unless keys %ToDo;
494 for my $file (keys %ToDo) {
495 if ($file =~ m|^$pat|i) {
496 $ModuleByFile{$file} = $ModuleByPat{$pat};
506 for my $file (@Files) {
507 if (defined $ModuleByFile{$file}) {
508 my $module = $ModuleByFile{$file};
509 my $maintainer = $Modules->{$ModuleByFile{$file}}->{MAINTAINER};
510 printf "%-15s $module $maintainer $Maintainers->{$maintainer}\n", $file;
512 printf "%-15s ?\n", $file;