Rename Modules and Modules.pl as Maintainers and
[p5sagit/p5-mst-13.2.git] / Porting / Maintainers
CommitLineData
b128a327 1#!/usr/bin/perl -w
2
3#
c9fe4ea1 4# Maintainers - show information about maintainers
b128a327 5#
6
7use strict;
8
9use FindBin qw($Bin);
c9fe4ea1 10require "$Bin/Maintainers.pl";
b128a327 11use vars qw(%Modules %Maintainers);
12
13use Getopt::Long;
14use File::Find;
15
16sub usage {
17 print <<__EOF__;
18$0: Usage: $0 [[--maintainer M --module M --files]|file ...]
19$0 --maintainer M list all maintainers matching M
20$0 --module M list all modules matching M
21$0 --files list all files of the module
22Matching is case-ignoring regexp, author matching is both by
c9fe4ea1 23the short id and by the full name and email. A "module" may
24not be just a module, it may be a file or files or a subdirectory.
25$0 file ... list the modules and maintainers of the files
b128a327 26__EOF__
27 exit(0);
28}
29
30my $Maintainer;
31my $Module;
32my $Files;
33
34usage()
35 unless
36 GetOptions(
37 'maintainer=s' => \$Maintainer,
38 'module=s' => \$Module,
39 'files' => \$Files,
40 );
41
42my @Files = @ARGV;
43
44usage() if @Files && ($Maintainer || $Module || $Files);
45
46for my $mean ($Maintainer, $Module) {
47 warn "$0: Did you mean '$0 $mean'?\n"
48 if $mean && -e $mean && $mean ne '.';
49}
50
51warn "$0: Did you mean '$0 -mo $Maintainer'?\n"
52 if defined $Maintainer && exists $Modules{$Maintainer};
53
54warn "$0: Did you mean '$0 -ma $Module'?\n"
55 if defined $Module && exists $Maintainers{$Module};
56
57sub get_module_pat {
58 my $m = shift;
59 split ' ', $Modules{$m}{FILES};
60}
61
62sub get_module_files {
63 my $m = shift;
64 sort { lc $a cmp lc $b }
65 map {
66 -f $_ ? # Files as-is.
67 $_ :
68 -d _ ? # Recurse into directories.
69 do {
70 my @files;
71 find(
72 sub {
73 push @files, $File::Find::name
74 if -f $_;
75 }, $_);
76 @files;
77 }
78 : glob($_) # The rest are globbable patterns.
79 } get_module_pat($m);
80}
81
82sub get_maintainer_modules {
83 my $m = shift;
84 sort { lc $a cmp lc $b }
85 grep { $Modules{$_}{MAINTAINER} eq $m }
86 keys %Modules;
87}
88
89if ($Maintainer) {
90 for my $m (sort keys %Maintainers) {
91 if ($m =~ /$Maintainer/io) {
92 my @modules = get_maintainer_modules($m);
93 if ($Module) {
94 @modules = grep { /$Module/io } @modules;
95 }
96 if ($Files) {
97 my @files;
98 for my $module (@modules) {
99 push @files, get_module_files($module);
100 }
101 printf "%-15s @files\n", $m;
102 } else {
103 if ($Module) {
104 printf "%-15s @modules\n", $m;
105 } else {
106 printf "%-15s $Maintainers{$m}\n", $m;
107 }
108 }
109 }
110 }
111} elsif ($Module) {
112 for my $m (sort { lc $a cmp lc $b } keys %Modules) {
113 if ($m =~ /$Module/io) {
114 if ($Files) {
115 my @files = get_module_files($m);
116 printf "%-15s @files\n", $m;
117 } else {
118 printf "%-15s $Modules{$m}{MAINTAINER}\n", $m;
119 }
120 }
121 }
122} elsif (@Files) {
123 my %ModuleByFile;
124
99a7b1fa 125 for (@Files) { s:^\./:: }
126
b128a327 127 @ModuleByFile{@Files} = ();
128
129 # First try fast match.
130
131 my %ModuleByPat;
132 for my $module (keys %Modules) {
133 for my $pat (get_module_pat($module)) {
134 $ModuleByPat{$pat} = $module;
135 }
136 }
137 # Expand any globs.
138 my %ExpModuleByPat;
139 for my $pat (keys %ModuleByPat) {
140 if (-e $pat) {
141 $ExpModuleByPat{$pat} = $ModuleByPat{$pat};
142 } else {
143 for my $exp (glob($pat)) {
144 $ExpModuleByPat{$exp} = $ModuleByPat{$pat};
145 }
146 }
147 }
148 %ModuleByPat = %ExpModuleByPat;
149 for my $file (@Files) {
150 $ModuleByFile{$file} = $ModuleByPat{$file}
151 if exists $ModuleByPat{$file};
152 }
153
154 # If still unresolved files..
155 if (my @ToDo = grep { !defined $ModuleByFile{$_} } keys %ModuleByFile) {
156
157 # Cannot match what isn't there.
158 @ToDo = grep { -e $_ } @ToDo;
159
160 if (@ToDo) {
161 # Try prefix matching.
162
163 # Remove trailing slashes.
164 for (@ToDo) { s|/$|| }
165
166 my %ToDo;
167 @ToDo{@ToDo} = ();
168
169 for my $pat (keys %ModuleByPat) {
170 last unless keys %ToDo;
171 if (-d $pat) {
172 my @Done;
173 for my $file (keys %ToDo) {
174 if ($file =~ m|^$pat|i) {
175 $ModuleByFile{$file} = $ModuleByPat{$pat};
176 push @Done, $file;
177 }
178 }
179 delete @ToDo{@Done};
180 }
181 }
182 }
183 }
184
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;
190 } else {
191 printf "%-15s ?\n", $file;
192 }
193 }
194}
195else {
196 usage();
197}
198