diff options
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | Porting/Modules | 195 | ||||
-rw-r--r-- | Porting/Modules.pl | 446 |
3 files changed, 643 insertions, 0 deletions
@@ -2402,6 +2402,8 @@ Porting/genlog Generate formatted changelogs by querying p4d Porting/Glossary Glossary of config.sh variables Porting/makerel Release making utility Porting/manicheck Check against MANIFEST +Porting/Modules Program to pretty print info in Modules.pl +Porting/Modules.pl Information about modules and their maintainers Porting/p4d2p Generate patch from p4 diff Porting/p4genpatch Generate patch from p4 change in repository (obsoletes p4desc) Porting/patching.pod How to report changes made to Perl diff --git a/Porting/Modules b/Porting/Modules new file mode 100644 index 0000000000..9de5385232 --- /dev/null +++ b/Porting/Modules @@ -0,0 +1,195 @@ +#!/usr/bin/perl -w + +# +# Modules - show information about modules and their maintainers +# + +use strict; + +use FindBin qw($Bin); +require "$Bin/Modules.pl"; +use vars qw(%Modules %Maintainers); + +use Getopt::Long; +use File::Find; + +sub usage { + print <<__EOF__; +$0: Usage: $0 [[--maintainer M --module M --files]|file ...] +$0 --maintainer M list all maintainers matching M +$0 --module M list all modules matching M +$0 --files list all files of the module +Matching is case-ignoring regexp, author matching is both by +the short id and by the full name and email. +$0 file ... list the module and maintainer +__EOF__ + exit(0); +} + +my $Maintainer; +my $Module; +my $Files; + +usage() + unless + GetOptions( + 'maintainer=s' => \$Maintainer, + 'module=s' => \$Module, + 'files' => \$Files, + ); + +my @Files = @ARGV; + +usage() if @Files && ($Maintainer || $Module || $Files); + +for my $mean ($Maintainer, $Module) { + warn "$0: Did you mean '$0 $mean'?\n" + if $mean && -e $mean && $mean ne '.'; +} + +warn "$0: Did you mean '$0 -mo $Maintainer'?\n" + if defined $Maintainer && exists $Modules{$Maintainer}; + +warn "$0: Did you mean '$0 -ma $Module'?\n" + if defined $Module && exists $Maintainers{$Module}; + +sub get_module_pat { + my $m = shift; + split ' ', $Modules{$m}{FILES}; +} + +sub get_module_files { + my $m = shift; + sort { lc $a cmp lc $b } + map { + -f $_ ? # Files as-is. + $_ : + -d _ ? # Recurse into directories. + do { + my @files; + find( + sub { + push @files, $File::Find::name + if -f $_; + }, $_); + @files; + } + : glob($_) # The rest are globbable patterns. + } get_module_pat($m); +} + +sub get_maintainer_modules { + my $m = shift; + sort { lc $a cmp lc $b } + grep { $Modules{$_}{MAINTAINER} eq $m } + keys %Modules; +} + +if ($Maintainer) { + for my $m (sort keys %Maintainers) { + if ($m =~ /$Maintainer/io) { + my @modules = get_maintainer_modules($m); + if ($Module) { + @modules = grep { /$Module/io } @modules; + } + if ($Files) { + my @files; + for my $module (@modules) { + push @files, get_module_files($module); + } + printf "%-15s @files\n", $m; + } else { + if ($Module) { + printf "%-15s @modules\n", $m; + } else { + printf "%-15s $Maintainers{$m}\n", $m; + } + } + } + } +} elsif ($Module) { + for my $m (sort { lc $a cmp lc $b } keys %Modules) { + if ($m =~ /$Module/io) { + if ($Files) { + my @files = get_module_files($m); + printf "%-15s @files\n", $m; + } else { + printf "%-15s $Modules{$m}{MAINTAINER}\n", $m; + } + } + } +} elsif (@Files) { + my %ModuleByFile; + + @ModuleByFile{@Files} = (); + + # First try fast match. + + my %ModuleByPat; + for my $module (keys %Modules) { + for my $pat (get_module_pat($module)) { + $ModuleByPat{$pat} = $module; + } + } + # Expand any globs. + my %ExpModuleByPat; + for my $pat (keys %ModuleByPat) { + if (-e $pat) { + $ExpModuleByPat{$pat} = $ModuleByPat{$pat}; + } else { + for my $exp (glob($pat)) { + $ExpModuleByPat{$exp} = $ModuleByPat{$pat}; + } + } + } + %ModuleByPat = %ExpModuleByPat; + for my $file (@Files) { + $ModuleByFile{$file} = $ModuleByPat{$file} + if exists $ModuleByPat{$file}; + } + + # If still unresolved files.. + if (my @ToDo = grep { !defined $ModuleByFile{$_} } keys %ModuleByFile) { + + # Cannot match what isn't there. + @ToDo = grep { -e $_ } @ToDo; + + if (@ToDo) { + # Try prefix matching. + + # Remove trailing slashes. + for (@ToDo) { s|/$|| } + + my %ToDo; + @ToDo{@ToDo} = (); + + for my $pat (keys %ModuleByPat) { + last unless keys %ToDo; + if (-d $pat) { + my @Done; + for my $file (keys %ToDo) { + if ($file =~ m|^$pat|i) { + $ModuleByFile{$file} = $ModuleByPat{$pat}; + push @Done, $file; + } + } + delete @ToDo{@Done}; + } + } + } + } + + for my $file (@Files) { + if (defined $ModuleByFile{$file}) { + my $module = $ModuleByFile{$file}; + my $maintainer = $Modules{$ModuleByFile{$file}}{MAINTAINER}; + printf "%-15s $module $maintainer $Maintainers{$maintainer}\n", $file; + } else { + printf "%-15s ?\n", $file; + } + } +} +else { + usage(); +} + diff --git a/Porting/Modules.pl b/Porting/Modules.pl new file mode 100644 index 0000000000..92691ad2b2 --- /dev/null +++ b/Porting/Modules.pl @@ -0,0 +1,446 @@ +# A simple listing of core modules that have specific maintainers. +# Most (but not all) of the modules have dual lives in the core and +# in CPAN. + +%Maintainers = + ( + 'ams' => 'Abhijit Menon-Sen <ams@cpan.org>', + 'andreas' => 'Andreas J. Koenig <andk@cpan.org>', + 'arthur' => 'Arthur Bergman <abergman@cpan.org>', + 'autarch' => 'Dave Rolsky <drolsky@cpan.org>', + 'bbb' => 'Rob Brown <bbb@cpan.org>', + 'damian' => 'Damian Conway <dconway@cpan.org>', + 'dankogai' => 'Dan Kogai <dankogai@cpan.org>', + 'gbarr' => 'Graham Barr <gbarr@cpan.org>', + 'gisle' => 'Gisle Aas <gaas@cpan.org>', + 'ilyam' => 'Ilya Martynov <ilyam@cpan.org>', + 'ilyaz' => 'Ilya Zakharevich <ilyaz@cpan.org>', + 'jhi' => 'Jarkko Hietaniemi <jhi@cpan.org>', + 'jns' => 'Jonathan Stowe <jstowe@cpan.org>', + 'jvromans' => 'Johan Vromans <jv@cpan.org>', + 'kenw' => 'Ken Williams <kwilliams@cpan.org>', + 'lstein' => 'Lincoln D. Stein <lds@cpan.org>', + 'marekr' => 'Marek Rouchal <marekr@cpan.org>', + 'mjd' => 'Mark-Jason Dominus <mjd@cpan.org>', + 'muir' => 'David Muir Sharnoff <muir@cpan.org>', + 'neilb' => 'Neil Bowers <neilb@cpan.org>', + 'p5p' => 'perl5-porters <perl5-porters@perl.org>', + 'petdance' => 'Andy Lester <petdance@cpan.org>', + 'pmarquess' => 'Paul Marquess <pmqs@cpan.org>', + 'rmbarker' => 'Robin Barker <rmbarker@cpan.org>', + 'rra' => 'Russ Allbery <rra@cpan.org>', + 'sadahiro' => 'SADAHIRO Tomoyuki <SADAHIRO@cpan.org>', + 'sburke' => 'Sean Burke <sburke@cpan.org>', + 'schwern' => 'Michael Schwern <schwern@cpan.org>', + 'smcc' => 'Stephen McCamant <smccam@cpan.org>', + 'tels' => 'perl_dummy a-t bloodgate.com', + 'tjenness' => 'Tim Jenness <tjenness@cpan.org>' + ); + +# The FILES is either filenames, or glob patterns, or directory +# names to be recursed down. The CPAN can be either 1 (get the +# latest one from CPAN) or 0 (there is no valid CPAN release). + +%Modules = ( + + 'Attribute::Handlers' => + { + 'MAINTAINER' => 'arthur', + 'FILES' => + q[lib/Attribute/Handlers.pm lib/Attribute/Handlers], + 'CPAN' => 1, + }, + + 'B::Concise' => + { + 'MAINTAINER' => 'smcc', + 'FILES' => q[ext/B/B/Concise.pm ext/B/t/concise.t], + 'CPAN' => 0, + }, + + 'bignum' => + { + 'MAINTAINER' => 'tels', + 'FILES' => q[lib/big{int,num,rat}.pm lib/bignum], + 'CPAN' => 1, + }, + + 'CGI' => + { + 'MAINTAINER' => 'lstein', + 'FILES' => q[lib/CGI.pm lib/CGI], + 'CPAN' => 1, + }, + + 'Class::ISA' => + { + 'MAINTAINER' => 'sburke', + 'FILES' => q[lib/Class/ISA.pm lib/Class/ISA], + 'CPAN' => 1, + }, + + 'CPAN' => + { + 'MAINTAINER' => 'andreas', + 'FILES' => q[lib/CPAN.pm lib/CPAN], + 'CPAN' => 1, + }, + + 'Data::Dumper' => + { + 'MAINTAINER' => 'ilyam', # Not gsar. + 'FILES' => q[ext/Data/Dumper], + 'CPAN' => 1, + }, + + 'DB::File' => + { + 'MAINTAINER' => 'pmarquess', + 'FILES' => q[ext/DB_File], + 'CPAN' => 1, + }, + + 'Devel::PPPort' => + { + 'MAINTAINER' => 'pmarquess', + 'FILES' => q[ext/Devel/PPPort], + 'CPAN' => 1, + }, + + 'Digest' => + { + 'MAINTAINER' => 'gisle', + 'FILES' => q[lib/Digest.{pm,t}], + 'CPAN' => 1, + }, + + 'Digest::MD5' => + { + 'MAINTAINER' => 'gisle', + 'FILES' => q[ext/Digest/MD5], + 'CPAN' => 1, + }, + + 'Encode' => + { + 'MAINTAINER' => 'dankogai', + 'FILES' => q[ext/Encode], + 'CPAN' => 1, + }, + + 'Errno' => + { + 'MAINTAINER' => 'p5p', # Not gbarr. + 'FILES' => q[ext/Data/Dumper], + 'CPAN' => 0, + }, + + 'ExtUtils::MakeMaker' => + { + 'MAINTAINER' => 'schwern', + 'FILES' => q[lib/ExtUtils/{Command,Install,Installed,Liblist,MakeMaker,Manifest,Mkbootstrap,Mksymlists,MM*,MY,Packlist,testlib}.pm lib/ExtUtils/{Command,Liblist,MakeMaker} + lib/ExtUtils/t t/lib/MakeMaker t/lib/TieIn.pm t/lib/TieOut.pm], + 'CPAN' => 1, + }, + + 'File::Spec' => + { + 'MAINTAINER' => 'kenw', + 'FILES' => q[lib/File/Spec.pm lib/File/Spec], + 'CPAN' => 1, + }, + + 'File::Temp' => + { + 'MAINTAINER' => 'tjenness', + 'FILES' => q[lib/File/Temp.pm lib/File/Temp], + 'CPAN' => 1, + }, + + 'Filter::Simple' => + { + 'MAINTAINER' => 'damian', + 'FILES' => q[lib/Filter/Simple.pm lib/Filter/Simple], + 'CPAN' => 1, + }, + + 'Filter::Util::Call' => + { + 'MAINTAINER' => 'pmarquess', + 'FILES' => q[ext/Filter/Util/Call], + 'CPAN' => 1, + }, + + 'Getopt::Long' => + { + 'MAINTAINER' => 'jvromans', + 'FILES' => q[lib/Getopt/Long.pm lib/Getopt/Long], + 'CPAN' => 1, + }, + + 'I18N::LangTags' => + { + 'MAINTAINER' => 'sburke', + 'FILES' => q[lib/I18N/LangTags.pm lib/I18N/LangTags], + 'CPAN' => 1, + }, + + 'if' => + { + 'MAINTAINER' => 'ilyaz', + 'FILES' => q[lib/if.{pm,t}], + 'CPAN' => 1, + }, + + 'IO' => + { + 'MAINTAINER' => 'p5p', # Not gbarr. + 'FILES' => q[ext/Data/Dumper], + 'CPAN' => 0, + }, + + 'libnet' => + { + 'MAINTAINER' => 'gbarr', + 'FILES' => + q[lib/Net/{Cmd,Config,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], + 'CPAN' => 1, + }, + + 'Scalar-List-Util' => + { + 'MAINTAINER' => 'gbarr', + 'FILES' => q[ext/List/Util], + 'CPAN' => 1, + }, + + 'Locale::Codes' => + { + 'MAINTAINER' => 'neilb', + 'FILES' => q[lib/Locale/{Codes,Constants,Country,Currency,Language,Script}*], + 'CPAN' => 1, + }, + + 'Locale::Maketext' => + { + 'MAINTAINER' => 'sburke', + 'FILES' => q[lib/Locale/Maketext.pm lib/Locale/Maketext], + 'CPAN' => 1, + }, + + 'Math::BigFloat' => + { + 'MAINTAINER' => 'tels', + 'FILES' => q[lib/Math/BigFloat.pm lib/Math/BigFloat], + 'CPAN' => 1, + }, + + 'Math::BigInt' => + { + 'MAINTAINER' => 'tels', + 'FILES' => q[lib/Math/BigInt.pm lib/Math/BigInt], + 'CPAN' => 1, + }, + + 'Math::BigRat' => + { + 'MAINTAINER' => 'tels', + 'FILES' => q[lib/Math/BigRat.pm lib/Math/BigRat], + 'CPAN' => 1, + }, + + 'Memoize' => + { + 'MAINTAINER' => 'mjd', + 'FILES' => q[lib/Memoize.pm lib/Memoize], + 'CPAN' => 1, + }, + + 'MIME::Base64' => + { + 'MAINTAINER' => 'gisle', + 'FILES' => q[ext/MIME/Base64], + 'CPAN' => 1, + }, + + 'Net::Ping' => + { + 'MAINTAINER' => 'bbb', + 'FILES' => q[lib/Net/Ping.pm lib/Net/Ping], + 'CPAN' => 1, + }, + + 'NEXT' => + { + 'MAINTAINER' => 'damian', + 'FILES' => q[lib/NEXT.pm lib/NEXT], + 'CPAN' => 1, + }, + + 'PerlIO' => + { + 'MAINTAINER' => 'p5p', + 'FILES' => q[ext/PerlIO lib/PerlIO], + 'CPAN' => 1, + }, + + 'Pod::Find' => + { + 'MAINTAINER' => 'marekr', + 'FILES' => q[lib/Pod/Find.pm t/pod/find.t], + 'CPAN' => 1, + }, + + 'Pod::LaTeX' => + { + 'MAINTAINER' => 'tjenness', + 'FILES' => q[lib/Pod/LaTeX.pm lib/Pod/t/pod2latex.t], + 'CPAN' => 1, + }, + + 'podlators' => + { + 'MAINTAINER' => 'rra', + 'FILES' => q[lib/Pod/{Checker,Find,Html,InputObjects,Man,ParseLink,Parser,ParseUtils,PlainText,Select,Text,Text/{Color,Overstrike,Termcap},Usage}.pm pod/pod2man.PL pod/pod2text.PL lib/Pod/t/{basic.*,{basic,man,parselink,text*}.t}], + 'CPAN' => 1, + }, + + 'Pod::Perldoc' => + { + 'MAINTAINER' => 'sburke', + 'FILES' => q[lib/Pod/Perldoc.pm], + 'CPAN' => 1, + }, + + 'Pod::Plainer' => + { + 'MAINTAINER' => 'rmbarker', + 'FILES' => q[lib/Pod/Plainer.pm], + 'CPAN' => 1, + }, + + 'Storable' => + { + 'MAINTAINER' => 'ams', + 'FILES' => q[ext/Storable], + 'CPAN' => 1, + }, + + 'Switch' => + { + 'MAINTAINER' => 'damian', + 'FILES' => q[lib/Switch.pm lib/Switch], + 'CPAN' => 1, + }, + + 'TabsWrap' => + { + 'MAINTAINER' => 'muir', + 'FILES' => + q[lib/Text/{Tabs,Wrap}.pm lib/Text/TabsWrap], + 'CPAN' => 1, + }, + + 'Text::Balanced' => + { + 'MAINTAINER' => 'damian', + 'FILES' => q[lib/Text/Balanced.pm lib/Text/Balanced], + 'CPAN' => 1, + }, + + 'Term::ANSIColor' => + { + 'MAINTAINER' => 'rra', + 'FILES' => q[lib/Term/ANSIColor.pm lib/Term/ANSIColor], + }, + + 'Test::Builder' => + { + 'MAINTAINER' => 'schwern', + 'FILES' => q[lib/Test/Builder.pm], + }, + + 'Test::Harness' => + { + 'MAINTAINER' => 'petdance', + 'FILES' => q[lib/Test/Harness.pm lib/Test/Harness], + 'CPAN' => 1, + }, + + 'Test::More' => + { + 'MAINTAINER' => 'schwern', + 'FILES' => q[lib/Test/More.pm], + 'CPAN' => 1, + }, + + 'Test::Simple' => + { + 'MAINTAINER' => 'schwern', + 'FILES' => q[lib/Test/Simple.pm lib/Test/Simple], + 'CPAN' => 1, + }, + + 'Term::Cap' => + { + 'MAINTAINER' => 'jns', + 'FILES' => q[lib/Term/Cap.{pm,t}], + 'CPAN' => 1, + }, + + + 'threads' => + { + 'MAINTAINER' => 'arthur', + 'FILES' => q[ext/threads], + 'CPAN' => 1, + }, + + 'Tie::File' => + { + 'MAINTAINER' => 'mjd', + 'FILES' => q[lib/Tie/File.pm lib/Tie/File], + 'CPAN' => 1, + }, + + 'Time::HiRes' => + { + 'MAINTAINER' => 'jhi', + 'FILES' => q[ext/Time/HiRes], + 'CPAN' => 1, + }, + + 'Time::Local' => + { + 'MAINTAINER' => 'autarch', + 'FILES' => q[lib/Time/Local.{pm,t}], + 'CPAN' => 1, + }, + + 'Unicode::Collate' => + { + 'MAINTAINER' => 'sadahiro', + 'FILES' => + q[lib/Unicode/Collate.pm lib/Unicode/Collate], + 'CPAN' => 1, + }, + + 'Unicode::Normalize' => + { + 'MAINTAINER' => 'sadahiro', + 'FILES' => q[ext/Unicode/Normalize], + 'CPAN' => 1, + }, + + 'warnings' => + { + 'MAINTAINER' => 'pmarquess', + 'FILES' => + q[warnings.pl lib/warnings.{pm,t} + lib/warnings t/lib/warnings], + 'CPAN' => 1, + }, + + ); + +1; |