return \%result;
};
+ sub provides {
+ my $class = shift;
+
+ die "provides() requires key/value pairs \n" if @_ % 2;
+ my %args = @_;
+
+ die "provides() takes only one of 'dir' or 'files'\n"
+ if $args{dir} && $args{files};
+
+ $args{prefix} = 'lib' unless defined $args{prefix};
+
+ my $p;
+ if ( $args{dir} ) {
+ $p = $class->package_versions_from_directory($args{dir});
+ }
+ else {
+ die "provides() requires 'files' to be an array reference\n"
+ unless ref $args{files} eq 'ARRAY';
+ $p = $class->package_versions_from_directory($args{files});
+ }
+
+ # Now, fix up files with prefix
+ if ( length $args{prefix} ) { # check in case disabled with q{}
+ $args{prefix} =~ s{/$}{};
+ for my $v ( values %$p ) {
+ $v->{file} = "$args{prefix}/$v->{file}";
+ }
+ }
+
+ return $p
+ }
+
sub package_versions_from_directory {
my ( $class, $dir, $files ) = @_;
my $info = Module::Metadata->new_from_file( $file );
my $version = $info->version;
- # information about a directory full of .pm files
- my $provides =
- Module::Metadata->package_versions_from_directory('lib');
+ # CPAN META 'provides' field for .pm files in a directory
+ my $provides = Module::Metadata->provides(dir => 'lib');
=head1 DESCRIPTION
Can be called as either an object or a class method.
+=item C<< provides( %options ) >>
+
+This is a convenience wrapper around C<package_versions_from_directory>
+to generate a CPAN META C<provides> data structure. It takes key/value
+pairs. Valid option keys include:
+
+=over
+
+=item dir
+
+Directory to search recursively for F<.pm> files. May not be specified with
+C<files>.
+
+=item files
+
+Array reference of files to examine. May not be specified with C<dir>.
+
+=item prefix
+
+String to prepend to the C<file> field of the resulting output. This defaults
+to F<lib>, which is the common case for most CPAN distributions with their
+F<.pm> files in F<lib>. This option ensures the META information has the
+correct relative path even when the C<dir> or C<files> arguments are
+absolute or have relative paths from a location other than the distribution
+root.
+
+=back
+
+For example, given C<dir> of 'lib' and C<prefix> of 'lib', the return value
+is a hashref of the form:
+
+ {
+ 'Package::Name' => {
+ version => '0.123',
+ file => 'lib/Package/Name.pm'
+ },
+ 'OtherPackage::Name' => ...
+ }
+
=item C<< package_versions_from_directory($dir, \@files?) >>
Scans C<$dir> for .pm files (unless C<@files> is given, in which case looks
'OtherPackage::Name' => ...
}
+The C<DB> and C<main> packages are always omitted, as are any "private"
+packages that have leading underscores in the namespace (e.g.
+C<Foo::_private>)
+
+Note that the file path is relative to C<$dir> if that is specified.
+This B<must not> be used directly for CPAN META C<provides>. See
+the C<provides> method instead.
+
=item C<< log_info (internal) >>
Used internally to perform logging; imported from Log::Contextual if
);
my %modules = reverse @modules;
-plan tests => 40 + 2 * keys( %modules );
+plan tests => 42 + 2 * keys( %modules );
require_ok('Module::Metadata');
my $got_pvfd = Module::Metadata->package_versions_from_directory('lib');
-is_deeply( $got_pvfd, $exp_pvfd, "package_version_from_directory" )
+is_deeply( $got_pvfd, $exp_pvfd, "package_version_from_directory()" )
or diag explain $got_pvfd;
+
+{
+ my $got_provides = Module::Metadata->provides(dir => 'lib');
+ my $exp_provides = {
+ 'Simple' => {
+ 'file' => 'lib/Simple.pm',
+ 'version' => '0.01'
+ },
+ 'Simple::Ex' => {
+ 'file' => 'lib/Simple.pm',
+ 'version' => '0.02'
+ }
+ };
+
+ is_deeply( $got_provides, $exp_provides, "provides()" )
+ or diag explain $got_provides;
+}
+
+{
+ my $got_provides = Module::Metadata->provides(dir => 'lib', prefix => 'other');
+ my $exp_provides = {
+ 'Simple' => {
+ 'file' => 'other/Simple.pm',
+ 'version' => '0.01'
+ },
+ 'Simple::Ex' => {
+ 'file' => 'other/Simple.pm',
+ 'version' => '0.02'
+ }
+ };
+
+ is_deeply( $got_provides, $exp_provides, "provides()" )
+ or diag explain $got_provides;
+}