File Coverage

blib/lib/Devel/Modlist.pm
Criterion Covered Total %
statement 12 85 14.1
branch 3 52 5.7
condition 1 33 3.0
subroutine 5 10 50.0
pod 0 2 0.0
total 21 182 11.5


line stmt bran cond sub pod time code
1             #
2             # Read the manual page from the pod at end for details.
3             #
4             # Generate a list of modules used by a perl script that has just run.
5             #
6             package Devel::Modlist;
7              
8             require 5.6.0;
9 1     1   9197 use strict;
  1         2  
  1         185  
10              
11             # Suppress warnings without using the vars pragma
12             our ($VERSION, $reported, %options);
13             $VERSION = '0.801';
14              
15             BEGIN
16 1     1   913 {
17             # This defines a simple class that CPAN will use if it is requested
18             package Devel::Modlist::QuietCPAN;
19              
20 0     0   0 sub myprint { }
21 0     0   0 sub mywarn { shift; CPAN::Shell->mywarn(@_); }
  0         0  
22 0     0   0 sub mydie { shift; CPAN::Shell->mydie(@_); }
  0         0  
23             }
24              
25             sub report;
26              
27             sub import
28             {
29 0     0   0 shift(@_); # Lose the leading "classname" value
30              
31 0         0 grep($options{$_} = 1, @_);
32             }
33              
34             sub DB::DB
35             {
36 0 0   0 0 0 if ($options{stop})
37             {
38 0         0 report;
39 0         0 exit;
40             }
41             }
42              
43             sub report
44             {
45 1 50   1 0 6 return if $reported;
46              
47 1 50       5 unless (keys %options)
48             {
49 1   33     12 grep($options{$_} = 1,
50             split(/[, ]/, ($ENV{'Devel::Modlist'} || $ENV{Devel__Modlist})));
51             }
52             # The 'noreport' option is not documented in the pod. It is only used by
53             # the pod_coverage.t test suite, to prevent the loading of this module
54             # from triggering a usage report.
55 1 50       7 return if $options{noreport};
56              
57 0           local $!;
58 0           $^W = 0;
59 0           my $pkg;
60             my $inc;
61 0           my $format;
62 0           my %yaml;
63 0 0         my $fh = $options{stdout} ? \*STDOUT : \*STDERR;
64 0 0         $DB::trace = 0 if ($DB::trace);
65 0           my %files = %INC;
66             # We use this ourselves, so delete it all the time. They shouldn't need
67             # to see it here anyway.
68 0           delete $files{'strict.pm'};
69              
70             # Anything required from here on won't show up unless it was already there
71 0           require File::Spec;
72 0           my @order = (0 .. 2);
73 0 0         if ($options{nocore})
74             {
75 0           require Config; # Won't have to worry about grep'ing out this one :-)
76 0           for my $lib ($Config::Config{installprivlib},
77             $Config::Config{installarchlib})
78             {
79 0           for (keys %files)
80             {
81 0 0         delete $files{$_} if ("$lib/$_" eq $files{$_});
82             }
83             }
84             }
85 0 0         if (my @yaml = grep(/^yaml/, keys %options))
86             {
87 0           %yaml =
88             map
89             {
90 0           my ($k, $v) = split('=', $_, 2);
91 0   0       (substr($k, 4) || 'yaml', lc $v || 1)
      0        
92             } @yaml;
93             # In case they only specified formatting options, no explicit
94             # reference to the "yaml" option itself, set it for later tests:
95 0           $yaml{yaml}++;
96              
97             # Start by defaulting the indentation. Defaults are no indentation for
98             # the header and 4 spaces for the key/value pairs. If the user chose
99             # to suppress the header, don't alter the key/value indentation.
100 0   0       $yaml{headerindent} ||= 0;
101 0 0 0       $yaml{indent} = 4
102             unless (defined($yaml{indent}) or $yaml{header} eq 'none');
103             # The indent value is relative to the header indentation, unless the
104             # header is supressed
105 0 0         $yaml{indent} += $yaml{headerindent} unless $yaml{header} eq 'none';
106              
107             # 'yamlcomplete' means to output a complete YAML stream, i.e. '---'
108 0 0         print $fh '# Generated by ' . __PACKAGE__ . " $VERSION\n---\n"
109             if ($yaml{complete});
110              
111             # Default the header to 'Requires', then print it if it isn't "none".
112 0   0       $yaml{header} ||= 'Requires';
113 0 0         unless ($yaml{header} eq 'none')
114             {
115 0           print $fh ' ' x $yaml{headerindent} . "$yaml{header}:\n";
116             }
117             }
118 0 0 0       if ($options{cpan} or $options{cpandist})
119             {
120 0           require CPAN;
121              
122             # Defeat "used only once" warnings without using local() which breaks
123 0           $CPAN::Frontend = $CPAN::Config->{index_expire} = '';
124 0           $CPAN::Frontend = 'Devel::Modlist::QuietCPAN';
125 0           CPAN::HandleConfig->load;
126             # This is an arbitrary value to inhibit re-loading index files
127 0           $CPAN::Config->{index_expire} = 300;
128 0           my %seen_dist = ();
129 0           my ($modobj, $cpan_file);
130              
131 0           for $inc (sort keys %files)
132             {
133 0           $pkg = join('::', File::Spec->splitdir($inc));
134 0           $pkg =~ s/\.pm$//;
135 0 0         $modobj = CPAN::Shell->expand('Module', $pkg) or next;
136 0           $cpan_file = $modobj->cpan_file;
137 0 0         if ($seen_dist{$cpan_file})
138             {
139 0           delete $files{$inc};
140 0           next;
141             }
142             # Haven't seen it until now
143 0           $seen_dist{$cpan_file}++;
144 0 0         $files{$inc} = $cpan_file if $options{cpandist};
145             }
146             }
147             # To prevent options being evaluated EVERY loop iteration, we set a format
148             # and data ordering:
149 0 0 0       if ($yaml{yaml})
    0 0        
150             {
151 0 0         $format = $options{noversion} ? "- '%s'\n" : "'%s': %s\n";
152 0   0       $format = ' ' x ($yaml{indent} || 0) . $format;
153 0 0         @order = (2, 1) if $options{path};
154             }
155             elsif ($options{noversion} || $options{path} || $options{cpandist})
156             {
157 0           $format = "%s\n";
158 0 0 0       @order = (2) if ($options{path} || $options{cpandist});
159             # Only include the value (3rd) element
160             }
161             else
162             {
163 0           $format = "%-20s %6s\n";
164 0 0         @order = (2, 1) if $options{path};
165             }
166 0           for $inc (sort keys %files)
167             {
168             # Disable refs-checking so we can read VERSION values
169 1     1   5 no strict 'refs';
  1         2  
  1         265  
170              
171             # Set the default for $version to either empty string or zero,
172             # depending on user choice
173 0 0         my $default = $options{zerodefault} ? '0' : '';
174 0 0         next if ($inc =~ /\.(al|ix)$/);
175 0           $pkg = join('::', File::Spec->splitdir($inc));
176 0           $pkg =~ s/\.pm$//;
177 0 0         next if ($pkg eq __PACKAGE__); # After all...
178 0   0       my $version = ${"$pkg\::VERSION"} || '';
179 0   0       printf $fh $format, ($pkg, $version || $default, $files{$inc})[@order];
180             }
181              
182 0           $reported++;
183             }
184              
185 1     1   847 END { report }
186              
187             1;
188              
189             __END__
190              
191             =head1 NAME
192              
193             Devel::Modlist - Perl extension to collect module use information
194              
195             =head1 SYNOPSIS
196              
197             perl -d:Modlist script.pl
198              
199             =head1 DESCRIPTION
200              
201             The B<Devel::Modlist> utility is provided as a means by which to get a quick
202             run-down on which libraries and modules are being utilized by a given script.
203              
204             Just as compiler systems like I<gcc> provide dependancy information via
205             switches such as C<-M>, B<Devel::Modlist> is intended to assist script authors
206             in preparing dependancy information for potential users of their scripts.
207              
208             =head1 USAGE
209              
210             Usage of B<Devel::Modlist> is simple. The primary method of invocation is to
211             use the C<-d> option of Perl:
212              
213             perl -d:Modlist script.pl
214              
215             Alternately, one could use the C<-M> option:
216              
217             perl -MDevel::Modlist script.pl
218              
219             In the case of this module, the two are identical save for the amount of
220             typing (and option passing, see below). It is I<not> recommended that this
221             module be loaded directly by a script via the B<use> keyword, as that would
222             cause the dependancy reporting after I<every> invocation until it was removed
223             from the code.
224              
225             =head1 OPTIONS
226              
227             The following options may be specified to the package. These are specified either by:
228              
229             perl -MDevel::Modlist=option1[,option2,...]
230              
231             or
232              
233             perl -d:Modlist=option1[,option2,...]
234              
235             Options may also be given in an environment variable, which gets read at any
236             invocation in which there are B<no> options explicitly provided. If any
237             options are given in the invocation, then the environment variable is ignored. Two different names are recognized:
238              
239             Devel::Modlist
240             Devel__Modlist
241              
242             The latter is to accomodate shells that do not like the presence of C<::> in
243             an environment variable name.
244              
245             The options:
246              
247             =over 4
248              
249             =item stdout
250              
251             By default, the report is printed on the STDERR filehandle. If this option is
252             present, it is sent to STDOUT instead.
253              
254             =item cpan
255              
256             Reduce the resulting list of modules by using the data maintained in the local
257             I<CPAN> configuration area. The B<CPAN> module (see L<CPAN>) maintains a very
258             thorough representation of the contents of the archive, on a per-module basis.
259             Using this option means that if there are two or more modules that are parts
260             of the same distribution, only one will be reported (the one with the shortest
261             name). This is useful for generating a minimalist dependancy set that can in
262             turn be fed to the B<CPAN> C<install> command to ensure that all needed
263             modules are in fact present.
264              
265             =item cpandist
266              
267             This is identical to the option above, with the exception that it causes the
268             reported output to be the B<CPAN> filename rather than the module name in
269             the standard Perl syntax. This can also be fed to the B<CPAN> shell, but it
270             can also be used by other front-ends as a path component in fetching the
271             requisite file from an archive site. Since the name contains the version
272             number, this behaves as though I<noversion> (see below) was also set. If
273             both I<cpan> and I<cpandist> are set, this option (I<cpandist>) takes
274             precedence. If I<path> is also specified, this option again takes precedence.
275              
276             =item nocore
277              
278             Suppress the display of those modules that are a part of the Perl core. This
279             is dependant on the Perl private library area not being an exact substring of
280             the site-dependant library. The build process checks this for you prior to
281             install.
282              
283             =item noversion
284              
285             Suppress the inclusion of version information with the module names. If a
286             module has defined its version by means of the accepted standard of
287             declaring a variable C<$VERSION> in the package namespace, B<Devel::Modlist>
288             finds this and includes it in the report by default. Use this option to
289             override that default.
290              
291             =item zerodefault
292              
293             Also oriented towards the display of versions, this option tells the report
294             to use a zero (C<0>) as the default version if the package has not provided
295             a value. Otherwise, an empty string is displayed (unless B<noversion> is
296             given).
297              
298             =item path
299              
300             Display the path and filename of each module instead of the module name. Useful
301             for producing lists for later input to tools such as B<rpm>.
302              
303             =item yaml
304             =item yamlheader=NAME
305             =item yamlheaderindent=N
306             =item yamlindent=N
307             =item yamlcomplete
308              
309             (Experimental, some options and/or features may change in future releases.)
310              
311             If any B<yaml> option is present, the output format is in YAML rather than
312             simple text. Additionally, the options can exert a degree of control
313             over the format of the resulting YAML. Those options that take value must
314             provide them by using a C<=> character immediately followed by the value, with
315             no space surrounding the C<=>.
316              
317             =over 8
318              
319             =item yamlheader=NAME
320              
321             Specify a "header" for the YAML section being emitted. This roughly corresponds
322             to the name of the section (or item) in the resulting parsed YAML tree. (See
323             any of the YAML-related modules on CPAN for an explanation of how a YAML file
324             is transformed into a Perl data structure.) If no header value is specified,
325             the default is C<Requires>. If you wish to suppress this header entirely,
326             pass the special value C<none>, i.e., C<yamlheader=none>.
327              
328             =item yamlheaderindent=N
329              
330             Specify the indentation for the section header. By default, the header is
331             flush to the left, an indentation of 0. The value provided specifies the
332             number of space characters printed before the header.
333              
334             =item yamlindent=N
335              
336             Specify the indentation for the key/value pairs (or sequential-list items,
337             see below). This defaults to 4, and represents the number of leading spaces
338             on each line. If B<yamlheader> is set to C<none>, then this is not given a
339             default, thus allowing the lines to be left-flush in the absence of the
340             header. If you wish the lines to have no indentation, pass this option with
341             a value of C<0>; the default is only applied if the option is not explicitly
342             present. The indentation is relative to the value of B<yamlheaderindent>, so
343             if you provide a non-zero value for that option, it will be added to this one
344             (unless the header is suppressed by C<yamlheader=none>).
345              
346             =item yamlcomplete
347              
348             If this option is present, the output will be a complete YAML document, with
349             a comment identifying the generator and a C<---> separator. B<yamlheader> may
350             still be set to C<none> to supress the header, even when a complete document
351             is being generated.
352              
353             =back
354              
355             The B<yaml> option is just to allow selection of the YAML option without
356             making any adjustments to the formatting. If any of the other YAML options
357             are present, it will trigger this output format; an explicit B<yaml> would
358             be unnecessary.
359              
360             The YAML output format respects other options (B<stdout>, B<noversion>,
361             B<zerodefault>, etc.). If B<noversion> is given, the output is a sequential
362             list rather than key/value pairings. If B<path> is given, the keys (or
363             values of the sequential list) are pathnames. Whether pathnames or module
364             names are used, those values are always explicitly quoted in the YAML output.
365              
366             =item stop
367              
368             Exit before the first actual program line is executed. This provides for
369             fetching the dependancy list without actually running the full program. This
370             has a drawback: if the program uses any of B<require>, B<eval> or other
371             such mechanisms to load libraries after the compilation phase, these will
372             not be reported.
373              
374             =back
375              
376             =head1 CAVEATS
377              
378             Perl versions up to 5.6.0 cannot accept options to the C<-d:> flag as
379             with the C<-M> flag. Thus, to pass options one must use:
380              
381             perl -MDevel::Modlist=option1[,option2,...]
382              
383             Unfortunately, this inhibits the B<stop> option detailed earlier. To use this
384             option, an invocation of:
385              
386             perl -d:Modlist -MDevel::Modlist=option1[,option2,...]
387              
388             does the trick, as the first invocation puts the interpreter in debugging mode
389             (necessary for B<stop> to work) while the second causes the options to be
390             parsed and recorded by B<Devel::Modlist>.
391              
392             Versions of Perl from 5.6.1 onwards allow options to be included with the
393             C<-d:Modlist> flag.
394              
395             Because B<Devel::Modlist> uses the C<strict> pragma internally (as all modules
396             should), that pragma is always removed from the output to avoid generating a
397             false-positive.
398              
399             =head1 AUTHOR
400              
401             Randy J. Ray <rjray@blackperl.com>, using idea and prototype code provided by
402             Tim Bunce <Tim.Bunce@ig.co.uk>
403              
404             =head1 LICENSE
405              
406             This module and the code within are
407             released under the terms of the Artistic License 2.0
408             (http://www.opensource.org/licenses/artistic-license-2.0.php). This
409             code may be redistributed under either the Artistic License or the GNU
410             Lesser General Public License (LGPL) version 2.1
411             (http://www.opensource.org/licenses/lgpl-2.1.php).
412              
413             =cut