File Coverage

blib/lib/Perl/PrereqScanner.pm
Criterion Covered Total %
statement 65 66 98.4
branch 9 16 56.2
condition n/a
subroutine 18 18 100.0
pod 4 5 80.0
total 96 105 91.4


line stmt bran cond sub pod time code
1 3     3   49333 use 5.008;
  3         32  
2 3     3   13 use strict;
  3         11  
  3         57  
3 3     3   14 use warnings;
  3         3  
  3         136  
4              
5             package Perl::PrereqScanner 1.025;
6             # ABSTRACT: a tool to scan your Perl code for its prerequisites
7              
8 3     3   1324 use Moose;
  3         1145025  
  3         19  
9              
10 3     3   18394 use List::Util qw(max);
  3         6  
  3         224  
11 3     3   19 use Params::Util qw(_CLASS);
  3         5  
  3         119  
12 3     3   1430 use Perl::PrereqScanner::Scanner;
  3         9  
  3         101  
13 3     3   1431 use PPI 1.215; # module_version, bug fixes
  3         256051  
  3         165  
14 3         30 use String::RewritePrefix 0.005 rewrite => {
15             -as => '__rewrite_scanner',
16             prefixes => { '' => 'Perl::PrereqScanner::Scanner::', '=' => '' },
17 3     3   1040 };
  3         2761  
18              
19 3     3   2022 use CPAN::Meta::Requirements 2.124; # normalized v-strings
  3         17200  
  3         82  
20              
21 3     3   1162 use namespace::autoclean;
  3         19867  
  3         12  
22              
23             has scanners => (
24             is => 'ro',
25             isa => 'ArrayRef[Perl::PrereqScanner::Scanner]',
26             init_arg => undef,
27             writer => '_set_scanners',
28             );
29              
30             sub __scanner_from_str {
31 540     540   1560 my $class = __rewrite_scanner($_[0]);
32 540 50       11692 confess "illegal class name: $class" unless _CLASS($class);
33 540 50       29832 eval "require $class; 1" or die $@;
34 540         2712 return $class->new;
35             }
36              
37             sub __prepare_scanners {
38 90     90   206 my ($self, $specs) = @_;
39 90 50       191 my @scanners = map {; ref $_ ? $_ : __scanner_from_str($_) } @$specs;
  540         58613  
40              
41 90         11878 return \@scanners;
42             }
43              
44             sub BUILD {
45 90     90 0 158390 my ($self, $arg) = @_;
46              
47 90 50       174 my @scanners = @{ $arg->{scanners} || [ qw(Perl5 Superclass TestMore Moose Aliased POE) ] };
  90         630  
48 90 50       328 my @extra_scanners = @{ $arg->{extra_scanners} || [] };
  90         348  
49              
50 90         406 my $scanners = $self->__prepare_scanners([ @scanners, @extra_scanners ]);
51              
52 90         3105 $self->_set_scanners($scanners);
53             }
54              
55             #pod =method scan_string
56             #pod
57             #pod my $prereqs = $scanner->scan_string( $perl_code );
58             #pod
59             #pod Given a string containing Perl source code, this method returns a
60             #pod CPAN::Meta::Requirements object describing the modules it requires.
61             #pod
62             #pod This method will throw an exception if PPI fails to parse the code.
63             #pod
64             #pod B<Warning!> It isn't entirely clear whether PPI prefers to receive
65             #pod strings as octet strings or character strings. For now, my advice
66             #pod is to pass octet strings.
67             #pod
68             #pod =cut
69              
70             sub scan_string {
71 89     89 1 69611 my ($self, $str) = @_;
72 89         368 my $ppi = PPI::Document->new( \$str );
73 89 100       142847 confess "PPI parse failed: " . PPI::Document->errstr unless defined $ppi;
74              
75 88         255 return $self->scan_ppi_document( $ppi );
76             }
77              
78             #pod =method scan_file
79             #pod
80             #pod my $prereqs = $scanner->scan_file( $path );
81             #pod
82             #pod Given a file path to a Perl document, this method returns a
83             #pod CPAN::Meta::Requirements object describing the modules it requires.
84             #pod
85             #pod This method will throw an exception if PPI fails to parse the code.
86             #pod
87             #pod =cut
88              
89             sub scan_file {
90 89     89 1 138626 my ($self, $path) = @_;
91 89         638 my $ppi = PPI::Document->new( $path );
92 89 50       248131 confess "PPI failed to parse '$path': " . PPI::Document->errstr
93             unless defined $ppi;
94              
95 89         285 return $self->scan_ppi_document( $ppi );
96             }
97              
98             #pod =method scan_ppi_document
99             #pod
100             #pod my $prereqs = $scanner->scan_ppi_document( $ppi_doc );
101             #pod
102             #pod Given a L<PPI::Document>, this method returns a CPAN::Meta::Requirements object
103             #pod describing the modules it requires.
104             #pod
105             #pod =cut
106              
107             sub scan_ppi_document {
108 265     265 1 160055 my ($self, $ppi_doc) = @_;
109              
110 265         1171 my $req = CPAN::Meta::Requirements->new;
111              
112 265         3659 for my $scanner (@{ $self->{scanners} }) {
  265         638  
113 1590         24417 $scanner->scan_for_prereqs($ppi_doc, $req);
114             }
115              
116 265         3677 return $req;
117             }
118              
119             #pod =method scan_module
120             #pod
121             #pod my $prereqs = $scanner->scan_module( $module_name );
122             #pod
123             #pod Given the name of a module, eg C<'PPI::Document'>,
124             #pod this method returns a CPAN::Meta::Requirements object
125             #pod describing the modules it requires.
126             #pod
127             #pod =cut
128              
129             sub scan_module {
130 1     1 1 63 my ($self, $module_name) = @_;
131              
132             # consider rewriting to use Module::Which -- rjbs, 2013-11-03
133 1         459 require Module::Path;
134 1 50       600 if (defined(my $path = Module::Path::module_path($module_name))) {
135 1         180 return $self->scan_file($path);
136             }
137              
138 0           confess "Failed to find file for module '$module_name'";
139             }
140              
141             1;
142              
143             =pod
144              
145             =encoding UTF-8
146              
147             =head1 NAME
148              
149             Perl::PrereqScanner - a tool to scan your Perl code for its prerequisites
150              
151             =head1 VERSION
152              
153             version 1.025
154              
155             =head1 SYNOPSIS
156              
157             use Perl::PrereqScanner;
158             my $scanner = Perl::PrereqScanner->new;
159             my $prereqs = $scanner->scan_ppi_document( $ppi_doc );
160             my $prereqs = $scanner->scan_file( $file_path );
161             my $prereqs = $scanner->scan_string( $perl_code );
162             my $prereqs = $scanner->scan_module( $module_name );
163              
164             =head1 DESCRIPTION
165              
166             The scanner will extract loosely your distribution prerequisites from your
167             files.
168              
169             The extraction may not be perfect but tries to do its best. It will currently
170             find the following prereqs:
171              
172             =over 4
173              
174             =item *
175              
176             plain lines beginning with C<use> or C<require> in your perl modules and scripts, including minimum perl version
177              
178             =item *
179              
180             regular inheritance declared with the C<base> and C<parent> pragmata
181              
182             =item *
183              
184             L<Moose> inheritance declared with the C<extends> keyword
185              
186             =item *
187              
188             L<Moose> roles included with the C<with> keyword
189              
190             =item *
191              
192             OO namespace aliasing using the C<aliased> module
193              
194             =back
195              
196             =head2 Scanner Plugins
197              
198             Perl::PrereqScanner works by running a series of scanners over a PPI::Document
199             representing the code to scan. By default the "Perl5", "Moose", "TestMore",
200             "POE", and "Aliased" scanners are run. You can supply your own scanners when
201             constructing your PrereqScanner:
202              
203             # Us only the Perl5 scanner:
204             my $scanner = Perl::PrereqScanner->new({ scanners => [ qw(Perl5) ] });
205              
206             # Use any stock scanners, plus Example:
207             my $scanner = Perl::PrereqScanner->new({ extra_scanners => [ qw(Example) ] });
208              
209             =head1 PERL VERSION
210              
211             This library should run on perls released even a long time ago. It should work
212             on any version of perl released in the last five years.
213              
214             Although it may work on older versions of perl, no guarantee is made that the
215             minimum required version will not be increased. The version may be increased
216             for any reason, and there is no promise that patches will be accepted to lower
217             the minimum required perl.
218              
219             =head1 METHODS
220              
221             =head2 scan_string
222              
223             my $prereqs = $scanner->scan_string( $perl_code );
224              
225             Given a string containing Perl source code, this method returns a
226             CPAN::Meta::Requirements object describing the modules it requires.
227              
228             This method will throw an exception if PPI fails to parse the code.
229              
230             B<Warning!> It isn't entirely clear whether PPI prefers to receive
231             strings as octet strings or character strings. For now, my advice
232             is to pass octet strings.
233              
234             =head2 scan_file
235              
236             my $prereqs = $scanner->scan_file( $path );
237              
238             Given a file path to a Perl document, this method returns a
239             CPAN::Meta::Requirements object describing the modules it requires.
240              
241             This method will throw an exception if PPI fails to parse the code.
242              
243             =head2 scan_ppi_document
244              
245             my $prereqs = $scanner->scan_ppi_document( $ppi_doc );
246              
247             Given a L<PPI::Document>, this method returns a CPAN::Meta::Requirements object
248             describing the modules it requires.
249              
250             =head2 scan_module
251              
252             my $prereqs = $scanner->scan_module( $module_name );
253              
254             Given the name of a module, eg C<'PPI::Document'>,
255             this method returns a CPAN::Meta::Requirements object
256             describing the modules it requires.
257              
258             =for Pod::Coverage::TrustPod new
259              
260             =head1 SEE ALSO
261              
262             L<scan-perl-prereqs>, in this distribution, is a command-line interface to the scanner
263              
264             =head1 AUTHORS
265              
266             =over 4
267              
268             =item *
269              
270             Jerome Quelin
271              
272             =item *
273              
274             Ricardo Signes <cpan@semiotic.systems>
275              
276             =back
277              
278             =head1 CONTRIBUTORS
279              
280             =for stopwords bowtie celogeek Christopher J. Madsen David Golden Steinbrunner Ed J Florian Ragwitz Jakob Voss Jérôme Quelin John SJ Anderson Karen Etheridge Mark Gardner Neil Bowers Randy Stauner Ricardo Signes Tina Mueller Vyacheslav Matjukhin
281              
282             =over 4
283              
284             =item *
285              
286             bowtie <bowtie@cpan.org>
287              
288             =item *
289              
290             celogeek <me@celogeek.com>
291              
292             =item *
293              
294             Christopher J. Madsen <perl@cjmweb.net>
295              
296             =item *
297              
298             David Golden <dagolden@cpan.org>
299              
300             =item *
301              
302             David Steinbrunner <dsteinbrunner@pobox.com>
303              
304             =item *
305              
306             Ed J <mohawk2@users.noreply.github.com>
307              
308             =item *
309              
310             Florian Ragwitz <rafl@debian.org>
311              
312             =item *
313              
314             Jakob Voss <voss@gbv.de>
315              
316             =item *
317              
318             Jérôme Quelin <jquelin@gmail.com>
319              
320             =item *
321              
322             John SJ Anderson <genehack@genehack.org>
323              
324             =item *
325              
326             Karen Etheridge <ether@cpan.org>
327              
328             =item *
329              
330             Mark Gardner <gardnerm@gsicommerce.com>
331              
332             =item *
333              
334             Neil Bowers <neil@bowers.com>
335              
336             =item *
337              
338             Randy Stauner <rwstauner@cpan.org>
339              
340             =item *
341              
342             Ricardo Signes <rjbs@semiotic.systems>
343              
344             =item *
345              
346             Tina Mueller <tinita@cpan.org>
347              
348             =item *
349              
350             Vyacheslav Matjukhin <mmcleric@yandex-team.ru>
351              
352             =back
353              
354             =head1 COPYRIGHT AND LICENSE
355              
356             This software is copyright (c) 2009 by Jerome Quelin.
357              
358             This is free software; you can redistribute it and/or modify it under
359             the same terms as the Perl 5 programming language system itself.
360              
361             =cut
362              
363             __END__
364              
365             #pod =for Pod::Coverage::TrustPod
366             #pod new
367             #pod
368             #pod =head1 SYNOPSIS
369             #pod
370             #pod use Perl::PrereqScanner;
371             #pod my $scanner = Perl::PrereqScanner->new;
372             #pod my $prereqs = $scanner->scan_ppi_document( $ppi_doc );
373             #pod my $prereqs = $scanner->scan_file( $file_path );
374             #pod my $prereqs = $scanner->scan_string( $perl_code );
375             #pod my $prereqs = $scanner->scan_module( $module_name );
376             #pod
377             #pod =head1 DESCRIPTION
378             #pod
379             #pod The scanner will extract loosely your distribution prerequisites from your
380             #pod files.
381             #pod
382             #pod The extraction may not be perfect but tries to do its best. It will currently
383             #pod find the following prereqs:
384             #pod
385             #pod =begin :list
386             #pod
387             #pod * plain lines beginning with C<use> or C<require> in your perl modules and scripts, including minimum perl version
388             #pod
389             #pod * regular inheritance declared with the C<base> and C<parent> pragmata
390             #pod
391             #pod * L<Moose> inheritance declared with the C<extends> keyword
392             #pod
393             #pod * L<Moose> roles included with the C<with> keyword
394             #pod
395             #pod * OO namespace aliasing using the C<aliased> module
396             #pod
397             #pod =end :list
398             #pod
399             #pod =head2 Scanner Plugins
400             #pod
401             #pod Perl::PrereqScanner works by running a series of scanners over a PPI::Document
402             #pod representing the code to scan. By default the "Perl5", "Moose", "TestMore",
403             #pod "POE", and "Aliased" scanners are run. You can supply your own scanners when
404             #pod constructing your PrereqScanner:
405             #pod
406             #pod # Us only the Perl5 scanner:
407             #pod my $scanner = Perl::PrereqScanner->new({ scanners => [ qw(Perl5) ] });
408             #pod
409             #pod # Use any stock scanners, plus Example:
410             #pod my $scanner = Perl::PrereqScanner->new({ extra_scanners => [ qw(Example) ] });
411             #pod
412             #pod =head1 SEE ALSO
413             #pod
414             #pod L<scan-perl-prereqs>, in this distribution, is a command-line interface to the scanner
415             #pod
416             #pod =cut