Move Module::CoreList from ext/ to dist/
[perl.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:f 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 "$_\n" for sort keys %Module::CoreList::version;
96         print "\n";
97         exit 0;
98     }
99
100     $Opts{v} = numify_version( $Opts{v} );
101     my $version_hash = Module::CoreList->find_version($Opts{v});
102     if( !$version_hash ) {
103         print "\nModule::CoreList has no info on perl v$Opts{v}\n\n";
104         exit 1;
105     }
106
107     if ( !@ARGV ) {
108         print "\nThe following modules were in perl v$Opts{v} CORE\n";
109         print "$_ ", $version_hash->{$_} || " ","\n"
110         for sort keys %$version_hash;
111         print "\n";
112         exit 0;
113     }
114 }
115
116 if ( !@ARGV ) {
117     pod2usage(0);
118 }
119
120 while (@ARGV) {
121         my ($mod, $ver);
122         if ($ARGV[0] =~ /=/) {
123             ($mod, $ver) = split /=/, shift @ARGV;
124         } else {
125             $mod = shift @ARGV;
126             $ver = (@ARGV && $ARGV[0] =~ /^\d/) ? shift @ARGV : "";
127         }
128
129         if ($mod !~ m|^/(.*)/([imosx]*)$|) { # not a regex
130             module_version($mod,$ver);
131         } else {
132             my $re;
133             eval { $re = $2 ? qr/(?$2)($1)/ : qr/$1/; }; # trap exceptions while building regex
134             if ($@) {
135                 # regex errors are usually like 'Quantifier follow nothing in regex; marked by ...'
136                 # then we drop text after ';' to shorten message
137                 my $errmsg = $@ =~ /(.*);/ ? $1 : $@;
138                 warn "\n$mod  is a bad regex: $errmsg\n";
139                 next;
140             }
141             my @mod = Module::CoreList->find_modules($re);
142             if (@mod) {
143                 module_version($_, $ver) for @mod;
144             } else {
145                 $ver |= '';
146                 print "\n$mod $ver has no match in CORE (or so I think)\n";
147             }
148
149         }
150 }
151
152 exit();
153
154 sub module_version {
155     my($mod,$ver) = @_;
156
157     if ( $Opts{v} ) {
158         my $version_hash = Module::CoreList->find_version($Opts{v});
159         if ($version_hash) {
160             print $mod, " ", $version_hash->{$mod} || 'undef', "\n";
161             return;
162         }
163         else { die "Shouldn't happen" }
164     }
165
166     my $ret = $Opts{d}
167         ? Module::CoreList->first_release_by_date(@_)
168         : Module::CoreList->first_release(@_);
169     my $msg = $mod;
170     $msg .= " $ver" if $ver;
171
172     if( defined $ret ) {
173         $msg .= " was ";
174         $msg .= "first " unless $ver;
175         $msg .= "released with perl $ret"
176     } else {
177         $msg .= " was not in CORE (or so I think)";
178     }
179
180     print "\n",$msg,"\n";
181
182     if(defined $ret and exists $Opts{a} and $Opts{a}){
183         for my $v(
184             sort keys %Module::CoreList::version ){
185
186             printf "  %-10s %-10s\n",
187                 $v,
188                 $Module::CoreList::version{$v}{$mod}
189                     || 'undef'
190                     if exists $Module::CoreList::version{$v}{$mod};
191         }
192         print "\n";
193     }
194 }
195
196 sub numify_version {
197     my $ver = shift;
198     if ($ver =~ /\..+\./) {
199         eval { require version ; 1 }
200             or die "You need to install version.pm to use dotted version numbers\n";
201         $ver = version->new($ver)->numify;
202     }
203     $ver += 0;
204     return $ver;
205 }
206
207 =head1 EXAMPLES
208
209     $ corelist File::Spec
210
211     File::Spec was first released with perl 5.005
212
213     $ corelist File::Spec 0.83
214
215     File::Spec 0.83 was released with perl 5.007003
216
217     $ corelist File::Spec 0.89
218
219     File::Spec 0.89 was not in CORE (or so I think)
220
221     $ corelist File::Spec::Aliens
222
223     File::Spec::Aliens  was not in CORE (or so I think)
224
225     $ corelist /IPC::Open/
226
227     IPC::Open2 was first released with perl 5
228
229     IPC::Open3 was first released with perl 5
230
231     $ corelist /MANIFEST/i
232
233     ExtUtils::Manifest was first released with perl 5.001
234
235     $ corelist /Template/
236
237     /Template/  has no match in CORE (or so I think)
238
239     $ corelist -v 5.8.8 B
240
241     B                        1.09_01
242
243     $ corelist -v 5.8.8 /^B::/
244
245     B::Asmdata               1.01
246     B::Assembler             0.07
247     B::Bblock                1.02_01
248     B::Bytecode              1.01_01
249     B::C                     1.04_01
250     B::CC                    1.00_01
251     B::Concise               0.66
252     B::Debug                 1.02_01
253     B::Deparse               0.71
254     B::Disassembler          1.05
255     B::Lint                  1.03
256     B::O                     1.00
257     B::Showlex               1.02
258     B::Stackobj              1.00
259     B::Stash                 1.00
260     B::Terse                 1.03_01
261     B::Xref                  1.01
262
263 =head1 COPYRIGHT
264
265 Copyright (c) 2002-2007 by D.H. aka PodMaster
266
267 Currently maintained by the perl 5 porters E<lt>perl5-porters@perl.orgE<gt>.
268
269 This program is distributed under the same terms as perl itself.
270 See http://perl.org/ or http://cpan.org/ for more info on that.
271
272 =cut