xref: /openbsd-src/gnu/usr.bin/perl/cpan/Module-Metadata/lib/Module/Metadata.pm (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
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
5# Adapted from Perl-licensed code originally distributed with
6# Module-Build by Ken Williams
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);
14$VERSION = '1.000011';
15$VERSION = eval $VERSION;
16
17use Carp qw/croak/;
18use File::Spec;
19use IO::File;
20use version 0.87;
21BEGIN {
22  if ($INC{'Log/Contextual.pm'}) {
23    Log::Contextual->import('log_info');
24  } else {
25    *log_info = sub (&) { warn $_[0]->() };
26  }
27}
28use File::Find qw(find);
29
30my $V_NUM_REGEXP = qr{v?[0-9._]+};  # crudely, a v-string or decimal
31
32my $PKG_REGEXP  = qr{   # match a package declaration
33  ^[\s\{;]*             # intro chars on a line
34  package               # the word 'package'
35  \s+                   # whitespace
36  ([\w:]+)              # a package name
37  \s*                   # optional whitespace
38  ($V_NUM_REGEXP)?        # optional version number
39  \s*                   # optional whitesapce
40  [;\{]                 # semicolon line terminator or block start (since 5.16)
41}x;
42
43my $VARNAME_REGEXP = qr{ # match fully-qualified VERSION name
44  ([\$*])         # sigil - $ or *
45  (
46    (             # optional leading package name
47      (?:::|\')?  # possibly starting like just :: (�  la $::VERSION)
48      (?:\w+(?:::|\'))*  # Foo::Bar:: ...
49    )?
50    VERSION
51  )\b
52}x;
53
54my $VERS_REGEXP = qr{ # match a VERSION definition
55  (?:
56    \(\s*$VARNAME_REGEXP\s*\) # with parens
57  |
58    $VARNAME_REGEXP           # without parens
59  )
60  \s*
61  =[^=~]  # = but not ==, nor =~
62}x;
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
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
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) = @_;
99    $v1 = version->new($v1)
100      unless UNIVERSAL::isa($v1,'version');
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    }
114    elsif ( ref $version eq 'version' ) { # version objects
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 provides {
164    my $class = shift;
165
166    croak "provides() requires key/value pairs \n" if @_ % 2;
167    my %args = @_;
168
169    croak "provides() takes only one of 'dir' or 'files'\n"
170      if $args{dir} && $args{files};
171
172    croak "provides() requires a 'version' argument"
173      unless defined $args{version};
174
175    croak "provides() does not support version '$args{version}' metadata"
176        unless grep { $args{version} eq $_ } qw/1.4 2/;
177
178    $args{prefix} = 'lib' unless defined $args{prefix};
179
180    my $p;
181    if ( $args{dir} ) {
182      $p = $class->package_versions_from_directory($args{dir});
183    }
184    else {
185      croak "provides() requires 'files' to be an array reference\n"
186        unless ref $args{files} eq 'ARRAY';
187      $p = $class->package_versions_from_directory($args{files});
188    }
189
190    # Now, fix up files with prefix
191    if ( length $args{prefix} ) { # check in case disabled with q{}
192      $args{prefix} =~ s{/$}{};
193      for my $v ( values %$p ) {
194        $v->{file} = "$args{prefix}/$v->{file}";
195      }
196    }
197
198    return $p
199  }
200
201  sub package_versions_from_directory {
202    my ( $class, $dir, $files ) = @_;
203
204    my @files;
205
206    if ( $files ) {
207      @files = @$files;
208    } else {
209      find( {
210        wanted => sub {
211          push @files, $_ if -f $_ && /\.pm$/;
212        },
213        no_chdir => 1,
214      }, $dir );
215    }
216
217    # First, we enumerate all packages & versions,
218    # separating into primary & alternative candidates
219    my( %prime, %alt );
220    foreach my $file (@files) {
221      my $mapped_filename = File::Spec::Unix->abs2rel( $file, $dir );
222      my @path = split( /\//, $mapped_filename );
223      (my $prime_package = join( '::', @path )) =~ s/\.pm$//;
224
225      my $pm_info = $class->new_from_file( $file );
226
227      foreach my $package ( $pm_info->packages_inside ) {
228        next if $package eq 'main';  # main can appear numerous times, ignore
229        next if $package eq 'DB';    # special debugging package, ignore
230        next if grep /^_/, split( /::/, $package ); # private package, ignore
231
232        my $version = $pm_info->version( $package );
233
234        $prime_package = $package if lc($prime_package) eq lc($package);
235        if ( $package eq $prime_package ) {
236          if ( exists( $prime{$package} ) ) {
237            croak "Unexpected conflict in '$package'; multiple versions found.\n";
238          } else {
239            $mapped_filename = "$package.pm" if lc("$package.pm") eq lc($mapped_filename);
240            $prime{$package}{file} = $mapped_filename;
241            $prime{$package}{version} = $version if defined( $version );
242          }
243        } else {
244          push( @{$alt{$package}}, {
245                                    file    => $mapped_filename,
246                                    version => $version,
247                                   } );
248        }
249      }
250    }
251
252    # Then we iterate over all the packages found above, identifying conflicts
253    # and selecting the "best" candidate for recording the file & version
254    # for each package.
255    foreach my $package ( keys( %alt ) ) {
256      my $result = $resolve_module_versions->( $alt{$package} );
257
258      if ( exists( $prime{$package} ) ) { # primary package selected
259
260        if ( $result->{err} ) {
261  	# Use the selected primary package, but there are conflicting
262  	# errors among multiple alternative packages that need to be
263  	# reported
264          log_info {
265  	    "Found conflicting versions for package '$package'\n" .
266  	    "  $prime{$package}{file} ($prime{$package}{version})\n" .
267  	    $result->{err}
268          };
269
270        } elsif ( defined( $result->{version} ) ) {
271  	# There is a primary package selected, and exactly one
272  	# alternative package
273
274  	if ( exists( $prime{$package}{version} ) &&
275  	     defined( $prime{$package}{version} ) ) {
276  	  # Unless the version of the primary package agrees with the
277  	  # version of the alternative package, report a conflict
278  	  if ( $compare_versions->(
279                 $prime{$package}{version}, '!=', $result->{version}
280               )
281             ) {
282
283            log_info {
284              "Found conflicting versions for package '$package'\n" .
285  	      "  $prime{$package}{file} ($prime{$package}{version})\n" .
286  	      "  $result->{file} ($result->{version})\n"
287            };
288  	  }
289
290  	} else {
291  	  # The prime package selected has no version so, we choose to
292  	  # use any alternative package that does have a version
293  	  $prime{$package}{file}    = $result->{file};
294  	  $prime{$package}{version} = $result->{version};
295  	}
296
297        } else {
298  	# no alt package found with a version, but we have a prime
299  	# package so we use it whether it has a version or not
300        }
301
302      } else { # No primary package was selected, use the best alternative
303
304        if ( $result->{err} ) {
305          log_info {
306            "Found conflicting versions for package '$package'\n" .
307  	    $result->{err}
308          };
309        }
310
311        # Despite possible conflicting versions, we choose to record
312        # something rather than nothing
313        $prime{$package}{file}    = $result->{file};
314        $prime{$package}{version} = $result->{version}
315  	  if defined( $result->{version} );
316      }
317    }
318
319    # Normalize versions.  Can't use exists() here because of bug in YAML::Node.
320    # XXX "bug in YAML::Node" comment seems irrelvant -- dagolden, 2009-05-18
321    for (grep defined $_->{version}, values %prime) {
322      $_->{version} = $normalize_version->( $_->{version} );
323    }
324
325    return \%prime;
326  }
327}
328
329
330sub _init {
331  my $class    = shift;
332  my $module   = shift;
333  my $filename = shift;
334  my %props = @_;
335
336  my $handle = delete $props{handle};
337  my( %valid_props, @valid_props );
338  @valid_props = qw( collect_pod inc );
339  @valid_props{@valid_props} = delete( @props{@valid_props} );
340  warn "Unknown properties: @{[keys %props]}\n" if scalar( %props );
341
342  my %data = (
343    module       => $module,
344    filename     => $filename,
345    version      => undef,
346    packages     => [],
347    versions     => {},
348    pod          => {},
349    pod_headings => [],
350    collect_pod  => 0,
351
352    %valid_props,
353  );
354
355  my $self = bless(\%data, $class);
356
357  if ( $handle ) {
358    $self->_parse_fh($handle);
359  }
360  else {
361    $self->_parse_file();
362  }
363
364  unless($self->{module} and length($self->{module})) {
365    my ($v, $d, $f) = File::Spec->splitpath($self->{filename});
366    if($f =~ /\.pm$/) {
367      $f =~ s/\..+$//;
368      my @candidates = grep /$f$/, @{$self->{packages}};
369      $self->{module} = shift(@candidates); # punt
370    }
371    else {
372      if(grep /main/, @{$self->{packages}}) {
373        $self->{module} = 'main';
374      }
375      else {
376        $self->{module} = $self->{packages}[0] || '';
377      }
378    }
379  }
380
381  $self->{version} = $self->{versions}{$self->{module}}
382      if defined( $self->{module} );
383
384  return $self;
385}
386
387# class method
388sub _do_find_module {
389  my $class   = shift;
390  my $module  = shift || croak 'find_module_by_name() requires a package name';
391  my $dirs    = shift || \@INC;
392
393  my $file = File::Spec->catfile(split( /::/, $module));
394  foreach my $dir ( @$dirs ) {
395    my $testfile = File::Spec->catfile($dir, $file);
396    return [ File::Spec->rel2abs( $testfile ), $dir ]
397	if -e $testfile and !-d _;  # For stuff like ExtUtils::xsubpp
398    return [ File::Spec->rel2abs( "$testfile.pm" ), $dir ]
399	if -e "$testfile.pm";
400  }
401  return;
402}
403
404# class method
405sub find_module_by_name {
406  my $found = shift()->_do_find_module(@_) or return;
407  return $found->[0];
408}
409
410# class method
411sub find_module_dir_by_name {
412  my $found = shift()->_do_find_module(@_) or return;
413  return $found->[1];
414}
415
416
417# given a line of perl code, attempt to parse it if it looks like a
418# $VERSION assignment, returning sigil, full name, & package name
419sub _parse_version_expression {
420  my $self = shift;
421  my $line = shift;
422
423  my( $sig, $var, $pkg );
424  if ( $line =~ /$VERS_REGEXP/o ) {
425    ( $sig, $var, $pkg ) = $2 ? ( $1, $2, $3 ) : ( $4, $5, $6 );
426    if ( $pkg ) {
427      $pkg = ($pkg eq '::') ? 'main' : $pkg;
428      $pkg =~ s/::$//;
429    }
430  }
431
432  return ( $sig, $var, $pkg );
433}
434
435sub _parse_file {
436  my $self = shift;
437
438  my $filename = $self->{filename};
439  my $fh = IO::File->new( $filename )
440    or croak( "Can't open '$filename': $!" );
441
442  $self->_handle_bom($fh, $filename);
443
444  $self->_parse_fh($fh);
445}
446
447# Look for a UTF-8/UTF-16BE/UTF-16LE BOM at the beginning of the stream.
448# If there's one, then skip it and set the :encoding layer appropriately.
449sub _handle_bom {
450  my ($self, $fh, $filename) = @_;
451
452  my $pos = $fh->getpos;
453  return unless defined $pos;
454
455  my $buf = ' ' x 2;
456  my $count = $fh->read( $buf, length $buf );
457  return unless defined $count and $count >= 2;
458
459  my $encoding;
460  if ( $buf eq "\x{FE}\x{FF}" ) {
461    $encoding = 'UTF-16BE';
462  } elsif ( $buf eq "\x{FF}\x{FE}" ) {
463    $encoding = 'UTF-16LE';
464  } elsif ( $buf eq "\x{EF}\x{BB}" ) {
465    $buf = ' ';
466    $count = $fh->read( $buf, length $buf );
467    if ( defined $count and $count >= 1 and $buf eq "\x{BF}" ) {
468      $encoding = 'UTF-8';
469    }
470  }
471
472  if ( defined $encoding ) {
473    if ( "$]" >= 5.008 ) {
474      # $fh->binmode requires perl 5.10
475      binmode( $fh, ":encoding($encoding)" );
476    }
477  } else {
478    $fh->setpos($pos)
479      or croak( sprintf "Can't reset position to the top of '$filename'" );
480  }
481
482  return $encoding;
483}
484
485sub _parse_fh {
486  my ($self, $fh) = @_;
487
488  my( $in_pod, $seen_end, $need_vers ) = ( 0, 0, 0 );
489  my( @pkgs, %vers, %pod, @pod );
490  my $pkg = 'main';
491  my $pod_sect = '';
492  my $pod_data = '';
493
494  while (defined( my $line = <$fh> )) {
495    my $line_num = $.;
496
497    chomp( $line );
498
499    # From toke.c : any line that begins by "=X", where X is an alphabetic
500    # character, introduces a POD segment.
501    my $is_cut;
502    if ( $line =~ /^=([a-zA-Z].*)/ ) {
503      my $cmd = $1;
504      # Then it goes back to Perl code for "=cutX" where X is a non-alphabetic
505      # character (which includes the newline, but here we chomped it away).
506      $is_cut = $cmd =~ /^cut(?:[^a-zA-Z]|$)/;
507      $in_pod = !$is_cut;
508    }
509
510    if ( $in_pod ) {
511
512      if ( $line =~ /^=head[1-4]\s+(.+)\s*$/ ) {
513	push( @pod, $1 );
514	if ( $self->{collect_pod} && length( $pod_data ) ) {
515          $pod{$pod_sect} = $pod_data;
516          $pod_data = '';
517        }
518	$pod_sect = $1;
519
520      } elsif ( $self->{collect_pod} ) {
521	$pod_data .= "$line\n";
522
523      }
524
525    } elsif ( $is_cut ) {
526
527      if ( $self->{collect_pod} && length( $pod_data ) ) {
528        $pod{$pod_sect} = $pod_data;
529        $pod_data = '';
530      }
531      $pod_sect = '';
532
533    } else {
534
535      # Skip comments in code
536      next if $line =~ /^\s*#/;
537
538      # Would be nice if we could also check $in_string or something too
539      last if $line =~ /^__(?:DATA|END)__$/;
540
541      # parse $line to see if it's a $VERSION declaration
542      my( $vers_sig, $vers_fullname, $vers_pkg ) =
543          ($line =~ /VERSION/)
544              ? $self->_parse_version_expression( $line )
545              : ();
546
547      if ( $line =~ /$PKG_REGEXP/o ) {
548        $pkg = $1;
549        push( @pkgs, $pkg ) unless grep( $pkg eq $_, @pkgs );
550        $vers{$pkg} = $2 unless exists( $vers{$pkg} );
551        $need_vers = defined $2 ? 0 : 1;
552
553      # VERSION defined with full package spec, i.e. $Module::VERSION
554      } elsif ( $vers_fullname && $vers_pkg ) {
555	push( @pkgs, $vers_pkg ) unless grep( $vers_pkg eq $_, @pkgs );
556	$need_vers = 0 if $vers_pkg eq $pkg;
557
558	unless ( defined $vers{$vers_pkg} && length $vers{$vers_pkg} ) {
559	  $vers{$vers_pkg} =
560	    $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
561	}
562
563      # first non-comment line in undeclared package main is VERSION
564      } elsif ( !exists($vers{main}) && $pkg eq 'main' && $vers_fullname ) {
565	$need_vers = 0;
566	my $v =
567	  $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
568	$vers{$pkg} = $v;
569	push( @pkgs, 'main' );
570
571      # first non-comment line in undeclared package defines package main
572      } elsif ( !exists($vers{main}) && $pkg eq 'main' && $line =~ /\w+/ ) {
573	$need_vers = 1;
574	$vers{main} = '';
575	push( @pkgs, 'main' );
576
577      # only keep if this is the first $VERSION seen
578      } elsif ( $vers_fullname && $need_vers ) {
579	$need_vers = 0;
580	my $v =
581	  $self->_evaluate_version_line( $vers_sig, $vers_fullname, $line );
582
583
584	unless ( defined $vers{$pkg} && length $vers{$pkg} ) {
585	  $vers{$pkg} = $v;
586	}
587
588      }
589
590    }
591
592  }
593
594  if ( $self->{collect_pod} && length($pod_data) ) {
595    $pod{$pod_sect} = $pod_data;
596  }
597
598  $self->{versions} = \%vers;
599  $self->{packages} = \@pkgs;
600  $self->{pod} = \%pod;
601  $self->{pod_headings} = \@pod;
602}
603
604{
605my $pn = 0;
606sub _evaluate_version_line {
607  my $self = shift;
608  my( $sigil, $var, $line ) = @_;
609
610  # Some of this code came from the ExtUtils:: hierarchy.
611
612  # We compile into $vsub because 'use version' would cause
613  # compiletime/runtime issues with local()
614  my $vsub;
615  $pn++; # everybody gets their own package
616  my $eval = qq{BEGIN { q#  Hide from _packages_inside()
617    #; package Module::Metadata::_version::p$pn;
618    use version;
619    no strict;
620
621      \$vsub = sub {
622        local $sigil$var;
623        \$$var=undef;
624        $line;
625        \$$var
626      };
627  }};
628
629  local $^W;
630  # Try to get the $VERSION
631  eval $eval;
632  # some modules say $VERSION = $Foo::Bar::VERSION, but Foo::Bar isn't
633  # installed, so we need to hunt in ./lib for it
634  if ( $@ =~ /Can't locate/ && -d 'lib' ) {
635    local @INC = ('lib',@INC);
636    eval $eval;
637  }
638  warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
639    if $@;
640  (ref($vsub) eq 'CODE') or
641    croak "failed to build version sub for $self->{filename}";
642  my $result = eval { $vsub->() };
643  croak "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
644    if $@;
645
646  # Upgrade it into a version object
647  my $version = eval { _dwim_version($result) };
648
649  croak "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
650    unless defined $version; # "0" is OK!
651
652  return $version;
653}
654}
655
656# Try to DWIM when things fail the lax version test in obvious ways
657{
658  my @version_prep = (
659    # Best case, it just works
660    sub { return shift },
661
662    # If we still don't have a version, try stripping any
663    # trailing junk that is prohibited by lax rules
664    sub {
665      my $v = shift;
666      $v =~ s{([0-9])[a-z-].*$}{$1}i; # 1.23-alpha or 1.23b
667      return $v;
668    },
669
670    # Activestate apparently creates custom versions like '1.23_45_01', which
671    # cause version.pm to think it's an invalid alpha.  So check for that
672    # and strip them
673    sub {
674      my $v = shift;
675      my $num_dots = () = $v =~ m{(\.)}g;
676      my $num_unders = () = $v =~ m{(_)}g;
677      my $leading_v = substr($v,0,1) eq 'v';
678      if ( ! $leading_v && $num_dots < 2 && $num_unders > 1 ) {
679        $v =~ s{_}{}g;
680        $num_unders = () = $v =~ m{(_)}g;
681      }
682      return $v;
683    },
684
685    # Worst case, try numifying it like we would have before version objects
686    sub {
687      my $v = shift;
688      no warnings 'numeric';
689      return 0 + $v;
690    },
691
692  );
693
694  sub _dwim_version {
695    my ($result) = shift;
696
697    return $result if ref($result) eq 'version';
698
699    my ($version, $error);
700    for my $f (@version_prep) {
701      $result = $f->($result);
702      $version = eval { version->new($result) };
703      $error ||= $@ if $@; # capture first failure
704      last if defined $version;
705    }
706
707    croak $error unless defined $version;
708
709    return $version;
710  }
711}
712
713############################################################
714
715# accessors
716sub name            { $_[0]->{module}           }
717
718sub filename        { $_[0]->{filename}         }
719sub packages_inside { @{$_[0]->{packages}}      }
720sub pod_inside      { @{$_[0]->{pod_headings}}  }
721sub contains_pod    { $#{$_[0]->{pod_headings}} }
722
723sub version {
724    my $self = shift;
725    my $mod  = shift || $self->{module};
726    my $vers;
727    if ( defined( $mod ) && length( $mod ) &&
728	 exists( $self->{versions}{$mod} ) ) {
729	return $self->{versions}{$mod};
730    } else {
731	return undef;
732    }
733}
734
735sub pod {
736    my $self = shift;
737    my $sect = shift;
738    if ( defined( $sect ) && length( $sect ) &&
739	 exists( $self->{pod}{$sect} ) ) {
740	return $self->{pod}{$sect};
741    } else {
742	return undef;
743    }
744}
745
7461;
747
748=head1 NAME
749
750Module::Metadata - Gather package and POD information from perl module files
751
752=head1 SYNOPSIS
753
754  use Module::Metadata;
755
756  # information about a .pm file
757  my $info = Module::Metadata->new_from_file( $file );
758  my $version = $info->version;
759
760  # CPAN META 'provides' field for .pm files in a directory
761  my $provides = Module::Metadata->provides(
762    dir => 'lib', version => 2
763  );
764
765=head1 DESCRIPTION
766
767This module provides a standard way to gather metadata about a .pm file
768without executing unsafe code.
769
770=head1 USAGE
771
772=head2 Class methods
773
774=over 4
775
776=item C<< new_from_file($filename, collect_pod => 1) >>
777
778Constructs a C<Module::Metadata> object given the path to a file.  Returns
779undef if the filename does not exist.
780
781C<collect_pod> is a optional boolean argument that determines whether POD
782data is collected and stored for reference.  POD data is not collected by
783default.  POD headings are always collected.
784
785If the file begins by an UTF-8, UTF-16BE or UTF-16LE byte-order mark, then
786it is skipped before processing, and the content of the file is also decoded
787appropriately starting from perl 5.8.
788
789=item C<< new_from_handle($handle, $filename, collect_pod => 1) >>
790
791This works just like C<new_from_file>, except that a handle can be provided
792as the first argument.
793
794Note that there is no validation to confirm that the handle is a handle or
795something that can act like one.  Passing something that isn't a handle will
796cause a exception when trying to read from it.  The C<filename> argument is
797mandatory or undef will be returned.
798
799You are responsible for setting the decoding layers on C<$handle> if
800required.
801
802=item C<< new_from_module($module, collect_pod => 1, inc => \@dirs) >>
803
804Constructs a C<Module::Metadata> object given a module or package name.
805Returns undef if the module cannot be found.
806
807In addition to accepting the C<collect_pod> argument as described above,
808this method accepts a C<inc> argument which is a reference to an array of
809directories to search for the module.  If none are given, the default is
810@INC.
811
812If the file that contains the module begins by an UTF-8, UTF-16BE or
813UTF-16LE byte-order mark, then it is skipped before processing, and the
814content of the file is also decoded appropriately starting from perl 5.8.
815
816=item C<< find_module_by_name($module, \@dirs) >>
817
818Returns the path to a module given the module or package name. A list
819of directories can be passed in as an optional parameter, otherwise
820@INC is searched.
821
822Can be called as either an object or a class method.
823
824=item C<< find_module_dir_by_name($module, \@dirs) >>
825
826Returns the entry in C<@dirs> (or C<@INC> by default) that contains
827the module C<$module>. A list of directories can be passed in as an
828optional parameter, otherwise @INC is searched.
829
830Can be called as either an object or a class method.
831
832=item C<< provides( %options ) >>
833
834This is a convenience wrapper around C<package_versions_from_directory>
835to generate a CPAN META C<provides> data structure.  It takes key/value
836pairs.  Valid option keys include:
837
838=over
839
840=item version B<(required)>
841
842Specifies which version of the L<CPAN::Meta::Spec> should be used as
843the format of the C<provides> output.  Currently only '1.4' and '2'
844are supported (and their format is identical).  This may change in
845the future as the definition of C<provides> changes.
846
847The C<version> option is required.  If it is omitted or if
848an unsupported version is given, then C<provides> will throw an error.
849
850=item dir
851
852Directory to search recursively for F<.pm> files.  May not be specified with
853C<files>.
854
855=item files
856
857Array reference of files to examine.  May not be specified with C<dir>.
858
859=item prefix
860
861String to prepend to the C<file> field of the resulting output. This defaults
862to F<lib>, which is the common case for most CPAN distributions with their
863F<.pm> files in F<lib>.  This option ensures the META information has the
864correct relative path even when the C<dir> or C<files> arguments are
865absolute or have relative paths from a location other than the distribution
866root.
867
868=back
869
870For example, given C<dir> of 'lib' and C<prefix> of 'lib', the return value
871is a hashref of the form:
872
873  {
874    'Package::Name' => {
875      version => '0.123',
876      file => 'lib/Package/Name.pm'
877    },
878    'OtherPackage::Name' => ...
879  }
880
881=item C<< package_versions_from_directory($dir, \@files?) >>
882
883Scans C<$dir> for .pm files (unless C<@files> is given, in which case looks
884for those files in C<$dir> - and reads each file for packages and versions,
885returning a hashref of the form:
886
887  {
888    'Package::Name' => {
889      version => '0.123',
890      file => 'Package/Name.pm'
891    },
892    'OtherPackage::Name' => ...
893  }
894
895The C<DB> and C<main> packages are always omitted, as are any "private"
896packages that have leading underscores in the namespace (e.g.
897C<Foo::_private>)
898
899Note that the file path is relative to C<$dir> if that is specified.
900This B<must not> be used directly for CPAN META C<provides>.  See
901the C<provides> method instead.
902
903=item C<< log_info (internal) >>
904
905Used internally to perform logging; imported from Log::Contextual if
906Log::Contextual has already been loaded, otherwise simply calls warn.
907
908=back
909
910=head2 Object methods
911
912=over 4
913
914=item C<< name() >>
915
916Returns the name of the package represented by this module. If there
917are more than one packages, it makes a best guess based on the
918filename. If it's a script (i.e. not a *.pm) the package name is
919'main'.
920
921=item C<< version($package) >>
922
923Returns the version as defined by the $VERSION variable for the
924package as returned by the C<name> method if no arguments are
925given. If given the name of a package it will attempt to return the
926version of that package if it is specified in the file.
927
928=item C<< filename() >>
929
930Returns the absolute path to the file.
931
932=item C<< packages_inside() >>
933
934Returns a list of packages. Note: this is a raw list of packages
935discovered (or assumed, in the case of C<main>).  It is not
936filtered for C<DB>, C<main> or private packages the way the
937C<provides> method does.
938
939=item C<< pod_inside() >>
940
941Returns a list of POD sections.
942
943=item C<< contains_pod() >>
944
945Returns true if there is any POD in the file.
946
947=item C<< pod($section) >>
948
949Returns the POD data in the given section.
950
951=back
952
953=head1 AUTHOR
954
955Original code from Module::Build::ModuleInfo by Ken Williams
956<kwilliams@cpan.org>, Randy W. Sims <RandyS@ThePierianSpring.org>
957
958Released as Module::Metadata by Matt S Trout (mst) <mst@shadowcat.co.uk> with
959assistance from David Golden (xdg) <dagolden@cpan.org>.
960
961=head1 COPYRIGHT & LICENSE
962
963Original code Copyright (c) 2001-2011 Ken Williams.
964Additional code Copyright (c) 2010-2011 Matt Trout and David Golden.
965All rights reserved.
966
967This library is free software; you can redistribute it and/or
968modify it under the same terms as Perl itself.
969
970=cut
971
972