4 # Maintainers - show information about maintainers
10 require "$Bin/Maintainers.pl";
11 use vars qw(%Modules %Maintainers);
18 $0: Usage: $0 [[--maintainer M --module M --files]|file ...]
19 --maintainer M list all maintainers matching M
20 --module M list all modules matching M
21 --files list all files
22 Matching is case-ignoring regexp, author matching is both by
23 the short id and by the full name and email. A "module" may
24 not be just a module, it may be a file or files or a subdirectory.
25 The options may be abbreviated to their unique prefixes
37 'maintainer=s' => \$Maintainer,
38 'module=s' => \$Module,
44 usage() if @Files && ($Maintainer || $Module || $Files);
46 for my $mean ($Maintainer, $Module) {
47 warn "$0: Did you mean '$0 $mean'?\n"
48 if $mean && -e $mean && $mean ne '.' && !$Files;
51 warn "$0: Did you mean '$0 -mo $Maintainer'?\n"
52 if defined $Maintainer && exists $Modules{$Maintainer};
54 warn "$0: Did you mean '$0 -ma $Module'?\n"
55 if defined $Module && exists $Maintainers{$Module};
59 split ' ', $Modules{$m}{FILES};
62 sub get_module_files {
64 sort { lc $a cmp lc $b }
66 -f $_ ? # Files as-is.
68 -d _ ? # Recurse into directories.
73 push @files, $File::Find::name
78 : glob($_) # The rest are globbable patterns.
82 sub get_maintainer_modules {
84 sort { lc $a cmp lc $b }
85 grep { $Modules{$_}{MAINTAINER} eq $m }
90 for my $m (sort keys %Maintainers) {
91 if ($m =~ /$Maintainer/io || $Maintainers{$m} =~ /$Maintainer/io) {
92 my @modules = get_maintainer_modules($m);
94 @modules = grep { /$Module/io } @modules;
98 for my $module (@modules) {
99 push @files, get_module_files($module);
101 printf "%-15s @files\n", $m;
104 printf "%-15s @modules\n", $m;
106 printf "%-15s $Maintainers{$m}\n", $m;
112 for my $m (sort { lc $a cmp lc $b } keys %Modules) {
113 if ($m =~ /$Module/io) {
115 my @files = get_module_files($m);
116 printf "%-15s @files\n", $m;
118 printf "%-15s $Modules{$m}{MAINTAINER}\n", $m;
125 for (@Files) { s:^\./:: }
127 @ModuleByFile{@Files} = ();
129 # First try fast match.
132 for my $module (keys %Modules) {
133 for my $pat (get_module_pat($module)) {
134 $ModuleByPat{$pat} = $module;
139 for my $pat (keys %ModuleByPat) {
141 $ExpModuleByPat{$pat} = $ModuleByPat{$pat};
143 for my $exp (glob($pat)) {
144 $ExpModuleByPat{$exp} = $ModuleByPat{$pat};
148 %ModuleByPat = %ExpModuleByPat;
149 for my $file (@Files) {
150 $ModuleByFile{$file} = $ModuleByPat{$file}
151 if exists $ModuleByPat{$file};
154 # If still unresolved files..
155 if (my @ToDo = grep { !defined $ModuleByFile{$_} } keys %ModuleByFile) {
157 # Cannot match what isn't there.
158 @ToDo = grep { -e $_ } @ToDo;
161 # Try prefix matching.
163 # Remove trailing slashes.
164 for (@ToDo) { s|/$|| }
169 for my $pat (keys %ModuleByPat) {
170 last unless keys %ToDo;
173 for my $file (keys %ToDo) {
174 if ($file =~ m|^$pat|i) {
175 $ModuleByFile{$file} = $ModuleByPat{$pat};
185 for my $file (@Files) {
186 if (defined $ModuleByFile{$file}) {
187 my $module = $ModuleByFile{$file};
188 my $maintainer = $Modules{$ModuleByFile{$file}}{MAINTAINER};
189 printf "%-15s $module $maintainer $Maintainers{$maintainer}\n", $file;
191 printf "%-15s ?\n", $file;