This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Math::BigInt to CPAN version 1.993
[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
17 =head1 OPTIONS
18
19 =over
20
21 =item -a
22
23 lists all versions of the given module (or the matching modules, in case you
24 used a module regexp) in the perls Module::CoreList knows about.
25
26     corelist -a utf8
27
28     utf8 was first released with perl 5.006
29       5.006      undef
30       5.006001   undef
31       5.006002   undef
32       5.007003   1.00
33       5.008      1.00
34       5.008001   1.02
35       5.008002   1.02
36       5.008003   1.02
37       5.008004   1.03
38       5.008005   1.04
39       5.008006   1.04
40       5.008007   1.05
41       5.008008   1.06
42       5.009      1.02
43       5.009001   1.02
44       5.009002   1.04
45       5.009003   1.06
46
47 =item -d
48
49 finds the first perl version where a module has been released by
50 date, and not by version number (as is the default).
51
52 =item -? or -help
53
54 help! help! help! to see more help, try --man.
55
56 =item -man
57
58 all of the help
59
60 =item -v
61
62 lists all of the perl release versions we got the CoreList for.
63
64 If you pass a version argument (value of C<$]>, like C<5.00503> or C<5.008008>),
65 you get a list of all the modules and their respective versions.
66 (If you have the C<version> module, you can also use new-style version numbers,
67 like C<5.8.8>.)
68
69 In module filtering context, it can be used as Perl version filter.
70
71 =back
72
73 As a special case, if you specify the module name C<Unicode>, you'll get
74 the version number of the Unicode Character Database bundled with the
75 requested perl versions.
76
77 =cut
78
79 use Module::CoreList;
80 use Getopt::Long;
81 use Pod::Usage;
82 use strict;
83 use warnings;
84
85 my %Opts;
86
87 GetOptions(\%Opts, qw[ help|?! man! v|version:s a! d ] );
88
89 pod2usage(1) if $Opts{help};
90 pod2usage(-verbose=>2) if $Opts{man};
91
92 if(exists $Opts{v} ){
93     if( !$Opts{v} ) {
94         print "\nModule::CoreList has info on the following perl versions:\n";
95         print format_perl_version($_)."\n" for sort keys %Module::CoreList::version;
96         print "\n";
97         exit 0;
98     }
99
100     my $num_v = numify_version( $Opts{v} );
101     my $version_hash = Module::CoreList->find_version($num_v);
102
103     if( !$version_hash ) {
104         print "\nModule::CoreList has no info on perl $Opts{v}\n\n";
105         exit 1;
106     }
107
108     if ( !@ARGV ) {
109         print "\nThe following modules were in perl $Opts{v} CORE\n";
110         my $max_mod_len = max_mod_len($version_hash);
111         for my $mod ( sort keys %$version_hash ) {
112             printf "%-${max_mod_len}s  %s\n", $mod, $version_hash->{$mod} || "";
113         }
114         print "\n";
115         exit 0;
116     }
117 }
118
119 if ( !@ARGV ) {
120     pod2usage(0);
121 }
122
123 while (@ARGV) {
124         my ($mod, $ver);
125         if ($ARGV[0] =~ /=/) {
126             ($mod, $ver) = split /=/, shift @ARGV;
127         } else {
128             $mod = shift @ARGV;
129             $ver = (@ARGV && $ARGV[0] =~ /^\d/) ? shift @ARGV : "";
130         }
131
132         if ($mod !~ m|^/(.*)/([imosx]*)$|) { # not a regex
133             module_version($mod,$ver);
134         } else {
135             my $re;
136             eval { $re = $2 ? qr/(?$2)($1)/ : qr/$1/; }; # trap exceptions while building regex
137             if ($@) {
138                 # regex errors are usually like 'Quantifier follow nothing in regex; marked by ...'
139                 # then we drop text after ';' to shorten message
140                 my $errmsg = $@ =~ /(.*);/ ? $1 : $@;
141                 warn "\n$mod  is a bad regex: $errmsg\n";
142                 next;
143             }
144             my @mod = Module::CoreList->find_modules($re);
145             if (@mod) {
146                 module_version($_, $ver) for @mod;
147             } else {
148                 $ver |= '';
149                 print "\n$mod $ver has no match in CORE (or so I think)\n";
150             }
151
152         }
153 }
154
155 exit();
156
157 sub module_version {
158     my($mod,$ver) = @_;
159
160     if ( $Opts{v} ) {
161         my $numeric_v = numify_version($Opts{v});
162         my $version_hash = Module::CoreList->find_version($numeric_v);
163         if ($version_hash) {
164             print $mod, " ", $version_hash->{$mod} || 'undef', "\n";
165             return;
166         }
167         else { die "Shouldn't happen" }
168     }
169
170     my $ret = $Opts{d}
171         ? Module::CoreList->first_release_by_date(@_)
172         : Module::CoreList->first_release(@_);
173     my $msg = $mod;
174     $msg .= " $ver" if $ver;
175
176     my $rem = $Opts{d}
177         ? Module::CoreList->removed_from_by_date($mod)
178         : Module::CoreList->removed_from($mod);
179
180     if( defined $ret ) {
181         $msg .= " was ";
182         $msg .= "first " unless $ver;
183         $msg .= "released with perl " . format_perl_version($ret);
184         $msg .= " and removed from " . format_perl_version($rem) if $rem;
185     } else {
186         $msg .= " was not in CORE (or so I think)";
187     }
188
189     print "\n",$msg,"\n";
190
191     if(defined $ret and exists $Opts{a} and $Opts{a}){
192         display_a($mod);
193     }
194 }
195
196
197 sub max_mod_len {
198     my $versions = shift;
199     my $max = 0;
200     for my $mod (keys %$versions) {
201         $max = max($max, length $mod);
202     }
203
204     return $max;
205 }
206
207 sub max {
208     my($this, $that) = @_;
209     return $this if $this > $that;
210     return $that;
211 }
212
213 sub display_a {
214     my $mod = shift;
215
216     for my $v (grep !/000$/, sort keys %Module::CoreList::version ) {
217         next unless exists $Module::CoreList::version{$v}{$mod};
218
219         my $mod_v = $Module::CoreList::version{$v}{$mod} || 'undef';
220         printf "  %-10s %-10s\n", format_perl_version($v), $mod_v;
221     }
222     print "\n";
223 }
224
225
226 {
227     my $have_version_pm;
228     sub have_version_pm {
229         return $have_version_pm if defined $have_version_pm;
230         return $have_version_pm = eval { require version; 1 };
231     }
232 }
233
234
235 sub format_perl_version {
236     my $v = shift;
237     return $v if $v < 5.006 or !have_version_pm;
238     return version->new($v)->normal;
239 }
240
241
242 sub numify_version {
243     my $ver = shift;
244     if ($ver =~ /\..+\./) {
245         have_version_pm()
246             or die "You need to install version.pm to use dotted version numbers\n";
247         $ver = version->new($ver)->numify;
248     }
249     $ver += 0;
250     return $ver;
251 }
252
253 =head1 EXAMPLES
254
255     $ corelist File::Spec
256
257     File::Spec was first released with perl 5.005
258
259     $ corelist File::Spec 0.83
260
261     File::Spec 0.83 was released with perl 5.007003
262
263     $ corelist File::Spec 0.89
264
265     File::Spec 0.89 was not in CORE (or so I think)
266
267     $ corelist File::Spec::Aliens
268
269     File::Spec::Aliens  was not in CORE (or so I think)
270
271     $ corelist /IPC::Open/
272
273     IPC::Open2 was first released with perl 5
274
275     IPC::Open3 was first released with perl 5
276
277     $ corelist /MANIFEST/i
278
279     ExtUtils::Manifest was first released with perl 5.001
280
281     $ corelist /Template/
282
283     /Template/  has no match in CORE (or so I think)
284
285     $ corelist -v 5.8.8 B
286
287     B                        1.09_01
288
289     $ corelist -v 5.8.8 /^B::/
290
291     B::Asmdata               1.01
292     B::Assembler             0.07
293     B::Bblock                1.02_01
294     B::Bytecode              1.01_01
295     B::C                     1.04_01
296     B::CC                    1.00_01
297     B::Concise               0.66
298     B::Debug                 1.02_01
299     B::Deparse               0.71
300     B::Disassembler          1.05
301     B::Lint                  1.03
302     B::O                     1.00
303     B::Showlex               1.02
304     B::Stackobj              1.00
305     B::Stash                 1.00
306     B::Terse                 1.03_01
307     B::Xref                  1.01
308
309 =head1 COPYRIGHT
310
311 Copyright (c) 2002-2007 by D.H. aka PodMaster
312
313 Currently maintained by the perl 5 porters E<lt>perl5-porters@perl.orgE<gt>.
314
315 This program is distributed under the same terms as perl itself.
316 See http://perl.org/ or http://cpan.org/ for more info on that.
317
318 =cut