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   51935 use 5.008;
  3         32  
2 3     3   16 use strict;
  3         6  
  3         61  
3 3     3   13 use warnings;
  3         7  
  3         172  
4              
5             package Perl::PrereqScanner 1.024;
6             # ABSTRACT: a tool to scan your Perl code for its prerequisites
7              
8 3     3   1685 use Moose;
  3         1423014  
  3         23  
9              
10 3     3   21556 use List::Util qw(max);
  3         7  
  3         249  
11 3     3   17 use Params::Util qw(_CLASS);
  3         6  
  3         131  
12 3     3   2306 use Perl::PrereqScanner::Scanner;
  3         10  
  3         112  
13 3     3   1707 use PPI 1.215; # module_version, bug fixes
  3         294705  
  3         170  
14 3         24 use String::RewritePrefix 0.005 rewrite => {
15             -as => '__rewrite_scanner',
16             prefixes => { '' => 'Perl::PrereqScanner::Scanner::', '=' => '' },
17 3     3   1407 };
  3         2962  
18              
19 3     3   2330 use CPAN::Meta::Requirements 2.124; # normalized v-strings
  3         18354  
  3         102  
20              
21 3     3   1620 use namespace::autoclean;
  3         22020  
  3         13  
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   1702 my $class = __rewrite_scanner($_[0]);
32 540 50       12683 confess "illegal class name: $class" unless _CLASS($class);
33 540 50       33577 eval "require $class; 1" or die $@;
34 540         2871 return $class->new;
35             }
36              
37             sub __prepare_scanners {
38 90     90   263 my ($self, $specs) = @_;
39 90 50       256 my @scanners = map {; ref $_ ? $_ : __scanner_from_str($_) } @$specs;
  540         61266  
40              
41 90         12149 return \@scanners;
42             }
43              
44             sub BUILD {
45 90     90 0 183500 my ($self, $arg) = @_;
46              
47 90 50       217 my @scanners = @{ $arg->{scanners} || [ qw(Perl5 Superclass TestMore Moose Aliased POE) ] };
  90         942  
48 90 50       441 my @extra_scanners = @{ $arg->{extra_scanners} || [] };
  90         501  
49              
50 90         444 my $scanners = $self->__prepare_scanners([ @scanners, @extra_scanners ]);
51              
52 90         3117 $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 88861 my ($self, $str) = @_;
72 89         648 my $ppi = PPI::Document->new( \$str );
73 89 100       172019 confess "PPI parse failed: " . PPI::Document->errstr unless defined $ppi;
74              
75 88         426 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 142661 my ($self, $path) = @_;
91 89         985 my $ppi = PPI::Document->new( $path );
92 89 50       288311 confess "PPI failed to parse '$path': " . PPI::Document->errstr
93             unless defined $ppi;
94              
95 89         528 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 187920 my ($self, $ppi_doc) = @_;
109              
110 265         2024 my $req = CPAN::Meta::Requirements->new;
111              
112 265         5291 for my $scanner (@{ $self->{scanners} }) {
  265         1004  
113 1590         32976 $scanner->scan_for_prereqs($ppi_doc, $req);
114             }
115              
116 265         4360 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 68 my ($self, $module_name) = @_;
131              
132             # consider rewriting to use Module::Which -- rjbs, 2013-11-03
133 1         698 require Module::Path;
134 1 50       685 if (defined(my $path = Module::Path::module_path($module_name))) {
135 1         220 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.024
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 <rjbs@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 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             Tina Mueller <tinita@cpan.org>
343              
344             =item *
345              
346             Vyacheslav Matjukhin <mmcleric@yandex-team.ru>
347              
348             =back
349              
350             =head1 COPYRIGHT AND LICENSE
351              
352             This software is copyright (c) 2009 by Jerome Quelin.
353              
354             This is free software; you can redistribute it and/or modify it under
355             the same terms as the Perl 5 programming language system itself.
356              
357             =cut
358              
359             __END__
360              
361             #pod =for Pod::Coverage::TrustPod
362             #pod new
363             #pod
364             #pod =head1 SYNOPSIS
365             #pod
366             #pod use Perl::PrereqScanner;
367             #pod my $scanner = Perl::PrereqScanner->new;
368             #pod my $prereqs = $scanner->scan_ppi_document( $ppi_doc );
369             #pod my $prereqs = $scanner->scan_file( $file_path );
370             #pod my $prereqs = $scanner->scan_string( $perl_code );
371             #pod my $prereqs = $scanner->scan_module( $module_name );
372             #pod
373             #pod =head1 DESCRIPTION
374             #pod
375             #pod The scanner will extract loosely your distribution prerequisites from your
376             #pod files.
377             #pod
378             #pod The extraction may not be perfect but tries to do its best. It will currently
379             #pod find the following prereqs:
380             #pod
381             #pod =begin :list
382             #pod
383             #pod * plain lines beginning with C<use> or C<require> in your perl modules and scripts, including minimum perl version
384             #pod
385             #pod * regular inheritance declared with the C<base> and C<parent> pragmata
386             #pod
387             #pod * L<Moose> inheritance declared with the C<extends> keyword
388             #pod
389             #pod * L<Moose> roles included with the C<with> keyword
390             #pod
391             #pod * OO namespace aliasing using the C<aliased> module
392             #pod
393             #pod =end :list
394             #pod
395             #pod =head2 Scanner Plugins
396             #pod
397             #pod Perl::PrereqScanner works by running a series of scanners over a PPI::Document
398             #pod representing the code to scan. By default the "Perl5", "Moose", "TestMore",
399             #pod "POE", and "Aliased" scanners are run. You can supply your own scanners when
400             #pod constructing your PrereqScanner:
401             #pod
402             #pod # Us only the Perl5 scanner:
403             #pod my $scanner = Perl::PrereqScanner->new({ scanners => [ qw(Perl5) ] });
404             #pod
405             #pod # Use any stock scanners, plus Example:
406             #pod my $scanner = Perl::PrereqScanner->new({ extra_scanners => [ qw(Example) ] });
407             #pod
408             #pod =head1 SEE ALSO
409             #pod
410             #pod L<scan-perl-prereqs>, in this distribution, is a command-line interface to the scanner
411             #pod
412             #pod =cut