package Dist::Zilla::Role::Rinci::CheckDefinesMeta;
our $DATE = '2016-01-17'; # DATE
our $VERSION = '0.04'; # VERSION
use 5.010001;
use Moose::Role;
sub check_dist_defines_rinci_meta {
no strict 'refs';
my $self = shift;
# cache result
state $res;
return $res if defined $res;
$res = 0;
{
my $files = $self->zilla->find_files(':InstallModules');
local @INC = ("lib", @INC);
for my $file (@$files) {
my $name = $file->name;
next if $name =~ /\.pod\z/i;
$name =~ s!\Alib/!!;
require $name;
my $pkg = $name; $pkg =~ s/\.pm\z//; $pkg =~ s!/!::!g;
if (keys %{"$pkg\::SPEC"}) {
$self->log_debug(["Found that %%%s\::SPEC contains stuffs",
$pkg]);
$res = 1;
goto DONE;
}
}
}
{
require File::Temp;
require PPI::Document;
my $files = $self->zilla->find_files(':ExecFiles');
for my $file (@$files) {
my $path = do {
# even though file is a DZF:OnDisk, name() won't always be the
# actual path (e.g. when we use DZP:AddFile::FromFS which
# creates a DZF:OnDisk object which points to src but then
# re-set the name to dest), so in any case we need to write to
# tempfile first
my ($temp_fh, $temp_path) = File::Temp::tempfile();
print $temp_fh $file->content;
$temp_path;
};
#$self->log(["path=%s (exists? %s)", $path, ((-f $path) ? 1:0)]);
my $doc = PPI::Document->new($path);
for my $node ($doc->children) {
next unless $node->isa("PPI::Statement");
my @chld = $node->children;
next unless @chld;
next unless $chld[0]->isa("PPI::Token::Symbol") &&
$chld[0]->content =~ /\A\$(main::)?SPEC\z/;
my $i = 1;
while ($i < @chld) {
last unless $chld[$i]->isa("PPI::Token::Whitespace");
$i++;
}
next unless $i < @chld;
next unless $chld[$i]->isa("PPI::Structure::Subscript") &&
$chld[$i]->content =~ /\A\{/;
$i++;
while ($i < @chld) {
last unless $chld[$i]->isa("PPI::Token::Whitespace");
$i++;
}
next unless $i < @chld;
next unless $chld[$i]->isa("PPI::Token::Operator") &&
$chld[$i]->content eq '=';
$self->log_debug(
['Found that %s contains assignment to $SPEC{...}',
$file->name]);
$res = 1;
goto DONE;
}
}
}
DONE:
$res;
}
no Moose::Role;
1;
# ABSTRACT: Role to check if dist defines Rinci metadata
__END__
=pod
=encoding UTF-8
=head1 NAME
Dist::Zilla::Role::Rinci::CheckDefinesMeta - Role to check if dist defines Rinci metadata
=head1 VERSION
This document describes version 0.04 of Dist::Zilla::Role::Rinci::CheckDefinesMeta (from Perl distribution Dist-Zilla-Role-Rinci-CheckDefinesMeta), released on 2016-01-17.
=head1 METHODS
=head2 $obj->check_dist_defines_rinci_meta => bool
Will return true if dist defines Rinci metadata. Currently this is done via the
following: 1) load all the module files and check whether C<%SPEC> in the
corresponding package contains stuffs; 2) analyze all the scripts using L<PPI>
and try to find any assignment like C<< $SPEC{something} = { ... } >> (this
might miss some stuffs).
=head1 SEE ALSO
L<Rinci>
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/Dist-Zilla-Role-Rinci-CheckDefinesMeta>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-Dist-Zilla-Role-Rinci-CheckDefinesMeta>.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Role-Rinci-CheckDefinesMeta>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut