File Coverage

blib/lib/Dist/Zilla/Plugin/LatestPrereqs.pm
Criterion Covered Total %
statement 2 4 50.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 4 6 66.6


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::LatestPrereqs;
2             BEGIN {
3 1     1   775 $Dist::Zilla::Plugin::LatestPrereqs::VERSION = '0.4';
4             }
5              
6 1     1   483 use Moose;
  0            
  0            
7             use CPAN;
8             use Module::CoreList;
9             with 'Dist::Zilla::Role::PrereqSource';
10              
11             has 'skip_core_modules' => (
12             is => 'ro',
13             isa => 'Bool',
14             default => 0,
15             );
16              
17              
18             sub register_prereqs {
19             my ($self) = @_;
20             my $zilla = $self->zilla;
21             my $skip_core = $self->skip_core_modules;
22              
23             my $prereqs = $zilla->prereqs;
24             my $cpan = _startup_cpan();
25              
26             my $guts = $prereqs->cpan_meta_prereqs->{prereqs} || {};
27              
28             for my $phase (keys %$guts) {
29             for my $type (keys %{$guts->{$phase}}) {
30             my $prereqs = $guts->{$phase}{$type}->as_string_hash;
31              
32             for my $module (keys %$prereqs) {
33             $self->log_debug("Check '$module', type '$type' phase '$phase'");
34             ## allow for user defined required version
35             next if $prereqs->{$module};
36              
37             if ($skip_core) {
38             my $rel = Module::CoreList->first_release($module);
39             if ($rel && $rel <= $]) {
40             $self->log_debug("Skipping core module $module ($rel <= $])");
41             next;
42             }
43             }
44              
45             ## fetch latest version
46             $self->log_debug("Fetch latest version for '$module' from CPAN");
47             my $info = $cpan->expand('Module', $module);
48             unless ($info) {
49             $self->log("Could not find info on Module '$module'");
50             next;
51             }
52             next unless my $version = $info->cpan_version;
53              
54             ## register the latest version
55             $self->log_debug("Update version of '$module' to '$version'");
56             $zilla->register_prereqs(
57             { type => $type,
58             phase => $phase,
59             },
60             $module => $version,
61             );
62             }
63             }
64             }
65             }
66              
67             sub _startup_cpan {
68             ## Hide output of CPAN
69             $CPAN::Be_Silent++;
70              
71             return 'CPAN::Shell';
72             }
73              
74             __PACKAGE__->meta->make_immutable;
75             no Moose;
76             1;
77              
78             __END__
79              
80              
81             =head1 NAME
82              
83             Dist::Zilla::Plugin::LatestPrereqs - adjust prereqs to use latest version available
84              
85              
86             =head1 VERSION
87              
88             version 0.4
89              
90             =head1 SYNOPSIS
91              
92             At the B<BOTTOM> of your C<dist.ini> file:
93              
94             [LatestPrereqs]
95            
96             ## Optionally skip core modules
97             [LatestPrereqs]
98             skip_core_modules = 1
99            
100              
101             =head1 DESCRIPTION
102              
103             This plugin will filter over all your declared or discovered
104             prerequisites, contact CPAN, and adjust the version to the latest one
105             available.
106              
107             This will make sure that your module will be installed with the latest
108             version available on CPAN at the time you built your package.
109              
110             The most common use for this techinique is for L<Task> modules. You can
111             rebuild your Task module on a regular basis to make sure it has the
112             latest versions of your dependencies.
113              
114             Please note that this plugin only makes sure that the version of the
115             prereq is the latest at the time you build your package, not the latest
116             at the time the package is installed.
117              
118             To do that it would require updates to the CPAN toolchain. Although I
119             would welcome that, this plugin implements the next best thing.
120              
121              
122             =head2 Core modules options
123              
124             B<NOTE WELL:> this feature should be considered alpha. The interface
125             might change in future versions.
126              
127             The option C<skip_core_modules> can be used to control the behaviour of
128             this plugin with core modules (as defined by the
129             L<Module::CoreList|Module::CoreList> API).
130              
131             If set to 1, we will skip forcing the latest version on modules that are
132             part of the perl core, version equal or below to the one used to release
133             the module.
134              
135             An example: you have two modules on your C<< [Prereqs] >> list,
136             C<Digest::SHA> part of the core since 5.009003, and C<HTTP::Tiny> part
137             of the core since 5.013009. With C<skip_core_modules=1>, the following
138             will happen:
139              
140             =over 4
141              
142             =item * If you release your module using perl 5.008009, both
143             C<Digest::SHA> and C<HTTP::Tiny> will be forced to the
144             lastest version.
145              
146             =item * If you release your module using perl 5.012003, the
147             C<Digest::SHA> will not be forced to the lastest version, but
148             C<HTTP::Tiny> will.
149              
150             =item * If you release your module using perl 5.014000, both
151             C<ExtUtils::MakeMaker> and C<HTTP::Tiny> will not be forced to the
152             lastest version.
153              
154             =back
155              
156             By default (0) all modules will get the latest version.
157              
158             Idealy we would make this decision based on the perl version of the
159             person that will install your distribution, but for now that is not
160             easy to do.
161              
162              
163             =head1 EXTRA REQUIREMENTS
164              
165             This plugin uses the L<CPAN> module, but hides the output, so make sure
166             you have your cpan shell properly configured before trying to use this.
167              
168              
169             =head1 BUGS
170              
171             This modules abuses the internals of the L<CPAN::Meta::Prereqs> module.
172             This is a bug, but right now that module does not provide an API to
173             traverse its internals.
174              
175             As soon as it does, I'll rewrite this module to use it.
176              
177             Until then, this module might break with new releases of
178             L<CPAN::Meta::Prereqs>.
179              
180              
181             =head1 CREDITS
182              
183             Marcel Gruenauer (hanekomu) described something like this in his
184             article "Repeatedly installing Task::* distributions":
185              
186             L<http://hanekomu.at/blog/dev/20091005-1227-repeatedly_installing_task_distributions.html>
187              
188             But the method he suggested does not work because it does not force the
189             latest version of the module to be installed.
190              
191             A L<Dist::Zilla> plugin that implements what Marcel describes is also
192             available, see L<Dist::Zilla::Plugin::MakeMaker::SkipInstall>.
193              
194             Mike Doherty added the first version of the skip core modules feature.
195              
196              
197             =head1 SEE ALSO
198              
199             L<Dist::Zilla>, L<Dist::Zilla::Plugin::MakeMaker::SkipInstall>.
200              
201              
202             =head1 AUTHOR
203              
204             Pedro Melo, C<< <melo at cpan.org> >>
205              
206              
207             =head1 COPYRIGHT & LICENSE
208              
209             Copyright 2009-2010 Pedro Melo.
210              
211             This program is free software; you can redistribute it and/or modify it
212             under the same terms as Perl itself.
213              
214              
215             =begin make-pod-coverage-happy
216              
217             =over 4
218              
219             =item register_prereqs()
220              
221             Loops over all the given prereqs and uses L<CPAN> to figure out which is
222             the latest version of the module.
223              
224             =back
225              
226             =end make-pod-coverage-happy
227              
228             =cut