File Coverage

blib/lib/Dist/Zilla/Plugin/RewriteVersion.pm
Criterion Covered Total %
statement 52 54 96.3
branch 20 24 83.3
condition 2 3 66.6
subroutine 10 10 100.0
pod 0 4 0.0
total 84 95 88.4


line stmt bran cond sub pod time code
1 6     6   3794494 use 5.008001;
  6         17  
2 6     6   25 use strict;
  6         8  
  6         119  
3 6     6   22 use warnings;
  6         8  
  6         312  
4              
5             package Dist::Zilla::Plugin::RewriteVersion;
6             # ABSTRACT: Get and/or rewrite module versions to match distribution version
7              
8             our $VERSION = '0.015';
9              
10 6     6   24 use Moose;
  6         7  
  6         43  
11 6     6   26799 use namespace::autoclean;
  6         9  
  6         45  
12 6     6   357 use version ();
  6         9  
  6         3591  
13              
14             #pod =attr allow_decimal_underscore
15             #pod
16             #pod Allows use of decimal versions with underscores. Default is false. (Version
17             #pod tuples with underscores are never allowed!)
18             #pod
19             #pod =cut
20              
21             has allow_decimal_underscore => (
22             is => 'ro',
23             isa => 'Bool',
24             );
25              
26             #pod =attr global
27             #pod
28             #pod If true, all occurrences of the version pattern will be replaced. Otherwise,
29             #pod only the first occurrence is replaced. Defaults to false.
30             #pod
31             #pod =cut
32              
33             has global => (
34             is => 'ro',
35             isa => 'Bool',
36             );
37              
38             #pod =attr skip_version_provider
39             #pod
40             #pod If true, rely on some other mechanism for determining the "current" version
41             #pod instead of extracting it from the C<main_module>. Defaults to false.
42             #pod
43             #pod This enables hard-coding C<version => in C<dist.ini> among other tricks.
44             #pod
45             #pod =cut
46              
47             has skip_version_provider => ( is => ro =>, lazy => 1, default => undef );
48              
49             #pod =attr add_tarball_name
50             #pod
51             #pod If true, when the version is written, it will append a comment with the name of
52             #pod the tarball it comes from. This helps users track down the source of a
53             #pod module if its name doesn't match the tarball name. If the module is
54             #pod a TRIAL release, that is also in the comment. For example:
55             #pod
56             #pod our $VERSION = '0.010'; # from Foo-Bar-0.010.tar.gz
57             #pod our $VERSION = '0.011'; # TRIAL from Foo-Bar-0.011-TRIAL.tar.gz
58             #pod
59             #pod This option defaults to false.
60             #pod
61             #pod =cut
62              
63             has add_tarball_name => ( is => ro =>, lazy => 1, default => undef );
64              
65             sub provide_version {
66 14     14 0 491046 my ($self) = @_;
67 14 100       564 return if $self->skip_version_provider;
68             # override (or maybe needed to initialize)
69 12 100       53 return $ENV{V} if exists $ENV{V};
70              
71 5         123 my $file = $self->zilla->main_module;
72 5         6234 my $content = $file->content;
73              
74 5         3342 my $assign_regex = $self->assign_re();
75              
76 5         140 my ( $quote, $version ) = $content =~ m{^$assign_regex[^\n]*$}ms;
77              
78 5 50       38 $self->log_debug( [ 'extracted version from main module: %s', $version ] )
79             if $version;
80 5         1256 return $version;
81             }
82              
83             sub munge_files {
84 14     14 0 7019 my $self = shift;
85 14         23 $self->munge_file($_) for @{ $self->found_files };
  14         66  
86 11         37 return;
87             }
88              
89             sub munge_file {
90 29     29 0 21877 my ( $self, $file ) = @_;
91              
92 29 50       93 return if $file->is_bytes;
93              
94 29 50       1298 if ( $file->name =~ m/\.pod$/ ) {
95 0         0 $self->log_debug( [ 'Skipping: "%s" is pod only', $file->name ] );
96 0         0 return;
97             }
98              
99 29         1615 my $version = $self->zilla->version;
100              
101 29         737 $self->check_valid_version($version);
102              
103 26 100       92 if ( $self->rewrite_version( $file, $version ) ) {
104 25         80 $self->log_debug( [ 'updating $VERSION assignment in %s', $file->name ] );
105             }
106             else {
107 1         4 $self->log( [ q[Skipping: no "our $VERSION = '...'" found in "%s"], $file->name ] );
108             }
109 26         6689 return;
110             }
111              
112             sub rewrite_version {
113 26     26 0 37 my ( $self, $file, $version ) = @_;
114              
115 26         92 my $content = $file->content;
116              
117 26         12146 my $code = "our \$VERSION = '$version';";
118 26 100       608 $code .= " # TRIAL" if $self->zilla->is_trial;
119              
120 26 100       6641 if ( $self->add_tarball_name ) {
121 2         43 my $tarball = $self->zilla->archive_filename;
122 2 50       165 $code .= ( $self->zilla->is_trial ? "" : " #" ) . " from $tarball";
123             }
124              
125 26 100 66     138 $code .= "\n\$VERSION = eval \$VERSION;"
126             if $version =~ /_/ and scalar( $version =~ /\./g ) <= 1;
127              
128 26         74 my $assign_regex = $self->assign_re();
129              
130 26 100       804 if (
    100          
131             $self->global
132             ? ( $content =~ s{^$assign_regex[^\n]*$}{$code}msg )
133             : ( $content =~ s{^$assign_regex[^\n]*$}{$code}ms )
134             )
135             {
136 25         72 $file->content($content);
137 25         4352 return 1;
138             }
139              
140 1         4 return;
141             }
142              
143             with(
144             'Dist::Zilla::Role::FileMunger' => { -version => 5 },
145             'Dist::Zilla::Role::VersionProvider',
146             'Dist::Zilla::Role::FileFinderUser' =>
147             { default_finders => [ ':InstallModules', ':ExecFiles' ], },
148             'Dist::Zilla::Plugin::BumpVersionAfterRelease::_Util',
149             );
150              
151             around dump_config => sub {
152             my ( $orig, $self ) = @_;
153             my $config = $self->$orig;
154              
155             $config->{ +__PACKAGE__ } = {
156             finders => [ sort @{ $self->finder } ],
157             (
158             map { $_ => $self->$_ ? 1 : 0 } qw(global skip_version_provider add_tarball_name)
159             ),
160             };
161              
162             return $config;
163             };
164              
165             __PACKAGE__->meta->make_immutable;
166              
167             1;
168              
169              
170             # vim: ts=4 sts=4 sw=4 et:
171              
172             __END__
173              
174             =pod
175              
176             =encoding UTF-8
177              
178             =head1 NAME
179              
180             Dist::Zilla::Plugin::RewriteVersion - Get and/or rewrite module versions to match distribution version
181              
182             =head1 VERSION
183              
184             version 0.015
185              
186             =head1 SYNOPSIS
187              
188             # in your code, declare $VERSION like this:
189             package Foo;
190             our $VERSION = '1.23';
191              
192             # in your dist.ini
193             [RewriteVersion]
194              
195             =head1 DESCRIPTION
196              
197             This module is both a C<VersionProvider> and C<FileMunger>.
198              
199             This module finds a version in a specific format from the main module file and
200             munges all gathered files to match. You can override the version found with
201             the C<V> environment variable, similar to
202             L<Git::NextVersion|Dist::Zilla::Plugin::Git::NextVersion>, in which case all
203             the gathered files have their C<$VERSION> set to that value.
204              
205             By default, versions B<must> be "strict" -- decimal or 3+ part tuple with a
206             leading "v". The C<allow_decimal_underscore> option, if enabled, will also
207             allow decimals to contain an underscore. All other version forms are
208             not allowed, including: "v1.2", "1.2.3" and "v1.2.3_4".
209              
210             Only the B<first> occurrence of a C<$VERSION> declaration in each file is
211             relevant and/or affected (unless the L</global> attribute is set) and it must
212             exactly match this regular expression:
213              
214             qr{^our \s+ \$VERSION \s* = \s* '$version::LAX'}mx
215              
216             It must be at the start of a line and any trailing comments are deleted. The
217             original may have double-quotes, but the re-written line will have single
218             quotes.
219              
220             The very restrictive regular expression format is intentional to avoid
221             the various ways finding a version assignment could go wrong and to avoid
222             using L<PPI>, which has similar complexity issues.
223              
224             For most modules, this should work just fine.
225              
226             See L<BumpVersionAfterRelease|Dist::Zilla::Plugin::BumpVersionAfterRelease> for
227             more details and usage examples.
228              
229             =head1 ATTRIBUTES
230              
231             =head2 allow_decimal_underscore
232              
233             Allows use of decimal versions with underscores. Default is false. (Version
234             tuples with underscores are never allowed!)
235              
236             =head2 global
237              
238             If true, all occurrences of the version pattern will be replaced. Otherwise,
239             only the first occurrence is replaced. Defaults to false.
240              
241             =head2 skip_version_provider
242              
243             If true, rely on some other mechanism for determining the "current" version
244             instead of extracting it from the C<main_module>. Defaults to false.
245              
246             This enables hard-coding C<version => in C<dist.ini> among other tricks.
247              
248             =head2 add_tarball_name
249              
250             If true, when the version is written, it will append a comment with the name of
251             the tarball it comes from. This helps users track down the source of a
252             module if its name doesn't match the tarball name. If the module is
253             a TRIAL release, that is also in the comment. For example:
254              
255             our $VERSION = '0.010'; # from Foo-Bar-0.010.tar.gz
256             our $VERSION = '0.011'; # TRIAL from Foo-Bar-0.011-TRIAL.tar.gz
257              
258             This option defaults to false.
259              
260             =for Pod::Coverage munge_files munge_file rewrite_version provide_version
261              
262             =head1 SEE ALSO
263              
264             =over 4
265              
266             =item *
267              
268             L<Dist::Zilla::Plugin::RewriteVersion::Transitional>
269              
270             =back
271              
272             =head1 AUTHOR
273              
274             David Golden <dagolden@cpan.org>
275              
276             =head1 COPYRIGHT AND LICENSE
277              
278             This software is Copyright (c) 2014 by David Golden.
279              
280             This is free software, licensed under:
281              
282             The Apache License, Version 2.0, January 2004
283              
284             =cut