File Coverage

blib/lib/Perl/PrereqScanner/Scanner/PodWeaver/PluginBundle.pm
Criterion Covered Total %
statement 52 61 85.2
branch 17 30 56.6
condition 13 25 52.0
subroutine 10 10 100.0
pod 0 1 0.0
total 92 127 72.4


line stmt bran cond sub pod time code
1             # ABSTRACT: scan for required plugins in Pod::Weaver plugin bundles
2              
3             ######################################################################
4             # Copyright (C) 2021 Asher Gordon <AsDaGo@posteo.net> #
5             # #
6             # This program is free software: you can redistribute it and/or #
7             # modify it under the terms of the GNU General Public License as #
8             # published by the Free Software Foundation, either version 3 of #
9             # the License, or (at your option) any later version. #
10             # #
11             # This program is distributed in the hope that it will be useful, #
12             # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
14             # General Public License for more details. #
15             # #
16             # You should have received a copy of the GNU General Public License #
17             # along with this program. If not, see #
18             # <http://www.gnu.org/licenses/>. #
19             ######################################################################
20              
21             package Perl::PrereqScanner::Scanner::PodWeaver::PluginBundle;
22             $Perl::PrereqScanner::Scanner::PodWeaver::PluginBundle::VERSION = '0.001';
23 1     1   1735 use v5.18.0;
  1         4  
24 1     1   5 use strict;
  1         3  
  1         20  
25 1     1   6 use warnings;
  1         2  
  1         27  
26 1     1   5 use feature 'lexical_subs';
  1         3  
  1         113  
27 1     1   7 no warnings 'experimental::lexical_subs';
  1         3  
  1         39  
28 1     1   5 use namespace::autoclean;
  1         3  
  1         7  
29 1     1   74 use Moose;
  1         3  
  1         7  
30 1     1   8324 use Pod::Weaver::Config::Assembler;
  1         485706  
  1         772  
31              
32             with 'Perl::PrereqScanner::Scanner';
33              
34             #pod =head1 DESCRIPTION
35             #pod
36             #pod This scanner will look for the following indicators:
37             #pod
38             #pod =begin :list
39             #pod
40             #pod * array references of three elements, with the third being a hash
41             #pod reference
42             #pod
43             #pod =end :list
44             #pod
45             #pod This isn't perfect, but it's not really practical to be much better
46             #pod without actually running the code.
47             #pod
48             #pod =cut
49              
50             # Look for the first quoted string, possibly entering lists and
51             # expressions.
52             my sub find_quote;
53             sub find_quote {
54 16     16   87 foreach my $element (@_) {
55 22 100       81 return $element->string if $element->isa('PPI::Token::Quote');
56 15 100       63 if ($element->isa('PPI::Token::Word')) {
57 5         35 my $next = $element->snext_sibling;
58 5 100 66     152 return $element->literal if defined $next &&
      66        
59             $next->isa('PPI::Token::Operator') && $next eq '=>';
60             }
61 14 100 100     97 my $str = find_quote $element->children
62             if $element->isa('PPI::Structure::List') ||
63             $element->isa('PPI::Statement::Expression');
64 14 100       58 return $str if defined $str;
65             }
66 0         0 return;
67             }
68              
69             sub scan_for_prereqs {
70 1     1 0 38373 my ($self, $ppi_doc, $req) = @_;
71              
72 16   50     8360 my @nodes = grep { ($_->braces // '') eq '[]' }
73 1         3 @{$ppi_doc->find('PPI::Structure::Constructor')};
  1         10  
74 1         62 foreach my $node (@nodes) {
75 8         297 my @elements = $node->schildren;
76 8 50 33     141 @elements = $elements[0]->schildren if @elements == 1 &&
77             $elements[0]->isa('PPI::Statement');
78              
79             # Group the elements together as they appear in the list.
80 8         136 my @groups = [];
81 8         18 foreach my $element (@elements) {
82 42 100 66     160 if ($element->isa('PPI::Token::Operator') &&
83             $element =~ /^(?:,|=>)$/) {
84 16         124 push @groups, [];
85             }
86             else {
87 26         65 push @{$groups[-1]}, $element;
  26         87  
88             }
89             }
90              
91             # Make sure there are three elements, and that the last is a
92             # hash reference.
93 8 50       21 next unless @groups == 3;
94 8         21 my (undef, $plugin, $options) = @groups;
95 8 50       20 return unless @$options == 1;
96 8         17 ($options) = @$options;
97             return unless
98 8 50 50     36 $options->isa('PPI::Structure::Constructor') &&
      33        
99             ($options->braces // '') eq '{}';
100              
101             # Look for the first quoted string.
102 8         93 my $name = find_quote @$plugin;
103 8 50       73 if (defined $name) {
104 8         28 $name =
105             Pod::Weaver::Config::Assembler->expand_package($name);
106 8         589 $req->add_minimum($name => 0)
107             }
108             else {
109 0 0         ($node) = @$plugin if @$plugin;
110 0           my ($file, $line) = map $node->$_,
111             qw(logical_filename logical_line_number);
112 0           my $msg = 'Invalid plugin specification';
113 0 0 0       $msg .= ' at' if defined ($file // $line);
114 0 0         $msg .= " $file" if defined $file;
115 0 0         $msg .= " line $line" if defined $line;
116 0           $msg .= "\n";
117 0           warn $msg;
118             }
119             }
120             }
121              
122             __END__
123              
124             =pod
125              
126             =encoding UTF-8
127              
128             =head1 NAME
129              
130             Perl::PrereqScanner::Scanner::PodWeaver::PluginBundle - scan for required plugins in Pod::Weaver plugin bundles
131              
132             =head1 VERSION
133              
134             version 0.001
135              
136             =head1 DESCRIPTION
137              
138             This scanner will look for the following indicators:
139              
140             =over 4
141              
142             =item *
143              
144             array references of three elements, with the third being a hash reference
145              
146             =back
147              
148             This isn't perfect, but it's not really practical to be much better
149             without actually running the code.
150              
151             =head1 BUGS
152              
153             Please report any bugs or feature requests on the bugtracker website
154             L<https://rt.cpan.org/Public/Dist/Display.html?Name=Perl-PrereqScanner-Scanner-DistZilla-PluginBundle>
155             or by email to
156             L<bug-Perl-PrereqScanner-Scanner-DistZilla-PluginBundle@rt.cpan.org|mailto:bug-Perl-PrereqScanner-Scanner-DistZilla-PluginBundle@rt.cpan.org>.
157              
158             When submitting a bug or request, please include a test-file or a
159             patch to an existing test-file that illustrates the bug or desired
160             feature.
161              
162             =head1 AUTHOR
163              
164             Asher Gordon <AsDaGo@posteo.net>
165              
166             =head1 COPYRIGHT AND LICENSE
167              
168             Copyright (C) 2021 Asher Gordon <AsDaGo@posteo.net>
169              
170             This program is free software: you can redistribute it and/or modify
171             it under the terms of the GNU General Public License as published by
172             the Free Software Foundation, either version 3 of the License, or (at
173             your option) any later version.
174              
175             This program is distributed in the hope that it will be useful, but
176             WITHOUT ANY WARRANTY; without even the implied warranty of
177             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
178             General Public License for more details.
179              
180             You should have received a copy of the GNU General Public License
181             along with this program. If not, see <http://www.gnu.org/licenses/>.
182              
183             =cut