File Coverage

blib/lib/Dist/Zilla/Plugin/NextRelease.pm
Criterion Covered Total %
statement 63 65 96.9
branch 8 12 66.6
condition 5 7 71.4
subroutine 11 11 100.0
pod 0 3 0.0
total 87 98 88.7


line stmt bran cond sub pod time code
1             # ABSTRACT: update the next release number in your changelog
2              
3             use Moose;
4 5     5   4192 with (
  5         15  
  5         44  
5             'Dist::Zilla::Role::FileMunger',
6             'Dist::Zilla::Role::TextTemplate',
7             'Dist::Zilla::Role::AfterRelease',
8             );
9              
10             use Dist::Zilla::Pragmas;
11 5     5   34224  
  5         17  
  5         54  
12             use namespace::autoclean;
13 5     5   40  
  5         13  
  5         48  
14             use Dist::Zilla::Path;
15 5     5   403 use Moose::Util::TypeConstraints;
  5         12  
  5         66  
16 5     5   1472 use List::Util 'first';
  5         12  
  5         50  
17 5     5   11092 use String::Formatter 0.100680 stringf => {
  5         13  
  5         2757  
18             -as => '_format_version',
19              
20             input_processor => 'require_single_input',
21             string_replacer => 'method_replace',
22             codes => {
23             v => sub { $_[0]->zilla->version },
24 15         2811 d => sub {
25             require DateTime;
26 9         3693 DateTime->VERSION('0.44'); # CLDR fixes
27 9         1330664  
28             DateTime->from_epoch(epoch => $^T, time_zone => $_[0]->time_zone)
29 9         355 ->format_cldr($_[1]),
30             },
31             t => sub { "\t" },
32 0         0 n => sub { "\n" },
33 0         0 E => sub { $_[0]->_user_info('email') },
34 2         28 U => sub { $_[0]->_user_info('name') },
35 3         54 T => sub { $_[0]->zilla->is_trial
36 10 100 100     50165 ? ($_[1] // '-TRIAL') : '' },
37             V => sub { $_[0]->zilla->version
38 1 50 50     160 . ($_[0]->zilla->is_trial
39             ? ($_[1] // '-TRIAL') : '') },
40             P => sub {
41             my $releaser = first { $_->can('cpanid') } @{ $_[0]->zilla->plugins_with('-Releaser') };
42 1         12 $_[0]->log_fatal('releaser doesn\'t provide cpanid, but %P used') unless $releaser;
  1         6  
  1         26  
43 1 50       6 $releaser->cpanid;
44 1         4 },
45             },
46             };
47 5     5   3951  
  5         15289  
  5         117  
48             our $DEFAULT_TIME_ZONE = 'local';
49             has time_zone => (
50             is => 'ro',
51             isa => 'Str', # should be more validated later -- apocal
52             default => $DEFAULT_TIME_ZONE,
53             );
54              
55             has format => (
56             is => 'ro',
57             isa => 'Str', # should be more validated Later -- rjbs, 2008-06-05
58             default => '%-9v %{yyyy-MM-dd HH:mm:ssZZZZZ VVVV}d%{ (TRIAL RELEASE)}T',
59             );
60              
61             has filename => (
62             is => 'ro',
63             isa => 'Str',
64             default => 'Changes',
65             );
66              
67             has update_filename => (
68             is => 'ro',
69             isa => 'Str',
70             lazy => 1,
71             default => sub { $_[0]->filename },
72             );
73              
74             has user_stash => (
75             is => 'ro',
76             isa => 'Str',
77             default => '%User'
78             );
79              
80             has _user_stash_obj => (
81             is => 'ro',
82             isa => maybe_type( class_type('Dist::Zilla::Stash::User') ),
83             lazy => 1,
84             init_arg => undef,
85             default => sub { $_[0]->zilla->stash_named( $_[0]->user_stash ) },
86             );
87              
88             my ($self, $field) = @_;
89              
90 5     5   17 my $stash = $self->_user_stash_obj;
91              
92 5         177 $self->log_fatal([
93             "You must enter your %s in the [%s] section in ~/.dzil/config.ini",
94 5 100 66     250 $field, $self->user_stash
95             ]) unless $stash and defined(my $value = $stash->$field);
96              
97             return $value;
98             }
99 4         15  
100             my ($self) = @_;
101              
102             return _format_version($self->format, $self);
103 16     16 0 51 }
104              
105 16         481 has _original_changes_content => (
106             is => 'rw',
107             isa => 'Str',
108             init_arg => undef,
109             );
110              
111             my ($self) = @_;
112              
113             my ($file) = grep { $_->name eq $self->filename } @{ $self->zilla->files };
114             $self->log_fatal([ 'failed to find %s in the distribution', $self->filename ]) if not $file;
115 15     15 0 55  
116             # save original unmunged content, for replacing back in the repo later
117 15         46 my $content = $self->_original_changes_content($file->content);
  86         221  
  15         464  
118 15 50       123  
119             $content = $self->fill_in_string(
120             $content,
121 15         82 {
122             dist => \($self->zilla),
123 15         419 version => \($self->zilla->version),
124             NEXT => \($self->section_header),
125             },
126             );
127              
128             $self->log_debug([ 'updating contents of %s in memory', $file->name ]);
129             $file->content($content);
130             }
131              
132 14         111 # new release is part of distribution history, let's record that.
133 14         502 my ($self) = @_;
134             my $filename = $self->filename;
135             my ($gathered_file) = grep { $_->name eq $filename } @{ $self->zilla->files };
136             $self->log_fatal("failed to find $filename in the distribution") if not $gathered_file;
137             my $iolayer = sprintf(":raw:encoding(%s)", $gathered_file->encoding);
138 1     1 0 987  
139 1         54 # read original changelog
140 1         13 my $content = $self->_original_changes_content;
  2         30  
  1         42  
141 1 50       16  
142 1         41 # add the version and date to file content
143             my $delim = $self->delim;
144             my $header = $self->section_header;
145 1         47 $content =~ s{ (\Q$delim->[0]\E \s*) \$NEXT (\s* \Q$delim->[1]\E) }
146             {$1\$NEXT$2\n\n$header}xs;
147              
148 1         48 my $update_fn = $self->update_filename;
149 1         14 $self->log_debug([ 'updating contents of %s on disk', $update_fn ]);
150 1         137  
151             # and finally rewrite the changelog on disk
152 1         45 path($update_fn)->spew({binmode => $iolayer}, $content);
153 1         17 }
154              
155             __PACKAGE__->meta->make_immutable;
156 1         75 1;
157              
158             #pod =head1 SYNOPSIS
159             #pod
160             #pod In your F<dist.ini>:
161             #pod
162             #pod [NextRelease]
163             #pod
164             #pod In your F<Changes> file:
165             #pod
166             #pod {{$NEXT}}
167             #pod
168             #pod
169             #pod =head1 DESCRIPTION
170             #pod
171             #pod Tired of having to update your F<Changes> file by hand with the new
172             #pod version and release date / time each time you release your distribution?
173             #pod Well, this plugin is for you.
174             #pod
175             #pod Add this plugin to your F<dist.ini>, and the following to your
176             #pod F<Changes> file:
177             #pod
178             #pod {{$NEXT}}
179             #pod
180             #pod The C<NextRelease> plugin will then do 2 things:
181             #pod
182             #pod =over 4
183             #pod
184             #pod =item * At build time, this special marker will be replaced with the
185             #pod version and the build date, to form a standard changelog header. This
186             #pod will be done to the in-memory file - the original F<Changes> file won't
187             #pod be updated.
188             #pod
189             #pod =item * After release (when running C<dzil release>), since the version
190             #pod and build date are now part of your dist's history, the real F<Changes>
191             #pod file (not the in-memory one) will be updated with this piece of
192             #pod information.
193             #pod
194             #pod =back
195             #pod
196             #pod The module accepts the following options in its F<dist.ini> section:
197             #pod
198             #pod =begin :list
199             #pod
200             #pod = filename
201             #pod the name of your changelog file; defaults to F<Changes>
202             #pod
203             #pod = update_filename
204             #pod the file to which to write an updated changelog to; defaults to the C<filename>
205             #pod
206             #pod = format
207             #pod sprintf-like string used to compute the next value of C<{{$NEXT}}>;
208             #pod defaults to C<%-9v %{yyyy-MM-dd HH:mm:ssZZZZZ VVVV}d%{ (TRIAL RELEASE)}T>
209             #pod
210             #pod = time_zone
211             #pod the timezone to use when generating the date; defaults to I<local>
212             #pod
213             #pod = user_stash
214             #pod the name of the stash where the user's name and email address can be found;
215             #pod defaults to C<%User>
216             #pod
217             #pod =end :list
218             #pod
219             #pod The module allows the following sprintf-like format codes in the C<format>:
220             #pod
221             #pod =begin :list
222             #pod
223             #pod = C<%v>
224             #pod The distribution version
225             #pod
226             #pod = C<%{-TRIAL}T>
227             #pod Expands to -TRIAL (or any other supplied string) if this
228             #pod is a trial release, or the empty string if not. A bare C<%T> means
229             #pod C<%{-TRIAL}T>.
230             #pod
231             #pod = C<%{-TRIAL}V>
232             #pod Equivalent to C<%v%{-TRIAL}T>, to allow for the application of modifiers such
233             #pod as space padding to the entire version string produced.
234             #pod
235             #pod = C<%{CLDR format}d>
236             #pod The date of the release. You can use any CLDR format supported by
237             #pod L<DateTime>. You must specify the format; there is no default.
238             #pod
239             #pod = C<%U>
240             #pod The name of the user making this release (from C<user_stash>).
241             #pod
242             #pod = C<%E>
243             #pod The email address of the user making this release (from C<user_stash>).
244             #pod
245             #pod = C<%P>
246             #pod The CPAN (PAUSE) id of the user making this release (from -Releaser plugins;
247             #pod see L<[UploadToCPAN]|Dist::Zilla::Plugin::UploadToCPAN/username>).
248             #pod
249             #pod = C<%n>
250             #pod A newline
251             #pod
252             #pod = C<%t>
253             #pod A tab
254             #pod
255             #pod =end :list
256             #pod
257             #pod =head1 SEE ALSO
258             #pod
259             #pod Core Dist::Zilla plugins:
260             #pod L<AutoVersion|Dist::Zilla::Plugin::AutoVersion>,
261             #pod L<PkgVersion|Dist::Zilla::Plugin::PkgVersion>,
262             #pod L<PodVersion|Dist::Zilla::Plugin::PodVersion>.
263             #pod
264             #pod Dist::Zilla roles:
265             #pod L<AfterRelease|Dist::Zilla::Plugin::AfterRelease>,
266             #pod L<FileMunger|Dist::Zilla::Role::FileMunger>,
267             #pod L<TextTemplate|Dist::Zilla::Role::TextTemplate>.
268              
269              
270             =pod
271              
272             =encoding UTF-8
273              
274             =head1 NAME
275              
276             Dist::Zilla::Plugin::NextRelease - update the next release number in your changelog
277              
278             =head1 VERSION
279              
280             version 6.028
281              
282             =head1 SYNOPSIS
283              
284             In your F<dist.ini>:
285              
286             [NextRelease]
287              
288             In your F<Changes> file:
289              
290             {{$NEXT}}
291              
292             =head1 DESCRIPTION
293              
294             Tired of having to update your F<Changes> file by hand with the new
295             version and release date / time each time you release your distribution?
296             Well, this plugin is for you.
297              
298             Add this plugin to your F<dist.ini>, and the following to your
299             F<Changes> file:
300              
301             {{$NEXT}}
302              
303             The C<NextRelease> plugin will then do 2 things:
304              
305             =over 4
306              
307             =item * At build time, this special marker will be replaced with the
308             version and the build date, to form a standard changelog header. This
309             will be done to the in-memory file - the original F<Changes> file won't
310             be updated.
311              
312             =item * After release (when running C<dzil release>), since the version
313             and build date are now part of your dist's history, the real F<Changes>
314             file (not the in-memory one) will be updated with this piece of
315             information.
316              
317             =back
318              
319             The module accepts the following options in its F<dist.ini> section:
320              
321             =over 4
322              
323             =item filename
324              
325             the name of your changelog file; defaults to F<Changes>
326              
327             =item update_filename
328              
329             the file to which to write an updated changelog to; defaults to the C<filename>
330              
331             =item format
332              
333             sprintf-like string used to compute the next value of C<{{$NEXT}}>;
334             defaults to C<%-9v %{yyyy-MM-dd HH:mm:ssZZZZZ VVVV}d%{ (TRIAL RELEASE)}T>
335              
336             =item time_zone
337              
338             the timezone to use when generating the date; defaults to I<local>
339              
340             =item user_stash
341              
342             the name of the stash where the user's name and email address can be found;
343             defaults to C<%User>
344              
345             =back
346              
347             The module allows the following sprintf-like format codes in the C<format>:
348              
349             =over 4
350              
351             =item C<%v>
352              
353             The distribution version
354              
355             =item C<%{-TRIAL}T>
356              
357             Expands to -TRIAL (or any other supplied string) if this
358             is a trial release, or the empty string if not. A bare C<%T> means
359             C<%{-TRIAL}T>.
360              
361             =item C<%{-TRIAL}V>
362              
363             Equivalent to C<%v%{-TRIAL}T>, to allow for the application of modifiers such
364             as space padding to the entire version string produced.
365              
366             =item C<%{CLDR format}d>
367              
368             The date of the release. You can use any CLDR format supported by
369             L<DateTime>. You must specify the format; there is no default.
370              
371             =item C<%U>
372              
373             The name of the user making this release (from C<user_stash>).
374              
375             =item C<%E>
376              
377             The email address of the user making this release (from C<user_stash>).
378              
379             =item C<%P>
380              
381             The CPAN (PAUSE) id of the user making this release (from -Releaser plugins;
382             see L<[UploadToCPAN]|Dist::Zilla::Plugin::UploadToCPAN/username>).
383              
384             =item C<%n>
385              
386             A newline
387              
388             =item C<%t>
389              
390             A tab
391              
392             =back
393              
394             =head1 PERL VERSION
395              
396             This module should work on any version of perl still receiving updates from
397             the Perl 5 Porters. This means it should work on any version of perl released
398             in the last two to three years. (That is, if the most recently released
399             version is v5.40, then this module should work on both v5.40 and v5.38.)
400              
401             Although it may work on older versions of perl, no guarantee is made that the
402             minimum required version will not be increased. The version may be increased
403             for any reason, and there is no promise that patches will be accepted to lower
404             the minimum required perl.
405              
406             =head1 SEE ALSO
407              
408             Core Dist::Zilla plugins:
409             L<AutoVersion|Dist::Zilla::Plugin::AutoVersion>,
410             L<PkgVersion|Dist::Zilla::Plugin::PkgVersion>,
411             L<PodVersion|Dist::Zilla::Plugin::PodVersion>.
412              
413             Dist::Zilla roles:
414             L<AfterRelease|Dist::Zilla::Plugin::AfterRelease>,
415             L<FileMunger|Dist::Zilla::Role::FileMunger>,
416             L<TextTemplate|Dist::Zilla::Role::TextTemplate>.
417              
418             =head1 AUTHOR
419              
420             Ricardo SIGNES 😏 <cpan@semiotic.systems>
421              
422             =head1 COPYRIGHT AND LICENSE
423              
424             This software is copyright (c) 2022 by Ricardo SIGNES.
425              
426             This is free software; you can redistribute it and/or modify it under
427             the same terms as the Perl 5 programming language system itself.
428              
429             =cut