File Coverage

blib/lib/Dist/Zilla/Plugin/Git/NextRelease.pm
Criterion Covered Total %
statement 63 73 86.3
branch 6 16 37.5
condition n/a
subroutine 18 19 94.7
pod 1 1 100.0
total 88 109 80.7


line stmt bran cond sub pod time code
1 5     5   9234719 use 5.008; # utf8
  5         14  
2 5     5   22 use strict;
  5         6  
  5         102  
3 5     5   25 use warnings;
  5         8  
  5         138  
4 5     5   500 use utf8;
  5         13  
  5         39  
5              
6             package Dist::Zilla::Plugin::Git::NextRelease;
7              
8             our $VERSION = '0.004001';
9              
10             # ABSTRACT: Use time-stamp from Git instead of process start time.
11              
12             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
13              
14 5     5   749 use Moose qw( extends has around );
  5         286538  
  5         34  
15             extends 'Dist::Zilla::Plugin::NextRelease';
16              
17 5     5   21705 use Git::Wrapper::Plus 0.003100; # Fixed shallow commits
  5         39636  
  5         151  
18 5     5   3914 use DateTime;
  5         1043848  
  5         234  
19 5     5   2954 use Dist::Zilla::Util::ConfigDumper qw( config_dumper );
  5         4529  
  5         23  
20              
21             use String::Formatter 0.100680 stringf => {
22             -as => '_format_version',
23              
24             input_processor => 'require_single_input',
25             string_replacer => 'method_replace',
26             codes => {
27 4         633 v => sub { $_[0]->zilla->version },
28             d => sub {
29 4         276 my $t = $_[0]->_git_timestamp;
30 4         221 $t = $t->set_time_zone( $_[0]->time_zone );
31 4         594 return $t->format_cldr( $_[1] ),;
32             },
33 0         0 t => sub { "\t" },
34 0         0 n => sub { "\n" },
35 0         0 E => sub { $_[0]->_user_info('email') },
36 0         0 U => sub { $_[0]->_user_info('name') },
37             T => sub {
38 4 0       1551 $_[0]->zilla->is_trial ? ( defined $_[1] ? $_[1] : '-TRIAL' ) : q[];
    50          
39             },
40             V => sub {
41 0 0       0 $_[0]->zilla->version . ( $_[0]->zilla->is_trial ? ( defined $_[1] ? $_[1] : '-TRIAL' ) : q[] );
    0          
42             },
43 1         953 'H' => sub { $_[0]->_git_sha1 },
44 1         861 'h' => sub { $_[0]->_git_sha1_abbrev },
45             },
46 5     5   3440 };
  5         9789  
  5         109  
47              
48              
49              
50              
51              
52              
53              
54              
55              
56             has 'branch' => (
57             is => ro =>,
58             lazy_build => 1,
59             );
60              
61              
62              
63              
64              
65              
66              
67              
68              
69             has 'default_branch' => (
70             is => ro =>,
71             lazy_build => 1,
72             predicate => 'has_default_branch',
73             );
74              
75             sub _build_default_branch {
76 0     0   0 my ($self) = @_;
77 0         0 return $self->log_fatal('default_branch was used but not specified');
78             }
79              
80             has _git_timestamp => (
81             init_arg => undef,
82             is => ro =>,
83             lazy_build => 1,
84             );
85             has '_gwp' => (
86             init_arg => undef,
87             is => ro =>,
88             lazy_build => 1,
89             );
90              
91             around dump_config => config_dumper( __PACKAGE__, { attrs => [ 'default_branch', 'branch' ] } );
92              
93             sub _build__gwp {
94 4     4   7 my ($self) = @_;
95 4         103 return Git::Wrapper::Plus->new( q[] . $self->zilla->root );
96             }
97              
98             sub _build_branch {
99 4     4   7 my ($self) = @_;
100 4         142 my $cb = $self->_gwp->branches->current_branch;
101 4 100       116314 if ( not $cb ) {
102 1 50       94 if ( not $self->has_default_branch ) {
103 0         0 $self->log_fatal(
104             [
105             q[Cannot determine branch to get timestamp from when not on a branch.]
106             . q[Specify default_branch if you want this to work here.],
107             ],
108             );
109             }
110 1         39 return $self->default_branch;
111             }
112 3         154 return $cb->name;
113             }
114              
115             has '_branch_object' => ( is => ro =>, init_arg => undef, lazy_build => 1 );
116             has '_branch_commit' => ( is => ro =>, init_arg => undef, lazy_build => 1 );
117             has '_git_sha1' => ( is => ro =>, init_arg => undef, lazy_build => 1 );
118             has '_git_sha1_abbrev' => ( is => ro =>, init_arg => undef, lazy_build => 1 );
119              
120             sub _build__branch_object {
121 4     4   5 my ($self) = @_;
122 4         141 my ( $branch, ) = $self->_gwp->branches->get_branch( $self->branch );
123 4 50       72832 if ( not $branch ) {
124 0         0 $self->log_fatal( [ q[Branch %s does not exist], $self->branch ] );
125             }
126 4         198 return $branch;
127             }
128              
129             sub _build__git_sha1 {
130 4     4   42 my ($self) = @_;
131 4         180 return $self->_branch_object->sha1;
132             }
133              
134             sub _build__git_sha1_abbrev {
135 1     1   2 my ($self) = @_;
136 1         34 return substr $self->_git_sha1, 0, 7;
137             }
138              
139             sub _build__branch_commit {
140 4     4   7 my ($self) = @_;
141 4         142 return [ $self->_gwp->git->cat_file( 'commit', $self->_git_sha1 ) ];
142             }
143              
144             sub _build__git_timestamp {
145 4     4   7 my ($self) = @_;
146 4         7 my ( $committer, ) = grep { /\Acommitter /msx } @{ $self->_branch_commit };
  21         58  
  4         149  
147 4         14 chomp $committer;
148             ## no critic ( Compatibility::PerlMinimumVersionAndWhy )
149 4 50       79 if ( $committer =~ qr/\s+(\d+)\s+(\S+)\z/msx ) {
150 4         71 return DateTime->from_epoch( epoch => $1, time_zone => $2 );
151             }
152 0         0 return $self->log_fatal( [ q[Could not parse timestamp and timezone from string <%s>], $committer ] );
153             }
154              
155              
156              
157              
158              
159              
160              
161              
162              
163              
164             sub section_header {
165 4     4 1 201406 my ($self) = @_;
166              
167 4         111 return _format_version( $self->format, $self );
168             }
169             __PACKAGE__->meta->make_immutable;
170 5     5   3231 no Moose;
  5         9  
  5         39  
171              
172             1;
173              
174             __END__
175              
176             =pod
177              
178             =encoding UTF-8
179              
180             =head1 NAME
181              
182             Dist::Zilla::Plugin::Git::NextRelease - Use time-stamp from Git instead of process start time.
183              
184             =head1 VERSION
185              
186             version 0.004001
187              
188             =head1 SYNOPSIS
189              
190             This module acts as a moderately thin wrapper to L<< C<[NextRelease]>|Dist::Zilla::Plugin::NextRelease >>
191             so that the time-stamps produced are generated by asking C<git> for the time-stamp of the current branch.
192              
193             If you always require a specific branch for generating time-stamps, it can be specified as a parameter.
194              
195             -[NextRelease]
196             +[Git::NextRelease]
197              
198             Optionally:
199              
200             +branch = master
201              
202             Or:
203              
204             +default_branch = master
205              
206             ( The latter only having impact in detached-head conditions )
207              
208             This exists mostly because of my extensive use of L<< C<[Git::CommitBuild]>|Dist::Zilla::Plugin::Git::CommitBuild >>, to provide
209             a commit series for both releases, and builds of all changes/commits in order to push them to Travis for testing. ( Mostly,
210             because testing a build branch is substantially faster than testing a master that requires C<Dist::Zilla>, especially if you're
211             doing "Fresh install" testing like I am. )
212              
213             =head1 METHODS
214              
215             =head2 C<section_header>
216              
217             This is the sole method of L<< C<[NextRelease]>|Dist::Zilla::Plugin::NextRelease >> that we override,
218             in order for it to inject the right things.
219              
220             This method basically returns the date string to append to the Changes header.
221              
222             =head1 ATTRIBUTES
223              
224             =head2 C<branch>
225              
226             If set, always use the specified branch to determine time-stamp.
227              
228             Default value is resolved from determining "current" branch.
229              
230             =head2 C<default_branch>
231              
232             If you want being on a branch to always resolve to that branch,
233             but you still want a useful behavior when on a detached head,
234             specifying this value means that on a detached head, the stated branch will be used instead.
235              
236             =head1 FORMATS
237              
238             C<[Git::NextRelease]> enhances and adds a few features of C<[NextRelease]>
239              
240             =over 4
241              
242             =item * C<%d> - A CLDR formatter of the C<branch>'s C<HEAD> timestamp. ( Original uses simply C<now> )
243              
244             =item * C<%H> - The SHA1 of C<branch>'s C<HEAD>
245              
246             =item * C<%h> - The SHA1 of C<branch>'s C<HEAD> shortened to 7 characters.
247              
248             =back
249              
250             =head1 AUTHOR
251              
252             Kent Fredric <kentnl@cpan.org>
253              
254             =head1 COPYRIGHT AND LICENSE
255              
256             This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.
257              
258             This is free software; you can redistribute it and/or modify it under
259             the same terms as the Perl 5 programming language system itself.
260              
261             =cut