This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
d5dac05b9550a83ba0b2a631954c3567028ea2ce
[perl5.git] / dist / Module-CoreList / corelist
1 #!/usr/bin/perl
2
3 =head1 NAME
4
5 corelist - a commandline frontend to Module::CoreList
6
7 =head1 DESCRIPTION
8
9 See L<Module::CoreList> for one.
10
11 =head1 SYNOPSIS
12
13     corelist -v
14     corelist [-a|-d] <ModuleName> | /<ModuleRegex>/ [<ModuleVersion>] ...
15     corelist [-v <PerlVersion>] [ <ModuleName> | /<ModuleRegex>/ ] ...
16     corelist [-r <PerlVersion>] ...
17
18 =head1 OPTIONS
19
20 =over
21
22 =item -a
23
24 lists all versions of the given module (or the matching modules, in case you
25 used a module regexp) in the perls Module::CoreList knows about.
26
27     corelist -a Unicode
28
29     Unicode was first released with perl v5.6.2
30       v5.6.2     3.0.1
31       v5.8.0     3.2.0
32       v5.8.1     4.0.0
33       v5.8.2     4.0.0
34       v5.8.3     4.0.0
35       v5.8.4     4.0.1
36       v5.8.5     4.0.1
37       v5.8.6     4.0.1
38       v5.8.7     4.1.0
39       v5.8.8     4.1.0
40       v5.8.9     5.1.0
41       v5.9.0     4.0.0
42       v5.9.1     4.0.0
43       v5.9.2     4.0.1
44       v5.9.3     4.1.0
45       v5.9.4     4.1.0
46       v5.9.5     5.0.0
47       v5.10.0    5.0.0
48       v5.10.1    5.1.0
49       v5.11.0    5.1.0
50       v5.11.1    5.1.0
51       v5.11.2    5.1.0
52       v5.11.3    5.2.0
53       v5.11.4    5.2.0
54       v5.11.5    5.2.0
55       v5.12.0    5.2.0
56       v5.12.1    5.2.0
57       v5.12.2    5.2.0
58       v5.12.3    5.2.0
59       v5.12.4    5.2.0
60       v5.13.0    5.2.0
61       v5.13.1    5.2.0
62       v5.13.2    5.2.0
63       v5.13.3    5.2.0
64       v5.13.4    5.2.0
65       v5.13.5    5.2.0
66       v5.13.6    5.2.0
67       v5.13.7    6.0.0
68       v5.13.8    6.0.0
69       v5.13.9    6.0.0
70       v5.13.10   6.0.0
71       v5.13.11   6.0.0
72       v5.14.0    6.0.0
73       v5.14.1    6.0.0
74       v5.15.0    6.0.0
75
76 =item -d
77
78 finds the first perl version where a module has been released by
79 date, and not by version number (as is the default).
80
81 =item -? or -help
82
83 help! help! help! to see more help, try --man.
84
85 =item -man
86
87 all of the help
88
89 =item -v
90
91 lists all of the perl release versions we got the CoreList for.
92
93 If you pass a version argument (value of C<$]>, like C<5.00503> or C<5.008008>),
94 you get a list of all the modules and their respective versions.
95 (If you have the C<version> module, you can also use new-style version numbers,
96 like C<5.8.8>.)
97
98 In module filtering context, it can be used as Perl version filter.
99
100 =item -r
101
102 lists all of the perl releases and when they were released
103
104 If you pass a perl version you get the release date for that version only.
105
106 =back
107
108 As a special case, if you specify the module name C<Unicode>, you'll get
109 the version number of the Unicode Character Database bundled with the
110 requested perl versions.
111
112 =cut
113
114 use Module::CoreList;
115 use Getopt::Long;
116 use Pod::Usage;
117 use strict;
118 use warnings;
119
120 my %Opts;
121
122 GetOptions(\%Opts, qw[ help|?! man! r|release:s v|version:s a! d ] );
123
124 pod2usage(1) if $Opts{help};
125 pod2usage(-verbose=>2) if $Opts{man};
126
127 if(exists $Opts{r} ){
128     if ( !$Opts{r} ) {
129         print "\nModule::CoreList has release info for the following perl versions:\n";
130         my $versions = { };
131         my $max_ver_len = max_mod_len(\%Module::CoreList::released);
132         for my $ver ( sort keys %Module::CoreList::released ) {
133           printf "%-${max_ver_len}s    %s\n", format_perl_version($ver), $Module::CoreList::released{$ver};
134         }
135         print "\n";
136         exit 0;
137     }
138
139     my $num_r = numify_version( $Opts{r} );
140     my $version_hash = Module::CoreList->find_version($num_r);
141
142     if( !$version_hash ) {
143         print "\nModule::CoreList has no info on perl $Opts{r}\n\n";
144         exit 1;
145     }
146
147     printf "Perl %s was released on %s\n\n", format_perl_version($num_r), $Module::CoreList::released{$num_r};
148     exit 0;
149 }
150
151 if(exists $Opts{v} ){
152     if( !$Opts{v} ) {
153         print "\nModule::CoreList has info on the following perl versions:\n";
154         print format_perl_version($_)."\n" for sort keys %Module::CoreList::version;
155         print "\n";
156         exit 0;
157     }
158
159     my $num_v = numify_version( $Opts{v} );
160     my $version_hash = Module::CoreList->find_version($num_v);
161
162     if( !$version_hash ) {
163         print "\nModule::CoreList has no info on perl $Opts{v}\n\n";
164         exit 1;
165     }
166
167     if ( !@ARGV ) {
168         print "\nThe following modules were in perl $Opts{v} CORE\n";
169         my $max_mod_len = max_mod_len($version_hash);
170         for my $mod ( sort keys %$version_hash ) {
171             printf "%-${max_mod_len}s  %s\n", $mod, $version_hash->{$mod} || "";
172         }
173         print "\n";
174         exit 0;
175     }
176 }
177
178 if ( !@ARGV ) {
179     pod2usage(0);
180 }
181
182 while (@ARGV) {
183         my ($mod, $ver);
184         if ($ARGV[0] =~ /=/) {
185             ($mod, $ver) = split /=/, shift @ARGV;
186         } else {
187             $mod = shift @ARGV;
188             $ver = (@ARGV && $ARGV[0] =~ /^\d/) ? shift @ARGV : "";
189         }
190
191         if ($mod !~ m|^/(.*)/([imosx]*)$|) { # not a regex
192             module_version($mod,$ver);
193         } else {
194             my $re;
195             eval { $re = $2 ? qr/(?$2)($1)/ : qr/$1/; }; # trap exceptions while building regex
196             if ($@) {
197                 # regex errors are usually like 'Quantifier follow nothing in regex; marked by ...'
198                 # then we drop text after ';' to shorten message
199                 my $errmsg = $@ =~ /(.*);/ ? $1 : $@;
200                 warn "\n$mod  is a bad regex: $errmsg\n";
201                 next;
202             }
203             my @mod = Module::CoreList->find_modules($re);
204             if (@mod) {
205                 module_version($_, $ver) for @mod;
206             } else {
207                 $ver |= '';
208                 print "\n$mod $ver has no match in CORE (or so I think)\n";
209             }
210
211         }
212 }
213
214 exit();
215
216 sub module_version {
217     my($mod,$ver) = @_;
218
219     if ( $Opts{v} ) {
220         my $numeric_v = numify_version($Opts{v});
221         my $version_hash = Module::CoreList->find_version($numeric_v);
222         if ($version_hash) {
223             print $mod, " ", $version_hash->{$mod} || 'undef', "\n";
224             return;
225         }
226         else { die "Shouldn't happen" }
227     }
228
229     my $ret = $Opts{d}
230         ? Module::CoreList->first_release_by_date(@_)
231         : Module::CoreList->first_release(@_);
232     my $msg = $mod;
233     $msg .= " $ver" if $ver;
234
235     my $rem = $Opts{d}
236         ? Module::CoreList->removed_from_by_date($mod)
237         : Module::CoreList->removed_from($mod);
238
239     if( defined $ret ) {
240         $msg .= " was ";
241         $msg .= "first " unless $ver;
242         $msg .= "released with perl " . format_perl_version($ret);
243         $msg .= " and removed from " . format_perl_version($rem) if $rem;
244     } else {
245         $msg .= " was not in CORE (or so I think)";
246     }
247
248     print "\n",$msg,"\n";
249
250     if(defined $ret and exists $Opts{a} and $Opts{a}){
251         display_a($mod);
252     }
253 }
254
255
256 sub max_mod_len {
257     my $versions = shift;
258     my $max = 0;
259     for my $mod (keys %$versions) {
260         $max = max($max, length $mod);
261     }
262
263     return $max;
264 }
265
266 sub max {
267     my($this, $that) = @_;
268     return $this if $this > $that;
269     return $that;
270 }
271
272 sub display_a {
273     my $mod = shift;
274
275     for my $v (grep !/000$/, sort keys %Module::CoreList::version ) {
276         next unless exists $Module::CoreList::version{$v}{$mod};
277
278         my $mod_v = $Module::CoreList::version{$v}{$mod} || 'undef';
279         printf "  %-10s %-10s\n", format_perl_version($v), $mod_v;
280     }
281     print "\n";
282 }
283
284
285 {
286     my $have_version_pm;
287     sub have_version_pm {
288         return $have_version_pm if defined $have_version_pm;
289         return $have_version_pm = eval { require version; 1 };
290     }
291 }
292
293
294 sub format_perl_version {
295     my $v = shift;
296     return $v if $v < 5.006 or !have_version_pm;
297     return version->new($v)->normal;
298 }
299
300
301 sub numify_version {
302     my $ver = shift;
303     if ($ver =~ /\..+\./) {
304         have_version_pm()
305             or die "You need to install version.pm to use dotted version numbers\n";
306         $ver = version->new($ver)->numify;
307     }
308     $ver += 0;
309     return $ver;
310 }
311
312 =head1 EXAMPLES
313
314     $ corelist File::Spec
315
316     File::Spec was first released with perl 5.005
317
318     $ corelist File::Spec 0.83
319
320     File::Spec 0.83 was released with perl 5.007003
321
322     $ corelist File::Spec 0.89
323
324     File::Spec 0.89 was not in CORE (or so I think)
325
326     $ corelist File::Spec::Aliens
327
328     File::Spec::Aliens  was not in CORE (or so I think)
329
330     $ corelist /IPC::Open/
331
332     IPC::Open2 was first released with perl 5
333
334     IPC::Open3 was first released with perl 5
335
336     $ corelist /MANIFEST/i
337
338     ExtUtils::Manifest was first released with perl 5.001
339
340     $ corelist /Template/
341
342     /Template/  has no match in CORE (or so I think)
343
344     $ corelist -v 5.8.8 B
345
346     B                        1.09_01
347
348     $ corelist -v 5.8.8 /^B::/
349
350     B::Asmdata               1.01
351     B::Assembler             0.07
352     B::Bblock                1.02_01
353     B::Bytecode              1.01_01
354     B::C                     1.04_01
355     B::CC                    1.00_01
356     B::Concise               0.66
357     B::Debug                 1.02_01
358     B::Deparse               0.71
359     B::Disassembler          1.05
360     B::Lint                  1.03
361     B::O                     1.00
362     B::Showlex               1.02
363     B::Stackobj              1.00
364     B::Stash                 1.00
365     B::Terse                 1.03_01
366     B::Xref                  1.01
367
368 =head1 COPYRIGHT
369
370 Copyright (c) 2002-2007 by D.H. aka PodMaster
371
372 Currently maintained by the perl 5 porters E<lt>perl5-porters@perl.orgE<gt>.
373
374 This program is distributed under the same terms as perl itself.
375 See http://perl.org/ or http://cpan.org/ for more info on that.
376
377 =cut