File Coverage

blib/lib/Dist/Zilla/Plugin/AutoVersion/Relative.pm
Criterion Covered Total %
statement 47 51 92.1
branch 1 2 50.0
condition n/a
subroutine 16 19 84.2
pod 1 1 100.0
total 65 73 89.0


line stmt bran cond sub pod time code
1 2     2   59581 use 5.006; # our
  2         7  
2 2     2   7 use strict;
  2         2  
  2         40  
3 2     2   13 use warnings;
  2         2  
  2         215  
4              
5             package Dist::Zilla::Plugin::AutoVersion::Relative;
6              
7             our $VERSION = '1.001001';
8              
9             # ABSTRACT: Time-Relative versioning
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 2     2   953 use Moose 1.09 qw( has around with );
  2         660930  
  2         16  
14 2     2   9522 use MooseX::Types::Moose qw( Int Str );
  2         84193  
  2         19  
15 2     2   8306 use MooseX::Types::DateTime qw( TimeZone Duration Now );
  2         744874  
  2         14  
16 2     2   4447 use MooseX::StrictConstructor 0.10;
  2         35668  
  2         13  
17              
18 2     2   14417 use Const::Fast qw( const );
  2         1687  
  2         11  
19              
20             const my $MONTHS_IN_YEAR => 12;
21              
22             const my $DAYS_IN_MONTH => 31; # This is assumed, makes our years square.
23              
24             with( 'Dist::Zilla::Role::VersionProvider', 'Dist::Zilla::Role::TextTemplate' );
25              
26 2     2   216 use DateTime ();
  2         4  
  2         26  
27 2     2   14 use namespace::autoclean;
  2         3  
  2         17  
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41              
42              
43              
44              
45             has major => ( isa => Int, is => 'ro', default => 1 );
46             has minor => ( isa => Int, is => 'ro', default => 1 );
47             has format => ( ## no critic (RequireInterpolationOfMetachars)
48             isa => Str,
49             is => 'ro',
50             default => q|{{ sprintf('%d.%02d%04d%02d', $major, $minor, days, hours) }}|,
51             );
52              
53              
54              
55              
56              
57              
58              
59              
60              
61              
62              
63              
64              
65              
66              
67              
68              
69              
70              
71              
72              
73              
74              
75              
76              
77              
78              
79              
80              
81              
82              
83             has year => ( isa => Int, is => 'ro', default => 2000 );
84             has month => ( isa => Int, is => 'ro', default => 1 );
85             has day => ( isa => Int, is => 'ro', default => 1 );
86             has hour => ( isa => Int, is => 'ro', default => 0 );
87             has minute => ( isa => Int, is => 'ro', default => 0 );
88             has second => ( isa => Int, is => 'ro', default => 0 );
89             has time_zone => ( isa => TimeZone, coerce => 1, is => 'ro', predicate => 'has_time_zone' );
90              
91              
92              
93              
94              
95              
96              
97              
98              
99              
100              
101              
102              
103              
104              
105             has '_release_time' => ( isa => 'DateTime', coerce => 1, is => 'ro', lazy_build => 1 );
106             has '_current_time' => ( isa => 'DateTime', coerce => 1, is => 'ro', lazy_build => 1 );
107             has 'relative' => ( isa => Duration, coerce => 1, is => 'ro', lazy_build => 1 );
108              
109             if ( __PACKAGE__->can('dump_config') ) {
110             around dump_config => sub {
111             my ( $orig, $self, @args ) = @_;
112             my $config = $self->$orig(@args);
113             my $localconf = $config->{ +__PACKAGE__ } = {};
114              
115             $localconf->{major} = $self->major;
116             $localconf->{minor} = $self->minor;
117             $localconf->{format} = $self->format;
118             $localconf->{relative_to} = {
119             year => $self->year,
120             month => $self->month,
121             day => $self->day,
122             hour => $self->hour,
123             minute => $self->minute,
124             second => $self->second,
125             time_zone => q{} . $self->time_zone->name,
126             };
127              
128             $localconf->{ q[$] . __PACKAGE__ . '::VERSION' } = $VERSION
129             unless __PACKAGE__ eq ref $self;
130              
131             return $config;
132              
133             };
134             }
135              
136              
137              
138              
139              
140             sub _build__release_time {
141 5     5   5 my $self = shift;
142 5 50       146 return DateTime->new(
143             year => $self->year,
144             month => $self->month,
145             day => $self->day,
146             hour => $self->hour,
147             minute => $self->minute,
148             second => $self->second,
149             ( ( $self->has_time_zone ) ? ( time_zone => $self->time_zone ) : () ),
150             );
151             }
152              
153              
154              
155              
156              
157             sub _build__current_time {
158 4     4   23 return DateTime->now;
159             }
160              
161              
162              
163              
164              
165             sub _build_relative {
166 5     5   5 my $self = shift;
167 5         155 my $x = $self->_current_time->subtract_datetime( $self->_release_time );
168 5         1544 return $x;
169             }
170              
171              
172              
173              
174              
175              
176              
177             {
178             my $av_track = 0;
179              
180             sub provide_version {
181 5     5 1 26 my ($self) = @_;
182 5         4 $av_track++;
183              
184 5         190 my ( $y, $m, $d, $h, undef, undef ) = $self->relative->in_units( 'years', 'months', 'days', 'hours', 'minutes', 'seconds' );
185              
186             my ($days_square) = sub() {
187 0     0   0 ( ( ( ( $y * $MONTHS_IN_YEAR ) + $m ) * $DAYS_IN_MONTH ) + $d );
188 5         155 };
189             my ($days_accurate) = sub() {
190 5     5   2520 $self->_current_time->delta_days( $self->_release_time )->in_units('days');
191 5         11 };
192              
193             my $tokens = {
194             major => \( $self->major ),
195             minor => \( $self->minor ),
196             relative => \( $self->relative ),
197             cldr => sub($) {
198 0     0   0 my ($format) = shift;
199 0         0 $self->_current_time->format_cldr($format);
200             },
201             days => $days_accurate,
202             days_square => $days_square,
203             days_accurate => $days_accurate,
204 0     0   0 hours => sub() { $h },
205 5         161 };
206              
207 5         167 my $version = $self->fill_in_string( $self->format, $tokens, { 'package' => "AutoVersion::_${av_track}_", }, );
208 5         605 return $version;
209             }
210             }
211              
212              
213              
214              
215              
216              
217              
218              
219              
220              
221              
222              
223              
224              
225              
226              
227              
228              
229              
230              
231              
232              
233              
234              
235              
236              
237              
238              
239              
240              
241              
242              
243              
244              
245              
246              
247              
248              
249              
250              
251              
252              
253              
254              
255              
256              
257              
258              
259              
260              
261              
262              
263              
264              
265 2     2   1323 no Moose;
  2         2  
  2         17  
266             __PACKAGE__->meta->make_immutable;
267              
268             1;
269              
270             __END__
271              
272             =pod
273              
274             =encoding UTF-8
275              
276             =head1 NAME
277              
278             Dist::Zilla::Plugin::AutoVersion::Relative - Time-Relative versioning
279              
280             =head1 VERSION
281              
282             version 1.001001
283              
284             =head1 SYNOPSIS
285              
286             Like all things, time is relative.
287             This plugin is to allow you to auto-increment versions based on a relative time point.
288              
289             It doesn't do it all for you, you can choose, its mostly like L<< The C<AutoVersion> Plugin|Dist::Zilla::Plugin::AutoVersion >>
290             except there's a few more user-visible entities, and a few more visible options.
291              
292             =head1 CONFIGURATION
293              
294             To configure this, you specify the date that the version is to be
295             relative to.
296              
297             =head2 Serving Suggestion
298              
299             [AutoVersion::Relative]
300             major = 1
301             minor = 1
302             year = 2009 ; when we did our last major rev
303             month = 08 ; " "
304             day = 23 ; " "
305             hour = 05 ; " "
306             minute = 30 ; " "
307             second = 00 ; If you're that picky.
308              
309             time_zone = Pacific/Auckland ; You really want to set this.
310              
311             ; 1.0110012
312             format = {{$major}}.{{sprintf('%02d%04d%02d', $minor, days, hours }}
313              
314             For the list of tuneables and how to use them, see
315             L</ATTRIBUTES> and L</DATE ATTRIBUTES>
316              
317             =head1 FORMATTING
318              
319             There are a handful of things we inject into the template for you
320              
321             # Just to give you an idea, you don't really want to be using this though.
322             {{ $major }}.{{ $minor }}{{ days }}{{ hours }}{{ $relative->seconds }}
323              
324             See L</FORMAT FIELDS> for the available fields and their use.
325              
326             =head1 WARNING
327              
328             If you don't specify Y/M/D, it will default to Jan 01, 2000 , because I
329             couldn't think of a more sane default. But you're setting that anyway, because
330             if you don't,you be cargo cultin' the bad way
331              
332             =head1 ATTRIBUTES
333              
334             =head2 major
335              
336             =head2 major = 1
337              
338             =head2 minor
339              
340             =head2 minor = 1
341              
342             =head2 format
343              
344             =head2 format = {{ sprintf('%d.%02d%04d%02d', $major, $minor, days, hours) }}
345              
346             See L</FORMATING>
347              
348             =head1 DATE ATTRIBUTES
349              
350             =head2 year
351              
352             =head2 year = 2000
353              
354             =head2 month
355              
356             =head2 month = 1
357              
358             =head2 day
359              
360             =head2 day = 1
361              
362             =head2 minute
363              
364             =head2 minute = 0
365              
366             =head2 second
367              
368             =head2 second = 0
369              
370             =head2 time_zone
371              
372             You want this.
373              
374             Formatting is like, "Pacific/Auckland" , or merely "+1200" format.
375              
376             =head1 FORMAT FIELDS
377              
378             =head2 $major
379              
380             The value set for major
381              
382             =head2 $minor
383              
384             The value set for minor
385              
386             =head2 $relative
387              
388             A L<< C<DateTime::Duration>|DateTime::Duration >> object
389              
390             =head2 cldr
391              
392             =head2 cldr($ARG)
393              
394             CLDR for the current time. See L<DateTime/format_cldr>
395              
396             =head2 days
397              
398             See L</days_accurate>
399              
400             Used to use the algorithm as used in L</days_square> but uses the algorithm in L</days_accurate> since 0.03000000
401              
402             =head2 days_square
403              
404             An approximation of the number of days passed since milestone.
405              
406             Note that for this approximation, it is assumed all months are 31 days long, and years as such,
407             have 372 days.
408              
409             This is a legacy way of computing dates, superseded by days_accurate since 0.03000000
410              
411             =head2 days_accurate
412              
413             The number of days passed since the milestone.
414              
415             =head2 hours
416              
417             The remainder number of hours elapsed.
418              
419             =head1 METHODS
420              
421             =head2 provide_version
422              
423             returns the formatted version string to satisfy the roles.
424              
425             =head1 ATTRIBUTE METHODS
426              
427             =head2 has_time_zone <- predicate('time_zone')
428              
429             =head1 PRIVATE ATTRIBUTES
430              
431             =head2 _release_time
432              
433             =head2 _release_time DateTime[ro]
434              
435             =head2 _current_time
436              
437             =head2 _current_time DateTime[ro]
438              
439             =head2 relative
440              
441             =head2 relative Duration[ro]
442              
443             =head1 PRIVATE BUILDERS
444              
445             =head2 _build__release_time
446              
447             =head2 _build__current_time
448              
449             =head2 _build_relative
450              
451             =head1 AUTHOR
452              
453             Kent Fredric <kentnl@cpan.org>
454              
455             =head1 COPYRIGHT AND LICENSE
456              
457             This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.
458              
459             This is free software; you can redistribute it and/or modify it under
460             the same terms as the Perl 5 programming language system itself.
461              
462             =cut