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