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