test package_versions_from_directory
[p5sagit/Module-Metadata.git] / lib / Module / Metadata.pm
CommitLineData
5ac756c6 1# -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-
2# vim:ts=8:sw=2:et:sta:sts=2
3package Module::Metadata;
4
cd41f0db 5# Adapted from Perl-licensed code originally distributed with
6# Module-Build by Ken Williams
5ac756c6 7
8# This module provides routines to gather information about
9# perl modules (assuming this may be expanded in the distant
10# parrot future to look at other types of modules).
11
12use strict;
13use vars qw($VERSION);
9782bfaf 14$VERSION = '1.000007';
5ac756c6 15$VERSION = eval $VERSION;
16
17use File::Spec;
18use IO::File;
4850170c 19use version 0.87;
3db27017 20BEGIN {
21 if ($INC{'Log/Contextual.pm'}) {
22 Log::Contextual->import('log_info');
23 } else {
e6ddd765 24 *log_info = sub (&) { warn $_[0]->() };
3db27017 25 }
26}
5ac756c6 27use File::Find qw(find);
28
29my $V_NUM_REGEXP = qr{v?[0-9._]+}; # crudely, a v-string or decimal
30
31my $PKG_REGEXP = qr{ # match a package declaration
32 ^[\s\{;]* # intro chars on a line
33 package # the word 'package'
34 \s+ # whitespace
35 ([\w:]+) # a package name
36 \s* # optional whitespace
37 ($V_NUM_REGEXP)? # optional version number
38 \s* # optional whitesapce
710f253f 39 [;\{] # semicolon line terminator or block start (since 5.16)
5ac756c6 40}x;
41
42my $VARNAME_REGEXP = qr{ # match fully-qualified VERSION name
43 ([\$*]) # sigil - $ or *
44 (
45 ( # optional leading package name
46 (?:::|\')? # possibly starting like just :: (Ì la $::VERSION)
47 (?:\w+(?:::|\'))* # Foo::Bar:: ...
48 )?
49 VERSION
50 )\b
51}x;
52
53my $VERS_REGEXP = qr{ # match a VERSION definition
54 (?:
55 \(\s*$VARNAME_REGEXP\s*\) # with parens
56 |
57 $VARNAME_REGEXP # without parens
58 )
59 \s*
60 =[^=~] # = but not ==, nor =~
61}x;
62
63
64sub new_from_file {
65 my $class = shift;
66 my $filename = File::Spec->rel2abs( shift );
67
68 return undef unless defined( $filename ) && -f $filename;
69 return $class->_init(undef, $filename, @_);
70}
71
f33c0a6c 72sub new_from_handle {
73 my $class = shift;
74 my $handle = shift;
75 my $filename = shift;
76 return undef unless defined($handle) && defined($filename);
77 $filename = File::Spec->rel2abs( $filename );
78
79 return $class->_init(undef, $filename, @_, handle => $handle);
80
81}
82
83
5ac756c6 84sub new_from_module {
85 my $class = shift;
86 my $module = shift;
87 my %props = @_;
88
89 $props{inc} ||= \@INC;
90 my $filename = $class->find_module_by_name( $module, $props{inc} );
91 return undef unless defined( $filename ) && -f $filename;
92 return $class->_init($module, $filename, %props);
93}
94
95{
96
97 my $compare_versions = sub {
98 my ($v1, $op, $v2) = @_;
4850170c 99 $v1 = version->new($v1)
100 unless UNIVERSAL::isa($v1,'version');
5ac756c6 101
102 my $eval_str = "\$v1 $op \$v2";
103 my $result = eval $eval_str;
104 log_info { "error comparing versions: '$eval_str' $@" } if $@;
105
106 return $result;
107 };
108
109 my $normalize_version = sub {
110 my ($version) = @_;
111 if ( $version =~ /[=<>!,]/ ) { # logic, not just version
112 # take as is without modification
113 }
4850170c 114 elsif ( ref $version eq 'version' ) { # version objects
5ac756c6 115 $version = $version->is_qv ? $version->normal : $version->stringify;
116 }
117 elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
118 # normalize string tuples without "v": "1.2.3" -> "v1.2.3"
119 $version = "v$version";
120 }
121 else {
122 # leave alone
123 }
124 return $version;
125 };
126
127 # separate out some of the conflict resolution logic
128
129 my $resolve_module_versions = sub {
130 my $packages = shift;
131
132 my( $file, $version );
133 my $err = '';
134 foreach my $p ( @$packages ) {
135 if ( defined( $p->{version} ) ) {
136 if ( defined( $version ) ) {
137 if ( $compare_versions->( $version, '!=', $p->{version} ) ) {
138 $err .= " $p->{file} ($p->{version})\n";
139 } else {
140 # same version declared multiple times, ignore
141 }
142 } else {
143 $file = $p->{file};
144 $version = $p->{version};
145 }
146 }
147 $file ||= $p->{file} if defined( $p->{file} );
148 }
149
150 if ( $err ) {
151 $err = " $file ($version)\n" . $err;
152 }
153
154 my %result = (
155 file => $file,
156 version => $version,
157 err => $err
158 );
159
160 return \%result;
161 };
162
163 sub package_versions_from_directory {
164 my ( $class, $dir, $files ) = @_;
165
166 my @files;
167
168 if ( $files ) {
169 @files = @$files;
170 } else {
171 find( {
172 wanted => sub {
173 push @files, $_ if -f $_ && /\.pm$/;
174 },
175 no_chdir => 1,
176 }, $dir );
177 }
178
179 # First, we enumerate all packages & versions,
180 # separating into primary & alternative candidates
181 my( %prime, %alt );
182 foreach my $file (@files) {
183 my $mapped_filename = File::Spec->abs2rel( $file, $dir );
184 my @path = split( /\//, $mapped_filename );
185 (my $prime_package = join( '::', @path )) =~ s/\.pm$//;
186
187 my $pm_info = $class->new_from_file( $file );
188
189 foreach my $package ( $pm_info->packages_inside ) {
190 next if $package eq 'main'; # main can appear numerous times, ignore
191 next if $package eq 'DB'; # special debugging package, ignore
192 next if grep /^_/, split( /::/, $package ); # private package, ignore
193
194 my $version = $pm_info->version( $package );
195
196 if ( $package eq $prime_package ) {
197 if ( exists( $prime{$package} ) ) {
5ac756c6 198 die "Unexpected conflict in '$package'; multiple versions found.\n";
199 } else {
200 $prime{$package}{file} = $mapped_filename;
201 $prime{$package}{version} = $version if defined( $version );
202 }
203 } else {
204 push( @{$alt{$package}}, {
205 file => $mapped_filename,
206 version => $version,
207 } );
208 }
209 }
210 }
211
212 # Then we iterate over all the packages found above, identifying conflicts
213 # and selecting the "best" candidate for recording the file & version
214 # for each package.
215 foreach my $package ( keys( %alt ) ) {
216 my $result = $resolve_module_versions->( $alt{$package} );
217
218 if ( exists( $prime{$package} ) ) { # primary package selected
219
220 if ( $result->{err} ) {
221 # Use the selected primary package, but there are conflicting
222 # errors among multiple alternative packages that need to be
223 # reported
224 log_info {
225 "Found conflicting versions for package '$package'\n" .
226 " $prime{$package}{file} ($prime{$package}{version})\n" .
227 $result->{err}
228 };
229
230 } elsif ( defined( $result->{version} ) ) {
231 # There is a primary package selected, and exactly one
232 # alternative package
233
234 if ( exists( $prime{$package}{version} ) &&
235 defined( $prime{$package}{version} ) ) {
236 # Unless the version of the primary package agrees with the
237 # version of the alternative package, report a conflict
238 if ( $compare_versions->(
239 $prime{$package}{version}, '!=', $result->{version}
240 )
241 ) {
242
243 log_info {
244 "Found conflicting versions for package '$package'\n" .
245 " $prime{$package}{file} ($prime{$package}{version})\n" .
246 " $result->{file} ($result->{version})\n"
247 };
248 }
249
250 } else {
251 # The prime package selected has no version so, we choose to
252 # use any alternative package that does have a version
253 $prime{$package}{file} = $result->{file};
254 $prime{$package}{version} = $result->{version};
255 }
256
257 } else {
258 # no alt package found with a version, but we have a prime
259 # package so we use it whether it has a version or not
260 }
261
262 } else { # No primary package was selected, use the best alternative
263
264 if ( $result->{err} ) {
265 log_info {
266 "Found conflicting versions for package '$package'\n" .
267 $result->{err}
268 };
269 }
270
271 # Despite possible conflicting versions, we choose to record
272 # something rather than nothing
273 $prime{$package}{file} = $result->{file};
274 $prime{$package}{version} = $result->{version}
275 if defined( $result->{version} );
276 }
277 }
278
279 # Normalize versions. Can't use exists() here because of bug in YAML::Node.
280 # XXX "bug in YAML::Node" comment seems irrelvant -- dagolden, 2009-05-18
281 for (grep defined $_->{version}, values %prime) {
282 $_->{version} = $normalize_version->( $_->{version} );
283 }
284
285 return \%prime;
286 }
287}
288
289
290sub _init {
291 my $class = shift;
292 my $module = shift;
293 my $filename = shift;
294 my %props = @_;
295
f33c0a6c 296 my $handle = delete $props{handle};
5ac756c6 297 my( %valid_props, @valid_props );
298 @valid_props = qw( collect_pod inc );
299 @valid_props{@valid_props} = delete( @props{@valid_props} );
300 warn "Unknown properties: @{[keys %props]}\n" if scalar( %props );
301
302 my %data = (
303 module => $module,
304 filename => $filename,
305 version => undef,
306 packages => [],
307 versions => {},
308 pod => {},
309 pod_headings => [],
310 collect_pod => 0,
311
312 %valid_props,
313 );
314
315 my $self = bless(\%data, $class);
316
f33c0a6c 317 if ( $handle ) {
318 $self->_parse_fh($handle);
319 }
320 else {
321 $self->_parse_file();
322 }
5ac756c6 323
324 unless($self->{module} and length($self->{module})) {
325 my ($v, $d, $f) = File::Spec->splitpath($self->{filename});
326 if($f =~ /\.pm$/) {
327 $f =~ s/\..+$//;
328 my @candidates = grep /$f$/, @{$self->{packages}};
329 $self->{module} = shift(@candidates); # punt
330 }
331 else {
332 if(grep /main/, @{$self->{packages}}) {
333 $self->{module} = 'main';
334 }
335 else {
336 $self->{module} = $self->{packages}[0] || '';
337 }
338 }
339 }
340
341 $self->{version} = $self->{versions}{$self->{module}}
342 if defined( $self->{module} );
343
344 return $self;
345}
346
347# class method
348sub _do_find_module {
349 my $class = shift;
350 my $module = shift || die 'find_module_by_name() requires a package name';
351 my $dirs = shift || \@INC;
352
353 my $file = File::Spec->catfile(split( /::/, $module));
354 foreach my $dir ( @$dirs ) {
355 my $testfile = File::Spec->catfile($dir, $file);
356 return [ File::Spec->rel2abs( $testfile ), $dir ]
357 if -e $testfile and !-d _; # For stuff like ExtUtils::xsubpp
358 return [ File::Spec->rel2abs( "$testfile.pm" ), $dir ]
359 if -e "$testfile.pm";
360 }
361 return;
362}
363
364# class method
365sub find_module_by_name {
366 my $found = shift()->_do_find_module(@_) or return;
367 return $found->[0];
368}
369
370# class method
371sub find_module_dir_by_name {
372 my $found = shift()->_do_find_module(@_) or return;
373 return $found->[1];
374}
375
376
377# given a line of perl code, attempt to parse it if it looks like a
378# $VERSION assignment, returning sigil, full name, & package name
379sub _parse_version_expression {
380 my $self = shift;
381 my $line = shift;
382
383 my( $sig, $var, $pkg );
384 if ( $line =~ $VERS_REGEXP ) {
385 ( $sig, $var, $pkg ) = $2 ? ( $1, $2, $3 ) : ( $4, $5, $6 );
386 if ( $pkg ) {
387 $pkg = ($pkg eq '::') ? 'main' : $pkg;
388 $pkg =~ s/::$//;
389 }
390 }
391
392 return ( $sig, $var, $pkg );
393}
394
395sub _parse_file {
396 my $self = shift;
397
398 my $filename = $self->{filename};
399 my $fh = IO::File->new( $filename )
400 or die( "Can't open '$filename': $!" );
401
402 $self->_parse_fh($fh);
403}
404
405sub _parse_fh {
406 my ($self, $fh) = @_;
407
408 my( $in_pod, $seen_end, $need_vers ) = ( 0, 0, 0 );
409 my( @pkgs, %vers, %pod, @pod );
410 my $pkg = 'main';
411 my $pod_sect = '';
412 my $pod_data = '';
413
414 while (defined( my $line = <$fh> )) {
415 my $line_num = $.;
416
417 chomp( $line );
418 next if $line =~ /^\s*#/;
419
420 $in_pod = ($line =~ /^=(?!cut)/) ? 1 : ($line =~ /^=cut/) ? 0 : $in_pod;
421
422 # Would be nice if we could also check $in_string or something too
423 last if !$in_pod && $line =~ /^__(?:DATA|END)__$/;
424
425 if ( $in_pod || $line =~ /^=cut/ ) {
426
427 if ( $line =~ /^=head\d\s+(.+)\s*$/ ) {
428 push( @pod, $1 );
429 if ( $self->{collect_pod} && length( $pod_data ) ) {
430 $pod{$pod_sect} = $pod_data;
431 $pod_data = '';
432 }
433 $pod_sect = $1;
434
435
436 } elsif ( $self->{collect_pod} ) {
437 $pod_data .= "$line\n";
438
439 }
440
441 } else {
442
443 $pod_sect = '';
444 $pod_data = '';
445
446 # parse $line to see if it's a $VERSION declaration
447 my( $vers_sig, $vers_fullname, $vers_pkg ) =
448 $self->_parse_version_expression( $line );
449
450 if ( $line =~ $PKG_REGEXP ) {
451 $pkg = $1;
452 push( @pkgs, $pkg ) unless grep( $pkg eq $_, @pkgs );
453 $vers{$pkg} = (defined $2 ? $2 : undef) unless exists( $vers{$pkg} );
454 $need_vers = defined $2 ? 0 : 1;
455
456 # VERSION defined with full package spec, i.e. $Module::VERSION
457 } elsif ( $vers_fullname && $vers_pkg ) {
458 push( @pkgs, $vers_pkg ) unless grep( $vers_pkg eq $_, @pkgs );
459 $need_vers = 0 if $vers_pkg eq $pkg;
460
461 unless ( defined $vers{$vers_pkg} && length $vers{$vers_pkg} ) {
462 $vers{$vers_pkg} =
463 $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
464 } else {
465 # Warn unless the user is using the "$VERSION = eval
466 # $VERSION" idiom (though there are probably other idioms
467 # that we should watch out for...)
468 warn <<"EOM" unless $line =~ /=\s*eval/;
469Package '$vers_pkg' already declared with version '$vers{$vers_pkg}',
470ignoring subsequent declaration on line $line_num.
471EOM
472 }
473
474 # first non-comment line in undeclared package main is VERSION
475 } elsif ( !exists($vers{main}) && $pkg eq 'main' && $vers_fullname ) {
476 $need_vers = 0;
477 my $v =
478 $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
479 $vers{$pkg} = $v;
480 push( @pkgs, 'main' );
481
482 # first non-comment line in undeclared package defines package main
483 } elsif ( !exists($vers{main}) && $pkg eq 'main' && $line =~ /\w+/ ) {
484 $need_vers = 1;
485 $vers{main} = '';
486 push( @pkgs, 'main' );
487
488 # only keep if this is the first $VERSION seen
489 } elsif ( $vers_fullname && $need_vers ) {
490 $need_vers = 0;
491 my $v =
492 $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
493
494
495 unless ( defined $vers{$pkg} && length $vers{$pkg} ) {
496 $vers{$pkg} = $v;
497 } else {
498 warn <<"EOM";
499Package '$pkg' already declared with version '$vers{$pkg}'
500ignoring new version '$v' on line $line_num.
501EOM
502 }
503
504 }
505
506 }
507
508 }
509
510 if ( $self->{collect_pod} && length($pod_data) ) {
511 $pod{$pod_sect} = $pod_data;
512 }
513
514 $self->{versions} = \%vers;
515 $self->{packages} = \@pkgs;
516 $self->{pod} = \%pod;
517 $self->{pod_headings} = \@pod;
518}
519
520{
521my $pn = 0;
522sub _evaluate_version_line {
523 my $self = shift;
524 my( $sigil, $var, $line ) = @_;
525
526 # Some of this code came from the ExtUtils:: hierarchy.
527
528 # We compile into $vsub because 'use version' would cause
529 # compiletime/runtime issues with local()
530 my $vsub;
531 $pn++; # everybody gets their own package
532 my $eval = qq{BEGIN { q# Hide from _packages_inside()
533 #; package Module::Metadata::_version::p$pn;
4850170c 534 use version;
5ac756c6 535 no strict;
536
5ac756c6 537 \$vsub = sub {
398fe5a2 538 local $sigil$var;
539 \$$var=undef;
5ac756c6 540 $line;
541 \$$var
542 };
543 }};
544
545 local $^W;
546 # Try to get the $VERSION
547 eval $eval;
548 # some modules say $VERSION = $Foo::Bar::VERSION, but Foo::Bar isn't
549 # installed, so we need to hunt in ./lib for it
550 if ( $@ =~ /Can't locate/ && -d 'lib' ) {
551 local @INC = ('lib',@INC);
552 eval $eval;
553 }
554 warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
555 if $@;
556 (ref($vsub) eq 'CODE') or
557 die "failed to build version sub for $self->{filename}";
558 my $result = eval { $vsub->() };
559 die "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
560 if $@;
561
d880ef1f 562 # Upgrade it into a version object
92ad06ed 563 my $version = eval { _dwim_version($result) };
564
5ac756c6 565 die "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
92ad06ed 566 unless defined $version; # "0" is OK!
5ac756c6 567
92ad06ed 568 return $version;
5ac756c6 569}
570}
571
92ad06ed 572# Try to DWIM when things fail the lax version test in obvious ways
573{
574 my @version_prep = (
575 # Best case, it just works
576 sub { return shift },
577
578 # If we still don't have a version, try stripping any
579 # trailing junk that is prohibited by lax rules
580 sub {
581 my $v = shift;
582 $v =~ s{([0-9])[a-z-].*$}{$1}i; # 1.23-alpha or 1.23b
583 return $v;
584 },
585
586 # Activestate apparently creates custom versions like '1.23_45_01', which
587 # cause version.pm to think it's an invalid alpha. So check for that
588 # and strip them
589 sub {
590 my $v = shift;
591 my $num_dots = () = $v =~ m{(\.)}g;
592 my $num_unders = () = $v =~ m{(_)}g;
593 my $leading_v = substr($v,0,1) eq 'v';
594 if ( ! $leading_v && $num_dots < 2 && $num_unders > 1 ) {
595 $v =~ s{_}{}g;
596 $num_unders = () = $v =~ m{(_)}g;
597 }
598 return $v;
599 },
600
601 # Worst case, try numifying it like we would have before version objects
602 sub {
603 my $v = shift;
604 no warnings 'numeric';
605 return 0 + $v;
606 },
607
608 );
609
610 sub _dwim_version {
611 my ($result) = shift;
612
613 return $result if ref($result) eq 'version';
614
615 my ($version, $error);
616 for my $f (@version_prep) {
617 $result = $f->($result);
618 $version = eval { version->new($result) };
619 $error ||= $@ if $@; # capture first failure
620 last if defined $version;
621 }
622
623 die $error unless defined $version;
624
625 return $version;
626 }
627}
5ac756c6 628
629############################################################
630
631# accessors
632sub name { $_[0]->{module} }
633
634sub filename { $_[0]->{filename} }
635sub packages_inside { @{$_[0]->{packages}} }
636sub pod_inside { @{$_[0]->{pod_headings}} }
637sub contains_pod { $#{$_[0]->{pod_headings}} }
638
639sub version {
640 my $self = shift;
641 my $mod = shift || $self->{module};
642 my $vers;
643 if ( defined( $mod ) && length( $mod ) &&
644 exists( $self->{versions}{$mod} ) ) {
645 return $self->{versions}{$mod};
646 } else {
647 return undef;
648 }
649}
650
651sub pod {
652 my $self = shift;
653 my $sect = shift;
654 if ( defined( $sect ) && length( $sect ) &&
655 exists( $self->{pod}{$sect} ) ) {
656 return $self->{pod}{$sect};
657 } else {
658 return undef;
659 }
660}
661
6621;
663
5ac756c6 664=head1 NAME
665
2c11e51d 666Module::Metadata - Gather package and POD information from perl module files
5ac756c6 667
6290f67c 668=head1 SYNOPSIS
669
670 use Module::Metadata;
671
672 # information about a .pm file
673 my $info = Module::Metadata->new_from_file( $file );
674 my $version = $info->version;
675
676 # information about a directory full of .pm files
677 my $provides =
678 Module::Metadata->package_versions_from_directory('lib');
679
5ac756c6 680=head1 DESCRIPTION
681
6290f67c 682This module provides a standard way to gather metadata about a .pm file
683without executing unsafe code.
684
685=head1 USAGE
686
687=head2 Class methods
688
5ac756c6 689=over 4
690
6290f67c 691=item C<< new_from_file($filename, collect_pod => 1) >>
5ac756c6 692
6290f67c 693Construct a C<Module::Metadata> object given the path to a file. Takes an
694optional argument C<collect_pod> which is a boolean that determines whether POD
695data is collected and stored for reference. POD data is not collected by
696default. POD headings are always collected. Returns undef if the filename
697does not exist.
5ac756c6 698
6290f67c 699=item C<< new_from_handle($handle, $filename, collect_pod => 1) >>
f33c0a6c 700
701This works just like C<new_from_file>, except that a handle can be provided
702as the first argument. Note that there is no validation to confirm that the
703handle is a handle or something that can act like one. Passing something that
704isn't a handle will cause a exception when trying to read from it. The
705C<filename> argument is mandatory or undef will be returned.
706
6290f67c 707=item C<< new_from_module($module, collect_pod => 1, inc => \@dirs) >>
5ac756c6 708
d846be69 709Construct a C<Module::Metadata> object given a module or package name. In addition
5ac756c6 710to accepting the C<collect_pod> argument as described above, this
711method accepts a C<inc> argument which is a reference to an array of
712of directories to search for the module. If none are given, the
6290f67c 713default is @INC. Returns undef if the module cannot be found.
5ac756c6 714
6290f67c 715=item C<< find_module_by_name($module, \@dirs) >>
5ac756c6 716
717Returns the path to a module given the module or package name. A list
718of directories can be passed in as an optional parameter, otherwise
719@INC is searched.
720
721Can be called as either an object or a class method.
722
6290f67c 723=item C<< find_module_dir_by_name($module, \@dirs) >>
5ac756c6 724
725Returns the entry in C<@dirs> (or C<@INC> by default) that contains
726the module C<$module>. A list of directories can be passed in as an
727optional parameter, otherwise @INC is searched.
728
729Can be called as either an object or a class method.
730
6290f67c 731=item C<< package_versions_from_directory($dir, \@files?) >>
2c11e51d 732
733Scans C<$dir> for .pm files (unless C<@files> is given, in which case looks
734for those files in C<$dir> - and reads each file for packages and versions,
735returning a hashref of the form:
5ac756c6 736
2c11e51d 737 {
738 'Package::Name' => {
739 version => '0.123',
740 file => 'Package/Name.pm'
741 },
742 'OtherPackage::Name' => ...
743 }
744
6290f67c 745=item C<< log_info (internal) >>
2c11e51d 746
747Used internally to perform logging; imported from Log::Contextual if
748Log::Contextual has already been loaded, otherwise simply calls warn.
749
750=back
5ac756c6 751
6290f67c 752=head2 Object methods
753
754=over 4
755
756=item C<< name() >>
757
758Returns the name of the package represented by this module. If there
759are more than one packages, it makes a best guess based on the
760filename. If it's a script (i.e. not a *.pm) the package name is
761'main'.
762
763=item C<< version($package) >>
764
765Returns the version as defined by the $VERSION variable for the
766package as returned by the C<name> method if no arguments are
767given. If given the name of a package it will attempt to return the
768version of that package if it is specified in the file.
769
770=item C<< filename() >>
771
772Returns the absolute path to the file.
773
774=item C<< packages_inside() >>
775
776Returns a list of packages.
777
778=item C<< pod_inside() >>
779
780Returns a list of POD sections.
781
782=item C<< contains_pod() >>
783
784Returns true if there is any POD in the file.
785
786=item C<< pod($section) >>
787
788Returns the POD data in the given section.
789
790=back
791
5ac756c6 792=head1 AUTHOR
793
6290f67c 794Original code from Module::Build::ModuleInfo by Ken Williams
795<kwilliams@cpan.org>, Randy W. Sims <RandyS@ThePierianSpring.org>
5ac756c6 796
2c11e51d 797Released as Module::Metadata by Matt S Trout (mst) <mst@shadowcat.co.uk> with
6290f67c 798assistance from David Golden (xdg) <dagolden@cpan.org>.
5ac756c6 799
800=head1 COPYRIGHT
801
6290f67c 802Original code Copyright (c) 2001-2011 Ken Williams.
803Additional code Copyright (c) 2010-2011 Matt Trout and David Golden.
804All rights reserved.
5ac756c6 805
806This library is free software; you can redistribute it and/or
807modify it under the same terms as Perl itself.
808
5ac756c6 809=cut
810