File Coverage

blib/lib/Dist/Zilla/Plugin/ReportVersions/Tiny.pm
Criterion Covered Total %
statement 52 61 85.2
branch 11 14 78.5
condition 2 3 66.6
subroutine 8 12 66.6
pod 0 7 0.0
total 73 97 75.2


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::ReportVersions::Tiny;
2             $Dist::Zilla::Plugin::ReportVersions::Tiny::VERSION = '1.11';
3 4     4   27457 use Moose;
  4         1521038  
  4         30  
4             with 'Dist::Zilla::Role::FileGatherer';
5             with 'Dist::Zilla::Role::TextTemplate';
6             with 'Dist::Zilla::Role::PrereqSource';
7              
8 4     4   25264 use Dist::Zilla::File::FromCode;
  4         879467  
  4         274  
9 4     4   2765 use version;
  4         14928  
  4         36  
10              
11             before register_component => sub {
12             warn
13             '!!! [ReportVersions::Tiny] is deprecated; recommended alternative: [Test::ReportPrereqs]'
14             };
15              
16              
17 0     0 0 0 sub mvp_multivalue_args { qw{exclude include} };
18             has exclude => (is => 'ro', isa => 'ArrayRef', default => sub { [] });
19             has include => (is => 'ro', isa => 'ArrayRef', default => sub { [] });
20              
21             our $template = q{use strict;
22             use warnings;
23             use Test::More 0.88;
24             # This is a relatively nice way to avoid Test::NoWarnings breaking our
25             # expectations by adding extra tests, without using no_plan. It also helps
26             # avoid any other test module that feels introducing random tests, or even
27             # test plans, is a nice idea.
28             our $success = 0;
29             END { $success && done_testing; }
30              
31             # List our own version used to generate this
32             my $v = "\nGenerated by {{$my_package}} v{{$my_version}}\n";
33              
34             eval { # no excuses!
35             # report our Perl details
36             my $want = {{ $perl }};
37             $v .= "perl: $] (wanted $want) on $^O from $^X\n\n";
38             };
39             defined($@) and diag("$@");
40              
41             # Now, our module version dependencies:
42             sub pmver {
43             my ($module, $wanted) = @_;
44             $wanted = " (want $wanted)";
45             my $pmver;
46             eval "require $module;";
47             if ($@) {
48             if ($@ =~ m/Can't locate .* in \@INC/) {
49             $pmver = 'module not found.';
50             } else {
51             diag("${module}: $@");
52             $pmver = 'died during require.';
53             }
54             } else {
55             my $version;
56             eval { $version = $module->VERSION; };
57             if ($@) {
58             diag("${module}: $@");
59             $pmver = 'died during VERSION check.';
60             } elsif (defined $version) {
61             $pmver = "$version";
62             } else {
63             $pmver = '<undef>';
64             }
65             }
66              
67             # So, we should be good, right?
68             return sprintf('%-45s => %-10s%-15s%s', $module, $pmver, $wanted, "\n");
69             }
70              
71             {{$module_code}}
72              
73              
74             # All done.
75             $v .= <<'EOT';
76              
77             Thanks for using my code. I hope it works for you.
78             If not, please try and include this output in the bug report.
79             That will help me reproduce the issue and solve your problem.
80              
81             EOT
82              
83             diag($v);
84             ok(1, "we really didn't test anything, just reporting data");
85             $success = 1;
86              
87             # Work around another nasty module on CPAN. :/
88             no warnings 'once';
89             $Template::Test::NO_FLUSH = 1;
90             exit 0;
91             };
92              
93             sub applicable_modules {
94 5     5 0 1835 my ($self) = @_;
95              
96             # Extract the set of modules we depend on.
97 5         15 my %modules;
98 5         275 my $prereq = $self->zilla->prereqs->as_string_hash;
99              
100             # Identify the set of modules, and the highest version required.
101 5         684 for my $phase (qw<configure build test runtime>) {
102 20 100       25 for my $type (keys %{ $prereq->{$phase} || {} }) {
  20         94  
103 9 50       9 for my $module (keys %{ $prereq->{$phase}->{$type} || {} }) {
  9         39  
104 38 100 66     297 next if exists $modules{$module} and
105             $modules{$module} > version->parse($prereq->{$phase}->{$type}->{$module});
106              
107 22         164 $modules{$module} = version->parse( $prereq->{$phase}->{$type}->{$module} );
108             }
109             }
110             }
111              
112             # Cleanup
113 5         19 for my $module ( keys %modules ) {
114 22 100       17 if (grep { $module =~ m{$_} } @{ $self->exclude }) {
  8         72  
  22         931  
115 1         6 $self->log("Will not report version of excluded module ${module}.");
116 1         261 delete $modules{$module};
117             }
118             }
119              
120             # Add any "interesting" modules you might want reported
121 5         10 for my $include ( @{ $self->include } ){
  5         196  
122             # split by whitespace; also allow equal sign between "Mod::Name = 1.1"
123 3         18 my ( $module, $version ) = (split(/[ =]+/, $include), 0);
124 3         17 $self->log("Will also report version of included module ${module}.");
125 3         642 $modules{$module} = $version;
126             }
127              
128             # Turn objects back to strings.
129 5         18 for my $module ( keys %modules ) {
130 24 100       46 next unless ref $modules{$module};
131 21         102 $modules{$module} = "$modules{$module}";
132             }
133              
134 5         21 return \%modules;
135             }
136              
137             sub generate_eval_stubs {
138 3     3 0 8 my ( $self, $modules ) = @_;
139              
140 15         20 return join qq{\n}, map {
141 3         15 my $ver = $modules->{$_};
142 15 50       114 $ver = 'any version' if version->parse($ver) == 0;
143 15         130 sprintf q[eval { $v .= pmver('%s','%s') };], $_, $ver ;
144 3         6 } sort keys %{$modules};
145             };
146              
147             sub wanted_perl {
148 2     2 0 3 my ( $self, $modules ) = @_;
149 2         5 my $perl_version = delete $modules->{perl};
150 2 50       9 defined($perl_version) ? "'${perl_version}'" : '"any version"';
151             }
152              
153             sub generate_test_from_prereqs {
154 2     2 0 583 my ($self) = @_;
155              
156 2         9 my $modules = $self->applicable_modules;
157              
158 2         9 my $perl = $self->wanted_perl( $modules );
159 2         13 my $module_code = $self->generate_eval_stubs( $modules );
160              
161 2         47 my $content = $self->fill_in_string($template, {
162             perl => $perl,
163             module_code => $module_code,
164             my_version => __PACKAGE__->VERSION,
165             my_package => __PACKAGE__,
166             });
167              
168 2         3422 return $content;
169             }
170              
171             sub gather_files {
172 0     0 0   my ($self) = @_;
173              
174             my $file = Dist::Zilla::File::FromCode->new({
175             name => 't/000-report-versions-tiny.t',
176             mode => 0644,
177 0     0     code => sub { $self->generate_test_from_prereqs }
178 0           });
179              
180 0           $self->add_file($file);
181 0           return;
182             }
183              
184             sub register_prereqs {
185 0     0 0   my ($self) = @_;
186              
187             # Dependencies of the test file we generate
188 0           $self->zilla->register_prereqs(
189             { phase => 'test', type => 'requires' },
190             'Test::More' => '0.88',
191             );
192             # Our own dependencies to run this plugin
193             # (dependencies that the developer using ReportVersions::Tiny in his build
194             # will need to have. Listed with 'dzil listdeps --author'.)
195 0           $self->zilla->register_prereqs(
196             { phase => 'develop', type => 'requires' },
197             'version' => '0.9901',
198             );
199             }
200              
201              
202             __PACKAGE__->meta->make_immutable;
203 4     4   3314 no Moose;
  4         9  
  4         33  
204             1;
205              
206             __END__
207              
208             =pod
209              
210             =encoding utf8
211              
212             =head1 NAME
213              
214             Dist::Zilla::Plugin::ReportVersions::Tiny - (DEPRECATED) reports dependency versions during testing
215              
216             =head1 VERSION
217              
218             version 1.11
219              
220             =head1 SYNOPSIS
221              
222             In your F<dist.ini>, include C<[ReportVersions::Tiny]> to load the plugin.
223              
224             =head1 B<THIS PLUGIN IS DEPRECATED!>
225              
226             B<Alert:> This plugin is deprecated! It was already in low maintainance for
227             years. L<[Test::ReportPrereqs]|Dist::Zilla::Plugin::Test::ReportPrereqs> is
228             now much better (better implementation, better output, better maintainer),
229             so use it instead!
230              
231             =head1 DESCRIPTION
232              
233             This module integrates with L<Dist::Zilla> to automatically add an additional
234             test to your released software. Rather than testing features of the software,
235             this reports the versions of all static module dependencies, and of Perl, at
236             the time the tests are run.
237              
238             The value of this is that when someone submits a test failure report you can
239             see which versions of the modules were installed and, hopefully, be able to
240             reproduce problems that are dependent on a specific set of module versions.
241              
242             =head1 Differences from Dist::Zilla::Plugin::ReportVersions
243              
244             This module has the same goal as L<Dist::Zilla::Plugin::ReportVersions>, but
245             takes a much lighter weight approach: the module that inspired my code bundles
246             a copy of YAML::Tiny, reads META.yml, then reports from that.
247              
248             This gives the most accurate picture, since any requirements added at install
249             time will be detected, but is overkill for the vast majority of modules that
250             use a simple, static list of dependencies.
251              
252             This module, rather, generates the list of modules to test at the time the
253             distribution is being built, and reports from that static list.
254              
255             The biggest advantage of this is that I no longer have to bundle a large
256             volume of code that isn't really needed, and have a simpler test suite with
257             less places that things can go wrong.
258              
259             =head1 ARGUMENTS
260              
261             =over
262              
263             =item B<exclude>
264              
265             Exclude an individual items from version reporting.
266              
267             This is most commonly required if some module otherwise interferes with the
268             normal operation of the tests, such as L<Module::Install>, which does not
269             behave as you might expect if normally C<use>d.
270              
271             =item B<include>
272              
273             [ReportVersions::Tiny]
274             include = JSON:PP 2.27103
275             include = Path::Class
276             include = Some::Thing = 1.1
277              
278             Include extra modules in version reporting.
279             This can be specified multiple times. The module name and version can be
280             separated by spaces (and/or an equal sign). If no version is specified
281             "0" will be used.
282              
283             This can be useful to help track down issues in installation or testing
284             environments. Perhaps a module used by one of your prereqs is broken
285             and/or has a missing (or insufficient) dependency. You can use this option
286             to specify multiple extra modules whose versions you would like reported.
287             They aren't modules that you need to declare as prerequisites
288             since you don't use them directly, but you've found installation issues
289             and it would be nice to show which version (if any) is in fact installed.
290              
291             This option is inspired by advice from Andreas J. König (ANDK)
292             who suggested adding a list of "interesting modules" to the
293             F<Makefile.PL> and checking their version so that the test reports can show
294             which version (if any) is in fact installed
295             (see the L<CPAN> dist for an example).
296              
297             =back
298              
299             =head1 CAVEATS
300              
301             =over 4
302              
303             =item *
304              
305             The list of prereqs that are reported is built at C<dzil build> time. Not at
306             install time. This means that if the C<configure> step of the
307             L<builder|Dist::Zilla::Role::Builder> generates the list of prereqs dynamically
308             (see L<CPAN::Meta::Spec/dynamic_config>), that list I<may> not match the real
309             list of dependencies given to the CPAN client. In that case, you should use
310             instead L<Dist::Zilla::Plugin::Test::ReportPrereqs>. [L<RT#83266|https://rt.cpan.org/Ticket/Display.html?id=83266>]
311              
312             =item *
313              
314             Modules are loaded (C<require>-d, which means C<BEGIN> blocks and code outside
315             subs will run) to extract their versions. So this may have side effects.
316             To fix this, a future version of this plugin may use L<Module::Metadata> to
317             extract versions, and so add this module as a C<test> prereqs of your
318             distribution. [L<RT#76308|https://rt.cpan.org/Ticket/Display.html?id=76308>]
319              
320             =item *
321              
322             L<Version ranges|CPAN::Meta::Spec/Version Range> for prereqs are not supported.
323             If you use them, you should use instead
324             L<Dist::Zilla::Plugin::Test::ReportPrereqs>. [L<RT#87364|https://rt.cpan.org/Ticket/Display.html?id=87364>]
325              
326             =back
327              
328             =head1 SEE ALSO
329              
330             L<Test::ReportPrereqs> and L<Dist::Zilla::Plugin::Test::ReportPrereqs>
331              
332             =head1 AUTHORS
333              
334             Maintainer since 1.04: Olivier MenguE<eacute> L<mailto:dolmen@cpan.org>.
335              
336             Original author: Daniel Pittman <daniel@rimspace.net>.
337              
338             Contributors:
339              
340             =over 4
341              
342             =item Kent Fredric
343              
344             =item Randy Stauner
345              
346             =item Karen Etheridge
347              
348             =item Alexandr Ciornii
349              
350             =item Apocalypse
351              
352             =item Ricardo Signes
353              
354             =back
355              
356             =head1 COPYRIGHT AND LICENSE
357              
358             Copyright 2015 by Olivier MenguE<eacute> L<mailto:dolmen@cpan.org>
359             All Rights Reserved.
360              
361             This is free software; you can redistribute it and/or modify it under
362             the same terms as the Perl 5 programming language system itself.
363              
364             =cut