File Coverage

blib/lib/Pod/Weaver/Section/Version.pm
Criterion Covered Total %
statement 63 68 92.6
branch 15 26 57.6
condition 3 3 100.0
subroutine 15 15 100.0
pod 1 3 33.3
total 97 115 84.3


line stmt bran cond sub pod time code
1             package Pod::Weaver::Section::Version 4.020;
2             # ABSTRACT: add a VERSION pod section
3              
4 7     7   32767 use Moose;
  7         20  
  7         106  
5             with 'Pod::Weaver::Role::Section',
6             'Pod::Weaver::Role::StringFromComment';
7              
8             # BEGIN BOILERPLATE
9 7     7   57187 use v5.20.0;
  7         72  
10 7     7   45 use warnings;
  7         13  
  7         499  
11 7     7   47 use utf8;
  7         13  
  7         67  
12 7     7   315 no feature 'switch';
  7         19  
  7         1399  
13 7     7   49 use experimental qw(postderef postderef_qq); # This experiment gets mainlined.
  7         14  
  7         67  
14             # END BOILERPLATE
15              
16 7     7   749 use Module::Runtime qw(use_module);
  7         15  
  7         67  
17 7     7   490 use namespace::autoclean;
  7         29  
  7         98  
18              
19             #pod =head1 OVERVIEW
20             #pod
21             #pod This section plugin will produce a hunk of Pod meant to indicate the version of
22             #pod the document being viewed, like this:
23             #pod
24             #pod =head1 VERSION
25             #pod
26             #pod version 1.234
27             #pod
28             #pod It will do nothing if there is no C<version> entry in the input.
29             #pod
30             #pod =attr header
31             #pod
32             #pod The title of the header to be added.
33             #pod (default: "VERSION")
34             #pod
35             #pod =cut
36              
37             has header => (
38             is => 'ro',
39             isa => 'Str',
40             default => 'VERSION',
41             );
42              
43 7     7   8440 use DateTime;
  7         3069332  
  7         538  
44              
45             {
46             # This is irritating.
47             #
48             # Moose::Util::TypeConstraints will turn on strict and warnings. This will
49             # undermine the setup that "use experimental" did above. So I could move
50             # this above my boilerplate pragmata. But this is annoying too, where the
51             # order of libraries is based on largely invisible factors. I now believe
52             # that "Moose stuff turns on strict!" was a mistake, even if a
53             # well-intentioned one. So it goes.
54             #
55             # So, I'm putting it in a block. Why? Because the "use strict" that gets
56             # exported is *lexical* and so will be constrained by this block. The named
57             # subroutines, though, are *global* so they will still work.
58             #
59             # Can't push me around, perl! -- rjbs, 2024-03-21
60 7     7   126 use Moose::Util::TypeConstraints;
  7         18  
  7         114  
61             }
62              
63             my $MARKER;
64 7     7   21002 BEGIN { $MARKER = "\x{2316}" }
65              
66             use String::Formatter 0.100680 stringf => {
67             -as => '_format_version',
68              
69             input_processor => 'require_single_input',
70             string_replacer => 'method_replace',
71             codes => {
72 17         2812 v => sub { $_[0]->{version} },
73             V => sub { $_[0]->{version}
74             . ($_[0]->{is_trial}
75 0 0       0 ? (defined $_[1] ? $_[1] : '-TRIAL') : '') },
    0          
76              
77             d => sub {
78 1         20 use_module( 'DateTime', '0.44' ); # CLDR fixes
79             DateTime->from_epoch(epoch => $^T, time_zone => $_[0]->{self}->time_zone)
80 1         134 ->format_cldr($_[1]),
81             },
82 0         0 r => sub { $_[0]->{zilla}->name },
83             m => sub {
84 2 50       38 return $_[0]->{module} if defined $_[0]->{module};
85             $_[0]->{self}->log_fatal([
86             "%%m format used for Version section, but no package declaration found in %s",
87             $_[0]->{filename},
88 0         0 ]);
89             },
90              
91 4         304 T => sub { $MARKER },
92 0         0 n => sub { "\n" },
93 0         0 s => sub { q{ } },
94 6         467 t => sub { "\t" },
95             },
96 7     7   6394 };
  7         25145  
  7         195  
97              
98             # Needed by Config::MVP.
99 17     17 0 79737 sub mvp_multivalue_args { 'format' }
100              
101             #pod =attr format
102             #pod
103             #pod The string to use when generating the version string.
104             #pod
105             #pod Default: version %v
106             #pod
107             #pod The following variables are available:
108             #pod
109             #pod =begin :list
110             #pod
111             #pod * v - the version
112             #pod
113             #pod * V - the version, suffixed by "-TRIAL" if a trial release
114             #pod
115             #pod * d - the CLDR format for L<DateTime>
116             #pod
117             #pod * n - a newline
118             #pod
119             #pod * t - a tab
120             #pod
121             #pod * s - a space
122             #pod
123             #pod * r - the name of the dist, present only if you use L<Dist::Zilla> to generate
124             #pod the POD!
125             #pod
126             #pod * m - the name of the module, present only if L<PPI> parsed the document and it
127             #pod contained a package declaration!
128             #pod
129             #pod * T - special: at the beginning of the line, followed by any amount of
130             #pod whitespace, indicates that the line should only be included in trial
131             #pod releases; otherwise, results in a fatal error
132             #pod
133             #pod =end :list
134             #pod
135             #pod If multiple strings are supplied as an array ref, a line of POD is
136             #pod produced for each string. Each line will be separated by a newline.
137             #pod This is useful for splitting longer text across multiple lines in a
138             #pod C<weaver.ini> file, for example:
139             #pod
140             #pod ; weaver.ini
141             #pod [Version]
142             #pod format = version %v
143             #pod format =
144             #pod format = This module's version numbers follow the conventions described at
145             #pod format = L<semver.org|http://semver.org/>.
146             #pod format = %T
147             #pod format = %T This is a trial release!
148             #pod
149             #pod =cut
150              
151             subtype 'Pod::Weaver::Section::Version::_Format',
152             as 'ArrayRef[Str]';
153              
154             coerce 'Pod::Weaver::Section::Version::_Format',
155             from 'Str',
156             via { [ $_ ] };
157              
158             has format => (
159             is => 'ro',
160             isa => 'Pod::Weaver::Section::Version::_Format',
161             coerce => 1,
162             default => 'version %v',
163             );
164              
165             #pod =attr is_verbatim
166             #pod
167             #pod A boolean value specifying whether the version paragraph should be verbatim or not.
168             #pod
169             #pod Default: false
170             #pod
171             #pod =cut
172              
173             has is_verbatim => (
174             is => 'ro',
175             isa => 'Bool',
176             default => 0,
177             );
178              
179             #pod =attr time_zone
180             #pod
181             #pod The timezone to use when using L<DateTime> for the format.
182             #pod
183             #pod Default: local
184             #pod
185             #pod =cut
186              
187             has time_zone => (
188             is => 'ro',
189             isa => 'Str', # should be more validated later -- apocal
190             default => 'local',
191             );
192              
193             #pod =method build_content
194             #pod
195             #pod my @pod_elements = $section->build_content(\%input);
196             #pod
197             #pod This method is passed the same C<\%input> that goes to the C<weave_section>
198             #pod method, and should return a list of pod elements to insert.
199             #pod
200             #pod In almost all cases, this method is used internally, but could be usefully
201             #pod overridden in a subclass.
202             #pod
203             #pod =cut
204              
205             sub build_content {
206 17     17 1 71 my ($self, $input) = @_;
207 17 50       83 return unless $input->{version};
208              
209             my %args = (
210             self => $self,
211             version => $input->{version},
212             filename => $input->{filename},
213 17         137 );
214 17 50       76 $args{zilla} = $input->{zilla} if exists $input->{zilla};
215              
216             $args{is_trial} = exists $input->{is_trial} ? $input->{is_trial}
217             : $args{zilla} ? $args{zilla}->is_trial
218 17 50       163 : undef;
    100          
219              
220 17 50       64 if ( exists $input->{ppi_document} ) {
221 17         101 my $pkg_node = $input->{ppi_document}->find_first('PPI::Statement::Package');
222             $args{module}
223             = $pkg_node
224             ? $pkg_node->namespace
225 17 100       5654 : $self->_extract_comment_content($input->{ppi_document}, 'PODNAME')
226             ;
227             }
228              
229 17         783 my $content = q{};
230 17         995 LINE: for my $format ($self->format->@*) {
231 30         205 my $line = _format_version($format, \%args);
232 30 100 100     3370 next if $line =~ s/^$MARKER\s*// and ! $args{is_trial};
233              
234 28 50       206 Carp::croak("%T format used inside line") if $line =~ /$MARKER/;
235              
236 28         94 $content .= "$line\n";
237             }
238              
239 17 100       897 if ( $self->is_verbatim ) {
240 3         168 $content = Pod::Elemental::Element::Pod5::Verbatim->new({
241             content => " $content",
242             });
243             } else {
244 14         745 $content = Pod::Elemental::Element::Pod5::Ordinary->new({
245             content => $content,
246             });
247             }
248              
249 17         5736 return ($content);
250             }
251              
252             sub weave_section {
253 17     17 0 68 my ($self, $document, $input) = @_;
254 17 50       137 return unless $input->{version};
255              
256 17         102 my @content = $self->build_content($input);
257              
258 17         890 $self->log_debug('adding ' . $self->header . ' section to pod');
259              
260 17         1473 push $document->children->@*,
261             Pod::Elemental::Element::Nested->new({
262             command => 'head1',
263             content => $self->header,
264             children => \@content,
265             });
266             }
267              
268             __PACKAGE__->meta->make_immutable;
269             1;
270              
271             __END__
272              
273             =pod
274              
275             =encoding UTF-8
276              
277             =head1 NAME
278              
279             Pod::Weaver::Section::Version - add a VERSION pod section
280              
281             =head1 VERSION
282              
283             version 4.020
284              
285             =head1 OVERVIEW
286              
287             This section plugin will produce a hunk of Pod meant to indicate the version of
288             the document being viewed, like this:
289              
290             =head1 VERSION
291              
292             version 1.234
293              
294             It will do nothing if there is no C<version> entry in the input.
295              
296             =head1 PERL VERSION
297              
298             This module should work on any version of perl still receiving updates from
299             the Perl 5 Porters. This means it should work on any version of perl
300             released in the last two to three years. (That is, if the most recently
301             released version is v5.40, then this module should work on both v5.40 and
302             v5.38.)
303              
304             Although it may work on older versions of perl, no guarantee is made that the
305             minimum required version will not be increased. The version may be increased
306             for any reason, and there is no promise that patches will be accepted to
307             lower the minimum required perl.
308              
309             =head1 ATTRIBUTES
310              
311             =head2 header
312              
313             The title of the header to be added.
314             (default: "VERSION")
315              
316             =head2 format
317              
318             The string to use when generating the version string.
319              
320             Default: version %v
321              
322             The following variables are available:
323              
324             =over 4
325              
326             =item *
327              
328             v - the version
329              
330             =item *
331              
332             V - the version, suffixed by "-TRIAL" if a trial release
333              
334             =item *
335              
336             d - the CLDR format for L<DateTime>
337              
338             =item *
339              
340             n - a newline
341              
342             =item *
343              
344             t - a tab
345              
346             =item *
347              
348             s - a space
349              
350             =item *
351              
352             r - the name of the dist, present only if you use L<Dist::Zilla> to generate the POD!
353              
354             =item *
355              
356             m - the name of the module, present only if L<PPI> parsed the document and it contained a package declaration!
357              
358             =item *
359              
360             T - special: at the beginning of the line, followed by any amount of whitespace, indicates that the line should only be included in trial releases; otherwise, results in a fatal error
361              
362             =back
363              
364             If multiple strings are supplied as an array ref, a line of POD is
365             produced for each string. Each line will be separated by a newline.
366             This is useful for splitting longer text across multiple lines in a
367             C<weaver.ini> file, for example:
368              
369             ; weaver.ini
370             [Version]
371             format = version %v
372             format =
373             format = This module's version numbers follow the conventions described at
374             format = L<semver.org|http://semver.org/>.
375             format = %T
376             format = %T This is a trial release!
377              
378             =head2 is_verbatim
379              
380             A boolean value specifying whether the version paragraph should be verbatim or not.
381              
382             Default: false
383              
384             =head2 time_zone
385              
386             The timezone to use when using L<DateTime> for the format.
387              
388             Default: local
389              
390             =head1 METHODS
391              
392             =head2 build_content
393              
394             my @pod_elements = $section->build_content(\%input);
395              
396             This method is passed the same C<\%input> that goes to the C<weave_section>
397             method, and should return a list of pod elements to insert.
398              
399             In almost all cases, this method is used internally, but could be usefully
400             overridden in a subclass.
401              
402             =head1 AUTHOR
403              
404             Ricardo SIGNES <cpan@semiotic.systems>
405              
406             =head1 COPYRIGHT AND LICENSE
407              
408             This software is copyright (c) 2024 by Ricardo SIGNES.
409              
410             This is free software; you can redistribute it and/or modify it under
411             the same terms as the Perl 5 programming language system itself.
412              
413             =cut