Blame inc/Module/Install/Metadata.pm

Packit c9e8cb
#line 1
Packit c9e8cb
package Module::Install::Metadata;
Packit c9e8cb
Packit c9e8cb
use strict 'vars';
Packit c9e8cb
use Module::Install::Base;
Packit c9e8cb
Packit c9e8cb
use vars qw{$VERSION $ISCORE @ISA};
Packit c9e8cb
BEGIN {
Packit c9e8cb
	$VERSION = '0.67';
Packit c9e8cb
	$ISCORE  = 1;
Packit c9e8cb
	@ISA     = qw{Module::Install::Base};
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
my @scalar_keys = qw{
Packit c9e8cb
    name module_name abstract author version license
Packit c9e8cb
    distribution_type perl_version tests installdirs
Packit c9e8cb
};
Packit c9e8cb
Packit c9e8cb
my @tuple_keys = qw{
Packit c9e8cb
    build_requires requires recommends bundles
Packit c9e8cb
};
Packit c9e8cb
Packit c9e8cb
sub Meta            { shift        }
Packit c9e8cb
sub Meta_ScalarKeys { @scalar_keys }
Packit c9e8cb
sub Meta_TupleKeys  { @tuple_keys  }
Packit c9e8cb
Packit c9e8cb
foreach my $key (@scalar_keys) {
Packit c9e8cb
    *$key = sub {
Packit c9e8cb
        my $self = shift;
Packit c9e8cb
        return $self->{values}{$key} if defined wantarray and !@_;
Packit c9e8cb
        $self->{values}{$key} = shift;
Packit c9e8cb
        return $self;
Packit c9e8cb
    };
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
foreach my $key (@tuple_keys) {
Packit c9e8cb
    *$key = sub {
Packit c9e8cb
        my $self = shift;
Packit c9e8cb
        return $self->{values}{$key} unless @_;
Packit c9e8cb
Packit c9e8cb
        my @rv;
Packit c9e8cb
        while (@_) {
Packit c9e8cb
            my $module = shift or last;
Packit c9e8cb
            my $version = shift || 0;
Packit c9e8cb
            if ( $module eq 'perl' ) {
Packit c9e8cb
                $version =~ s{^(\d+)\.(\d+)\.(\d+)}
Packit c9e8cb
                             {$1 + $2/1_000 + $3/1_000_000}e;
Packit c9e8cb
                $self->perl_version($version);
Packit c9e8cb
                next;
Packit c9e8cb
            }
Packit c9e8cb
            my $rv = [ $module, $version ];
Packit c9e8cb
            push @rv, $rv;
Packit c9e8cb
        }
Packit c9e8cb
        push @{ $self->{values}{$key} }, @rv;
Packit c9e8cb
        @rv;
Packit c9e8cb
    };
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
# configure_requires is currently a null-op
Packit c9e8cb
sub configure_requires { 1 }
Packit c9e8cb
Packit c9e8cb
# Aliases for build_requires that will have alternative
Packit c9e8cb
# meanings in some future version of META.yml.
Packit c9e8cb
sub test_requires      { shift->build_requires(@_)  }
Packit c9e8cb
sub install_requires   { shift->build_requires(@_)  }
Packit c9e8cb
Packit c9e8cb
# Aliases for installdirs options
Packit c9e8cb
sub install_as_core    { $_[0]->installdirs('perl')   }
Packit c9e8cb
sub install_as_cpan    { $_[0]->installdirs('site')   }
Packit c9e8cb
sub install_as_site    { $_[0]->installdirs('site')   }
Packit c9e8cb
sub install_as_vendor  { $_[0]->installdirs('vendor') }
Packit c9e8cb
Packit c9e8cb
sub sign {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    return $self->{'values'}{'sign'} if defined wantarray and ! @_;
Packit c9e8cb
    $self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
Packit c9e8cb
    return $self;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub dynamic_config {
Packit c9e8cb
	my $self = shift;
Packit c9e8cb
	unless ( @_ ) {
Packit c9e8cb
		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
Packit c9e8cb
		return $self;
Packit c9e8cb
	}
Packit c9e8cb
	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
Packit c9e8cb
	return $self;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub all_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
Packit c9e8cb
    unless ( defined($file) ) {
Packit c9e8cb
        my $name = $self->name
Packit c9e8cb
            or die "all_from called with no args without setting name() first";
Packit c9e8cb
        $file = join('/', 'lib', split(/-/, $name)) . '.pm';
Packit c9e8cb
        $file =~ s{.*/}{} unless -e $file;
Packit c9e8cb
        die "all_from: cannot find $file from $name" unless -e $file;
Packit c9e8cb
    }
Packit c9e8cb
Packit c9e8cb
    $self->version_from($file)      unless $self->version;
Packit c9e8cb
    $self->perl_version_from($file) unless $self->perl_version;
Packit c9e8cb
Packit c9e8cb
    # The remaining probes read from POD sections; if the file
Packit c9e8cb
    # has an accompanying .pod, use that instead
Packit c9e8cb
    my $pod = $file;
Packit c9e8cb
    if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
Packit c9e8cb
        $file = $pod;
Packit c9e8cb
    }
Packit c9e8cb
Packit c9e8cb
    $self->author_from($file)   unless $self->author;
Packit c9e8cb
    $self->license_from($file)  unless $self->license;
Packit c9e8cb
    $self->abstract_from($file) unless $self->abstract;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub provides {
Packit c9e8cb
    my $self     = shift;
Packit c9e8cb
    my $provides = ( $self->{values}{provides} ||= {} );
Packit c9e8cb
    %$provides = (%$provides, @_) if @_;
Packit c9e8cb
    return $provides;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub auto_provides {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    return $self unless $self->is_admin;
Packit c9e8cb
Packit c9e8cb
    unless (-e 'MANIFEST') {
Packit c9e8cb
        warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
Packit c9e8cb
        return $self;
Packit c9e8cb
    }
Packit c9e8cb
Packit c9e8cb
    # Avoid spurious warnings as we are not checking manifest here.
Packit c9e8cb
Packit c9e8cb
    local $SIG{__WARN__} = sub {1};
Packit c9e8cb
    require ExtUtils::Manifest;
Packit c9e8cb
    local *ExtUtils::Manifest::manicheck = sub { return };
Packit c9e8cb
Packit c9e8cb
    require Module::Build;
Packit c9e8cb
    my $build = Module::Build->new(
Packit c9e8cb
        dist_name    => $self->name,
Packit c9e8cb
        dist_version => $self->version,
Packit c9e8cb
        license      => $self->license,
Packit c9e8cb
    );
Packit c9e8cb
    $self->provides(%{ $build->find_dist_packages || {} });
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub feature {
Packit c9e8cb
    my $self     = shift;
Packit c9e8cb
    my $name     = shift;
Packit c9e8cb
    my $features = ( $self->{values}{features} ||= [] );
Packit c9e8cb
Packit c9e8cb
    my $mods;
Packit c9e8cb
Packit c9e8cb
    if ( @_ == 1 and ref( $_[0] ) ) {
Packit c9e8cb
        # The user used ->feature like ->features by passing in the second
Packit c9e8cb
        # argument as a reference.  Accomodate for that.
Packit c9e8cb
        $mods = $_[0];
Packit c9e8cb
    } else {
Packit c9e8cb
        $mods = \@_;
Packit c9e8cb
    }
Packit c9e8cb
Packit c9e8cb
    my $count = 0;
Packit c9e8cb
    push @$features, (
Packit c9e8cb
        $name => [
Packit c9e8cb
            map {
Packit c9e8cb
                ref($_) ? ( ref($_) eq 'HASH' ) ? %$_
Packit c9e8cb
                                                : @$_
Packit c9e8cb
                        : $_
Packit c9e8cb
            } @$mods
Packit c9e8cb
        ]
Packit c9e8cb
    );
Packit c9e8cb
Packit c9e8cb
    return @$features;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub features {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
Packit c9e8cb
        $self->feature( $name, @$mods );
Packit c9e8cb
    }
Packit c9e8cb
    return $self->{values}->{features}
Packit c9e8cb
    	? @{ $self->{values}->{features} }
Packit c9e8cb
    	: ();
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub no_index {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    my $type = shift;
Packit c9e8cb
    push @{ $self->{values}{no_index}{$type} }, @_ if $type;
Packit c9e8cb
    return $self->{values}{no_index};
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub read {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    $self->include_deps( 'YAML', 0 );
Packit c9e8cb
Packit c9e8cb
    require YAML;
Packit c9e8cb
    my $data = YAML::LoadFile('META.yml');
Packit c9e8cb
Packit c9e8cb
    # Call methods explicitly in case user has already set some values.
Packit c9e8cb
    while ( my ( $key, $value ) = each %$data ) {
Packit c9e8cb
        next unless $self->can($key);
Packit c9e8cb
        if ( ref $value eq 'HASH' ) {
Packit c9e8cb
            while ( my ( $module, $version ) = each %$value ) {
Packit c9e8cb
                $self->can($key)->($self, $module => $version );
Packit c9e8cb
            }
Packit c9e8cb
        }
Packit c9e8cb
        else {
Packit c9e8cb
            $self->can($key)->($self, $value);
Packit c9e8cb
        }
Packit c9e8cb
    }
Packit c9e8cb
    return $self;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub write {
Packit c9e8cb
    my $self = shift;
Packit c9e8cb
    return $self unless $self->is_admin;
Packit c9e8cb
    $self->admin->write_meta;
Packit c9e8cb
    return $self;
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub version_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
    require ExtUtils::MM_Unix;
Packit c9e8cb
    $self->version( ExtUtils::MM_Unix->parse_version($file) );
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub abstract_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
    require ExtUtils::MM_Unix;
Packit c9e8cb
    $self->abstract(
Packit c9e8cb
        bless(
Packit c9e8cb
            { DISTNAME => $self->name },
Packit c9e8cb
            'ExtUtils::MM_Unix'
Packit c9e8cb
        )->parse_abstract($file)
Packit c9e8cb
     );
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub _slurp {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
Packit c9e8cb
    local *FH;
Packit c9e8cb
    open FH, "< $file" or die "Cannot open $file.pod: $!";
Packit c9e8cb
    do { local $/; <FH> };
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub perl_version_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
Packit c9e8cb
    if (
Packit c9e8cb
        $self->_slurp($file) =~ m/
Packit c9e8cb
        ^
Packit c9e8cb
        use \s*
Packit c9e8cb
        v?
Packit c9e8cb
        ([\d_\.]+)
Packit c9e8cb
        \s* ;
Packit c9e8cb
    /ixms
Packit c9e8cb
      )
Packit c9e8cb
    {
Packit c9e8cb
        my $v = $1;
Packit c9e8cb
        $v =~ s{_}{}g;
Packit c9e8cb
        $self->perl_version($1);
Packit c9e8cb
    }
Packit c9e8cb
    else {
Packit c9e8cb
        warn "Cannot determine perl version info from $file\n";
Packit c9e8cb
        return;
Packit c9e8cb
    }
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub author_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
    my $content = $self->_slurp($file);
Packit c9e8cb
    if ($content =~ m/
Packit c9e8cb
        =head \d \s+ (?:authors?)\b \s*
Packit c9e8cb
        ([^\n]*)
Packit c9e8cb
        |
Packit c9e8cb
        =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
Packit c9e8cb
        .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
Packit c9e8cb
        ([^\n]*)
Packit c9e8cb
    /ixms) {
Packit c9e8cb
        my $author = $1 || $2;
Packit c9e8cb
        $author =~ s{E<lt>}{<}g;
Packit c9e8cb
        $author =~ s{E<gt>}{>}g;
Packit c9e8cb
        $self->author($author); 
Packit c9e8cb
    }
Packit c9e8cb
    else {
Packit c9e8cb
        warn "Cannot determine author info from $file\n";
Packit c9e8cb
    }
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
sub license_from {
Packit c9e8cb
    my ( $self, $file ) = @_;
Packit c9e8cb
Packit c9e8cb
    if (
Packit c9e8cb
        $self->_slurp($file) =~ m/
Packit c9e8cb
        (
Packit c9e8cb
            =head \d \s+
Packit c9e8cb
            (?:licen[cs]e|licensing|copyright|legal)\b
Packit c9e8cb
            .*?
Packit c9e8cb
        )
Packit c9e8cb
        (=head\\d.*|=cut.*|)
Packit c9e8cb
        \z
Packit c9e8cb
    /ixms
Packit c9e8cb
      )
Packit c9e8cb
    {
Packit c9e8cb
        my $license_text = $1;
Packit c9e8cb
        my @phrases      = (
Packit c9e8cb
            'under the same (?:terms|license) as perl itself' => 'perl',        1,
Packit c9e8cb
            'GNU public license'                              => 'gpl',         1,
Packit c9e8cb
            'GNU lesser public license'                       => 'gpl',         1,
Packit c9e8cb
            'BSD license'                                     => 'bsd',         1,
Packit c9e8cb
            'Artistic license'                                => 'artistic',    1,
Packit c9e8cb
            'GPL'                                             => 'gpl',         1,
Packit c9e8cb
            'LGPL'                                            => 'lgpl',        1,
Packit c9e8cb
            'BSD'                                             => 'bsd',         1,
Packit c9e8cb
            'Artistic'                                        => 'artistic',    1,
Packit c9e8cb
            'MIT'                                             => 'mit',         1,
Packit c9e8cb
            'proprietary'                                     => 'proprietary', 0,
Packit c9e8cb
        );
Packit c9e8cb
        while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
Packit c9e8cb
            $pattern =~ s{\s+}{\\s+}g;
Packit c9e8cb
            if ( $license_text =~ /\b$pattern\b/i ) {
Packit c9e8cb
                if ( $osi and $license_text =~ /All rights reserved/i ) {
Packit c9e8cb
                        warn "LEGAL WARNING: 'All rights reserved' may invalidate Open Source licenses. Consider removing it.";
Packit c9e8cb
		}
Packit c9e8cb
                $self->license($license);
Packit c9e8cb
                return 1;
Packit c9e8cb
            }
Packit c9e8cb
        }
Packit c9e8cb
    }
Packit c9e8cb
Packit c9e8cb
    warn "Cannot determine license info from $file\n";
Packit c9e8cb
    return 'unknown';
Packit c9e8cb
}
Packit c9e8cb
Packit c9e8cb
1;