line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Dist::Zilla::Plugin::ChangelogFromGit::CPAN::Changes 0.230480; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# ABSTRACT: Generate valid CPAN::Changes Changelogs from git |
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
8260553
|
use v5.24; |
|
2
|
|
|
|
|
16
|
|
6
|
2
|
|
|
2
|
|
26
|
use Moose; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
22
|
|
7
|
2
|
|
|
2
|
|
13438
|
use Moose::Util::TypeConstraints; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
23
|
|
8
|
2
|
|
|
2
|
|
4594
|
use Class::Load 'try_load_class'; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
205
|
|
9
|
2
|
|
|
2
|
|
20
|
use CPAN::Changes::Release; |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
99
|
|
10
|
2
|
|
|
2
|
|
41
|
use CPAN::Changes 0.400002; |
|
2
|
|
|
|
|
72
|
|
|
2
|
|
|
|
|
68
|
|
11
|
2
|
|
|
2
|
|
1947
|
use DateTime; |
|
2
|
|
|
|
|
731691
|
|
|
2
|
|
|
|
|
139
|
|
12
|
2
|
|
|
2
|
|
19
|
use Encode; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
412
|
|
13
|
2
|
|
|
2
|
|
1291
|
use Git::Wrapper; |
|
2
|
|
|
|
|
24893
|
|
|
2
|
|
|
|
|
4866
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
with qw/ |
16
|
|
|
|
|
|
|
Dist::Zilla::Role::AfterBuild |
17
|
|
|
|
|
|
|
Dist::Zilla::Role::FileGatherer |
18
|
|
|
|
|
|
|
Dist::Zilla::Role::Git::Repo |
19
|
|
|
|
|
|
|
/; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
subtype 'CoercedRegexpRef' => as 'RegexpRef'; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
coerce 'CoercedRegexpRef' => from 'Str' => via {qr/$_[0]/}; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has group_by_author => ( is => 'ro', isa => 'Bool', default => 0); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
has show_author_email => ( is => 'ro', isa => 'Bool', default => 0); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
has show_author => ( is => 'ro', isa => 'Bool', default => 1); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
has tag_regexp => ( |
36
|
|
|
|
|
|
|
is => 'ro', |
37
|
|
|
|
|
|
|
isa => 'CoercedRegexpRef', |
38
|
|
|
|
|
|
|
coerce => 1, |
39
|
|
|
|
|
|
|
default => 'v?(\d+\.\d+(_\d+)?)' |
40
|
|
|
|
|
|
|
); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
has file_name => (is => 'ro', isa => 'Str', default => 'Changes'); |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
has preamble => ( |
47
|
|
|
|
|
|
|
is => 'ro', |
48
|
|
|
|
|
|
|
lazy => 1, |
49
|
|
|
|
|
|
|
isa => 'Str', |
50
|
|
|
|
|
|
|
default => sub { 'Changelog for ' . $_[0]->zilla->name }, |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
has copy_to_root => (is => 'ro', isa => 'Bool', default => 1); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
has edit_changelog => (is => 'ro', isa => 'Bool', default => 0); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
has _changes => (is => 'ro', lazy_build => 1, isa => 'CPAN::Changes'); |
60
|
|
|
|
|
|
|
has _last_release => (is => 'ro', lazy_build => 1, isa => 'Maybe[version]'); |
61
|
|
|
|
|
|
|
has _tags => (is => 'rw', isa => 'ArrayRef', default => sub {[]}); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
has _git => ( |
64
|
|
|
|
|
|
|
is => 'ro', |
65
|
|
|
|
|
|
|
lazy => 1, |
66
|
|
|
|
|
|
|
isa => 'Git::Wrapper', |
67
|
|
|
|
|
|
|
default => sub { Git::Wrapper->new('.') }, |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
has _git_can_mailmap => ( |
71
|
|
|
|
|
|
|
is => 'ro', |
72
|
|
|
|
|
|
|
lazy => 1, |
73
|
|
|
|
|
|
|
isa => 'Bool', |
74
|
|
|
|
|
|
|
default => sub { |
75
|
|
|
|
|
|
|
my ($gv) = $_[0]->git->version =~ /(\d+\.\d+\.\d+)/; |
76
|
|
|
|
|
|
|
$gv //= 0; |
77
|
|
|
|
|
|
|
return version->parse($gv) < '1.8.2' ? 0 : 1; |
78
|
|
|
|
|
|
|
}, |
79
|
|
|
|
|
|
|
); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub BUILDARGS { |
82
|
7
|
|
|
7
|
1
|
50
|
my %args = %{$_[1]}; |
|
7
|
|
|
|
|
86
|
|
83
|
|
|
|
|
|
|
|
84
|
7
|
50
|
|
|
|
98
|
if (exists $args{tag_regexp}) { |
85
|
0
|
0
|
|
|
|
0
|
if ($args{tag_regexp} eq 'semantic') { |
|
|
0
|
|
|
|
|
|
86
|
0
|
|
|
|
|
0
|
$args{tag_regexp} = 'v?(\d+\.\d+\.\d+)'; |
87
|
|
|
|
|
|
|
} elsif ($args{tag_regexp} eq 'decimal') { |
88
|
0
|
|
|
|
|
0
|
$args{tag_regexp} = 'v?(\d+\.\d+)$'; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
7
|
|
|
|
|
378
|
return \%args; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _build__changes { |
96
|
7
|
|
|
7
|
|
28
|
my $self = shift; |
97
|
|
|
|
|
|
|
|
98
|
7
|
|
|
|
|
22
|
my $changes; |
99
|
7
|
|
|
|
|
435
|
my @args = (preamble => $self->preamble); |
100
|
|
|
|
|
|
|
|
101
|
7
|
100
|
|
|
|
426
|
if (-f $self->file_name) { |
102
|
1
|
|
|
|
|
50
|
$self->logger->log_debug('Starting from an existing changelog'); |
103
|
1
|
|
|
|
|
124
|
$changes = CPAN::Changes->load($self->file_name, @args); |
104
|
|
|
|
|
|
|
} else { |
105
|
6
|
|
|
|
|
359
|
$self->logger->log_debug('Creating full changelog'); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# TODO maybe. If Changelog is new and this is the first release, |
108
|
|
|
|
|
|
|
# first entry should just be "First release" |
109
|
6
|
|
|
|
|
742
|
$changes = CPAN::Changes->new(@args); |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
7
|
|
|
|
|
1989
|
return $changes; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub _build__last_release { |
116
|
6
|
|
|
6
|
|
32
|
my $self = shift; |
117
|
|
|
|
|
|
|
|
118
|
6
|
|
|
|
|
388
|
my @releases = $self->_changes->releases; |
119
|
6
|
50
|
|
|
|
489
|
if (scalar @releases > 1) { |
120
|
0
|
|
|
|
|
0
|
my $last_release = version->parse($releases[-1]->version); |
121
|
0
|
|
|
|
|
0
|
$self->logger->log("Last release in changelog: $last_release"); |
122
|
|
|
|
|
|
|
|
123
|
0
|
0
|
|
|
|
0
|
if (version->parse($self->zilla->version) == $last_release) { |
124
|
0
|
|
|
|
|
0
|
$last_release = $releases[-2]->version; |
125
|
0
|
|
|
|
|
0
|
$self->logger->log( |
126
|
|
|
|
|
|
|
"Last release is *this* release, using $last_release as last"); |
127
|
|
|
|
|
|
|
} |
128
|
0
|
|
|
|
|
0
|
$last_release =~ $self->tag_regexp; |
129
|
0
|
0
|
|
|
|
0
|
if (!defined $1) { |
130
|
0
|
|
|
|
|
0
|
$self->logger->log_fatal( |
131
|
|
|
|
|
|
|
"Last release $last_release does not match tag_regexp"); |
132
|
|
|
|
|
|
|
} |
133
|
0
|
|
|
|
|
0
|
return version->parse($1); |
134
|
|
|
|
|
|
|
} |
135
|
6
|
|
|
|
|
352
|
return; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub gather_files { |
139
|
7
|
|
|
7
|
0
|
249549
|
my $self = shift; |
140
|
|
|
|
|
|
|
|
141
|
7
|
100
|
|
|
|
74
|
if (!$ENV{DZIL_RELEASING}) { |
142
|
1
|
|
|
|
|
10
|
$self->log( |
143
|
|
|
|
|
|
|
'We are not performing a release, so not wasting time updating changelog' |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
|
146
|
1
|
|
|
|
|
353
|
$self->add_file( |
147
|
|
|
|
|
|
|
Dist::Zilla::File::InMemory->new({ |
148
|
|
|
|
|
|
|
content => $self->_changes->serialize, |
149
|
|
|
|
|
|
|
name => $self->file_name, |
150
|
|
|
|
|
|
|
})); |
151
|
|
|
|
|
|
|
|
152
|
1
|
|
|
|
|
925
|
return; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
6
|
|
|
|
|
52
|
$self->_get_tags; |
156
|
6
|
|
|
|
|
202
|
$self->_get_changes; |
157
|
|
|
|
|
|
|
|
158
|
6
|
|
|
|
|
388
|
my $content = $self->_changes->serialize; |
159
|
|
|
|
|
|
|
|
160
|
6
|
50
|
|
|
|
14369
|
$self->log('Editing changelogs is disabled') if $ENV{NO_EDIT_CHANGES}; |
161
|
|
|
|
|
|
|
|
162
|
6
|
50
|
33
|
|
|
497
|
if ($self->edit_changelog && !$ENV{NO_EDIT_CHANGES}) { |
163
|
0
|
0
|
|
|
|
0
|
if (try_load_class('Proc::InvokeEditor')) { |
164
|
0
|
|
|
|
|
0
|
my $edited_content = Proc::InvokeEditor->edit($content); |
165
|
0
|
|
|
|
|
0
|
my $new_changes = CPAN::Changes->load_string($edited_content); |
166
|
0
|
|
|
|
|
0
|
$content = $new_changes->serialize; |
167
|
|
|
|
|
|
|
} else { |
168
|
0
|
|
|
|
|
0
|
$self->log( |
169
|
|
|
|
|
|
|
'Proc::InvokeEditor needs to be installed for editing changelogs' |
170
|
|
|
|
|
|
|
); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
6
|
|
|
|
|
437
|
my $file = Dist::Zilla::File::InMemory->new({ |
175
|
|
|
|
|
|
|
content => $content, |
176
|
|
|
|
|
|
|
name => $self->file_name, |
177
|
|
|
|
|
|
|
}); |
178
|
|
|
|
|
|
|
|
179
|
6
|
|
|
|
|
6064
|
$self->add_file($file); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# Will copy the the changelog into the root folder if C<copy_to_root> is enabled. |
183
|
|
|
|
|
|
|
sub after_build { |
184
|
7
|
|
|
7
|
0
|
198133
|
my ($self, $args) = @_; |
185
|
|
|
|
|
|
|
|
186
|
7
|
100
|
|
|
|
79
|
return unless $ENV{DZIL_RELEASING}; |
187
|
6
|
50
|
|
|
|
395
|
return unless $self->copy_to_root; |
188
|
|
|
|
|
|
|
|
189
|
6
|
|
|
|
|
300
|
my $build_file = $args->{build_root}->child($self->file_name); |
190
|
|
|
|
|
|
|
|
191
|
6
|
|
|
|
|
490
|
my $root_file = $self->zilla->root->child($self->file_name); |
192
|
6
|
|
|
|
|
273
|
$self->log_debug("Copying changes file from $build_file to $root_file"); |
193
|
6
|
50
|
|
|
|
517
|
if (!-e $build_file) { |
194
|
0
|
|
|
|
|
0
|
$self->logger->log_fatal("Where is the changelog?"); |
195
|
|
|
|
|
|
|
} |
196
|
6
|
|
|
|
|
265
|
$build_file->copy($root_file); |
197
|
|
|
|
|
|
|
|
198
|
6
|
|
|
|
|
4780
|
return; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub _get_tags { |
202
|
6
|
|
|
6
|
|
23
|
my $self = shift; |
203
|
6
|
|
|
|
|
293
|
$self->logger->log_debug( |
204
|
|
|
|
|
|
|
'Searching for tags matching ' . $self->tag_regexp); |
205
|
6
|
|
|
|
|
108
|
my @tags; |
206
|
6
|
|
|
|
|
300
|
foreach my $tag ($self->_git->RUN('tag')) { |
207
|
15
|
50
|
|
|
|
62717
|
next unless $tag =~ $self->tag_regexp; |
208
|
15
|
|
|
|
|
114
|
push @tags, $tag; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
6
|
|
|
|
|
10966
|
@{$self->_tags} = sort { version->parse($a) <=> version->parse($b) } @tags; |
|
6
|
|
|
|
|
508
|
|
|
15
|
|
|
|
|
591
|
|
212
|
6
|
|
|
|
|
39
|
push @{$self->_tags}, 'HEAD'; |
|
6
|
|
|
|
|
347
|
|
213
|
6
|
|
|
|
|
107
|
return; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub _git_log { |
217
|
21
|
|
|
21
|
|
105
|
my ($self, $revs) = @_; |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# easier to read than just writing the string directly |
220
|
21
|
|
|
|
|
392
|
my $format = { |
221
|
|
|
|
|
|
|
author => '%aN', |
222
|
|
|
|
|
|
|
date => '%at', |
223
|
|
|
|
|
|
|
email => '<%aE>', |
224
|
|
|
|
|
|
|
subject => '%s', |
225
|
|
|
|
|
|
|
}; |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# commit has to come first |
228
|
21
|
|
|
|
|
103
|
my $format_str = 'commit:%H%n'; |
229
|
21
|
|
|
|
|
220
|
while (my ($attr, $esc) = each %$format) { |
230
|
84
|
|
|
|
|
397
|
$format_str .= "$attr:$esc%n"; |
231
|
|
|
|
|
|
|
} |
232
|
21
|
|
|
|
|
62
|
$format_str .= '<END COMMIT>%n'; |
233
|
|
|
|
|
|
|
|
234
|
21
|
|
|
|
|
323
|
my $log_opts = { |
235
|
|
|
|
|
|
|
no_color => 1, |
236
|
|
|
|
|
|
|
format => $format_str, |
237
|
|
|
|
|
|
|
}; |
238
|
|
|
|
|
|
|
|
239
|
21
|
100
|
66
|
|
|
1601
|
if ($self->_git_can_mailmap and $self->show_author) { |
240
|
17
|
|
|
|
|
839
|
$self->logger->log_debug('Using git mailmap'); |
241
|
17
|
|
|
|
|
1064
|
$log_opts->{'use-mailmap'} = 1; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
21
|
|
|
|
|
1480
|
my @out = $self->_git->RUN( |
245
|
|
|
|
|
|
|
log => $log_opts, |
246
|
|
|
|
|
|
|
$revs |
247
|
|
|
|
|
|
|
); |
248
|
|
|
|
|
|
|
|
249
|
21
|
|
|
|
|
238650
|
my $commits; |
250
|
|
|
|
|
|
|
my $cur_commit; |
251
|
21
|
|
|
|
|
322
|
while (my $line = shift @out) { |
252
|
162
|
100
|
|
|
|
617
|
if ($line eq '<END COMMIT>') { |
253
|
27
|
|
|
|
|
77
|
$cur_commit = undef; |
254
|
27
|
|
|
|
|
73
|
shift @out; |
255
|
27
|
|
|
|
|
133
|
next; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
135
|
100
|
|
|
|
769
|
if ($line =~ /^commit:(\w+)$/) { |
|
|
50
|
|
|
|
|
|
259
|
27
|
|
|
|
|
359
|
$cur_commit = $1; |
260
|
27
|
|
|
|
|
392
|
$commits->{$cur_commit}->{id} = $cur_commit; |
261
|
27
|
|
|
|
|
182
|
next; |
262
|
|
|
|
|
|
|
} elsif (!$cur_commit) { |
263
|
0
|
|
|
|
|
0
|
die 'Failed to parse commit id'; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
108
|
50
|
|
|
|
637
|
if ($line =~ /^(\w+):(.+)$/) { |
267
|
108
|
50
|
|
|
|
333
|
die 'WTF? Not currently in a commit?' if !$cur_commit; |
268
|
108
|
|
|
|
|
1008
|
$commits->{$cur_commit}->{$1} = $2; |
269
|
108
|
|
|
|
|
476
|
next; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
21
|
100
|
|
|
|
168
|
if (!defined $commits) { |
274
|
5
|
|
|
|
|
716
|
$self->logger->log_debug("No commits found for $revs"); |
275
|
|
|
|
|
|
|
return [{ |
276
|
5
|
|
|
|
|
778
|
subject => "No changes found" |
277
|
|
|
|
|
|
|
}]; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
16
|
|
|
|
|
428
|
return [sort { $b->{date} <=> $a->{date} } values %$commits]; |
|
14
|
|
|
|
|
226
|
|
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
sub _get_release_date { |
284
|
21
|
|
|
21
|
|
152
|
my ($self, $tag) = @_; |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# TODO configurable date formats |
287
|
21
|
100
|
|
|
|
137
|
if ($tag eq 'HEAD') { |
288
|
6
|
|
|
|
|
220
|
return DateTime->now->iso8601; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# XXX 'max-count' => '1' doesn't work with Git::Wrapper, it becomes |
292
|
|
|
|
|
|
|
# just '--max-count'. File a bug! |
293
|
15
|
|
|
|
|
2344
|
my @out = $self->_git->RUN(log => {format => '%ct', 1 => 1}, $tag); |
294
|
15
|
|
|
|
|
160980
|
my $dt = DateTime->from_epoch(epoch => $out[0]); |
295
|
15
|
|
|
|
|
14704
|
return $dt->iso8601; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
sub _get_changes { |
299
|
6
|
|
|
6
|
|
39
|
my $self = shift; |
300
|
6
|
|
|
|
|
443
|
my $last_tag = $self->_last_release; |
301
|
|
|
|
|
|
|
|
302
|
6
|
|
|
|
|
56
|
foreach my $tag (@{$self->_tags}) { |
|
6
|
|
|
|
|
329
|
|
303
|
21
|
100
|
|
|
|
1291
|
my $rev = $last_tag ? "$last_tag..$tag" : $tag; |
304
|
21
|
|
|
|
|
84
|
$last_tag = $tag; |
305
|
|
|
|
|
|
|
|
306
|
21
|
|
|
|
|
58
|
my $version; |
307
|
21
|
100
|
|
|
|
90
|
if ($tag eq 'HEAD') { |
308
|
6
|
|
|
|
|
371
|
$version = $self->zilla->version; |
309
|
|
|
|
|
|
|
} else { |
310
|
15
|
|
|
|
|
1046
|
$tag =~ $self->tag_regexp; |
311
|
15
|
50
|
|
|
|
196
|
if (!$1) { |
312
|
0
|
|
|
|
|
0
|
die sprintf |
313
|
|
|
|
|
|
|
'Failed to get a match from tag_regexp: [%s] vs [%s]', |
314
|
|
|
|
|
|
|
$version, $self->tag_regexp; |
315
|
|
|
|
|
|
|
} |
316
|
15
|
|
|
|
|
111
|
$version = $1; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
21
|
|
|
|
|
11000
|
$self->logger->log_debug("Tag $tag == Version $version"); |
320
|
21
|
50
|
|
|
|
3391
|
if ($self->_last_release) { |
321
|
0
|
0
|
|
|
|
0
|
if ($self->_last_release > version->parse($version)) { |
|
|
0
|
|
|
|
|
|
322
|
0
|
|
|
|
|
0
|
$self->logger->log_debug("Skipping previous release $version"); |
323
|
0
|
|
|
|
|
0
|
next; |
324
|
|
|
|
|
|
|
} elsif ($self->_last_release == version->parse($version)) { |
325
|
0
|
|
|
|
|
0
|
$self->logger->log_debug("Skipping release $version"); |
326
|
0
|
|
|
|
|
0
|
next; |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
21
|
|
|
|
|
957
|
$self->logger->log_debug("Getting commits for $rev"); |
332
|
21
|
|
|
|
|
1043
|
my $commits = $self->_git_log($rev); |
333
|
|
|
|
|
|
|
|
334
|
21
|
|
|
|
|
395
|
my $release = CPAN::Changes::Release->new( |
335
|
|
|
|
|
|
|
version => $version, |
336
|
|
|
|
|
|
|
date => $self->_get_release_date($tag), |
337
|
|
|
|
|
|
|
); |
338
|
|
|
|
|
|
|
|
339
|
21
|
|
|
|
|
8248
|
my %seen; |
340
|
21
|
|
|
|
|
236
|
foreach my $commit (@$commits) { |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# TODO strip extra spaces and newlines |
343
|
|
|
|
|
|
|
# TODO convert * lists |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# weed out dupes |
346
|
32
|
|
|
|
|
1181
|
chomp $commit->{subject}; |
347
|
32
|
50
|
|
|
|
196
|
next if exists $seen{$commit->{subject}}; |
348
|
32
|
|
|
|
|
300
|
$seen{$commit->{subject}} = 1; |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# ignore the auto-commits |
351
|
32
|
50
|
|
|
|
160
|
next if $commit->{subject} eq $tag; |
352
|
32
|
50
|
|
|
|
299
|
next if $commit->{subject} =~ /^Release /; |
353
|
32
|
50
|
|
|
|
165
|
next if $commit->{subject} =~ /^Merge (pull|branch)/; |
354
|
|
|
|
|
|
|
|
355
|
32
|
50
|
|
|
|
202
|
unless (utf8::is_utf8($commit->{subject})) { |
356
|
32
|
|
|
|
|
953
|
$commit->{subject} = Encode::decode_utf8($commit->{subject}); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
32
|
100
|
100
|
|
|
2779
|
if ($self->show_author && exists $commit->{author}) { |
360
|
22
|
|
|
|
|
151
|
my $author = $commit->{author}; |
361
|
|
|
|
|
|
|
|
362
|
22
|
100
|
|
|
|
1370
|
if ($self->show_author_email) { |
363
|
10
|
|
|
|
|
84
|
$author .= ' ' . $commit->{email}; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
22
|
50
|
|
|
|
137
|
unless (utf8::is_utf8($author)) { |
367
|
22
|
|
|
|
|
231
|
$author = Encode::decode_utf8($author); |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
22
|
100
|
|
|
|
1650
|
if ($self->group_by_author) { |
371
|
10
|
|
|
|
|
68
|
my $group = $author; |
372
|
|
|
|
|
|
|
$release->add_changes({group => $group}, |
373
|
10
|
|
|
|
|
119
|
$commit->{subject}); |
374
|
|
|
|
|
|
|
} else { |
375
|
12
|
|
|
|
|
204
|
$release->add_changes($commit->{subject} . " ($author)"); |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
} else { |
378
|
10
|
|
|
|
|
90
|
$release->add_changes($commit->{subject}); |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
21
|
|
|
|
|
3337
|
$self->_changes->add_release($release); |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
6
|
|
|
|
|
353
|
return; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
1; |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
__END__ |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=pod |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=encoding UTF-8 |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=for :stopwords Ioan Rogers cpan testmatrix url bugtracker rt cpants kwalitee diff irc |
399
|
|
|
|
|
|
|
mailto metadata placeholders metacpan |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head1 NAME |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
Dist::Zilla::Plugin::ChangelogFromGit::CPAN::Changes - Generate valid CPAN::Changes Changelogs from git |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=head1 VERSION |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
version 0.230480 |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=head1 SYNOPSIS |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
[ChangelogFromGit::CPAN::Changes] |
412
|
|
|
|
|
|
|
; All options from [ChangelogFromGit] plus |
413
|
|
|
|
|
|
|
group_by_author = 1 ; default 0 |
414
|
|
|
|
|
|
|
show_author_email = 1 ; default 0 |
415
|
|
|
|
|
|
|
show_author = 0 ; default 1 |
416
|
|
|
|
|
|
|
edit_changelog = 1 ; default 0 |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=head2 group_by_author |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Whether to group commit messages by their author. This is the only way previous |
423
|
|
|
|
|
|
|
versions did it. Defaults to no, and [ Anne Author ] is appended to the commit |
424
|
|
|
|
|
|
|
message. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
Defaults to off. |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=head2 show_author_email |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
Author email is probably just noise for most people, but turn this on if you |
431
|
|
|
|
|
|
|
want to show it [ Anne Author <anne@author.com> ] |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
Defaults to off. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=head2 show_author |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Whether to show authors at all. Turning this off also |
438
|
|
|
|
|
|
|
turns off grouping by author and author emails. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Defaults to on. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=head2 C<tag_regexp> |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
A regexp string which will be used to match git tags to find releases. If your |
445
|
|
|
|
|
|
|
release tags are not compliant with L<CPAN::Changes::Spec>, you can use a |
446
|
|
|
|
|
|
|
capture group. It will be used as the version in place of the full tag name. |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
Also takes C<semantic>, which becomes C<qr{^v?(\d+\.\d+\.\d+)$}>, and |
449
|
|
|
|
|
|
|
C<decimal>, which becomes C<qr{^v?(\d+\.\d+)$}>. |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
Defaults to 'decimal' |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=head2 C<file_name> |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
The name of the changelog file. |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Defaults to 'Changes'. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 C<preamble> |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Block of text at the beginning of the changelog. |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
Defaults to 'Changelog for $dist_name' |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=head2 C<copy_to_root> |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
When true, the generated changelog will be copied into the root folder where it |
468
|
|
|
|
|
|
|
can be committed (possiby automatically by L<Dist::Zilla::Plugin::Git::Commit>) |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
Defaults to true. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head2 C<edit_changelog> |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
When true, the generated changelog will be opened in an editor to allow manual |
475
|
|
|
|
|
|
|
editing. |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
Defaults to false. |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
=head1 SUPPORT |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=head2 Perldoc |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
perldoc Dist::Zilla::Plugin::ChangelogFromGit::CPAN::Changes |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=head2 Websites |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
The following websites have more information about this module, and may be of help to you. As always, |
490
|
|
|
|
|
|
|
in addition to those websites please use your favorite search engine to discover more resources. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=over 4 |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=item * |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
MetaCPAN |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
A modern, open-source CPAN search engine, useful to view POD in HTML format. |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
L<https://metacpan.org/release/Dist-Zilla-Plugin-ChangelogFromGit-CPAN-Changes> |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=back |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=head2 Bugs / Feature Requests |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
Please report any bugs or feature requests through the web interface at L<https://github.com/ioanrogers/Dist-Zilla-Plugin-ChangelogFromGit-CPAN-Changes.git/issues>. |
507
|
|
|
|
|
|
|
You will be automatically notified of any progress on the request by the system. |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=head2 Source Code |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
The source code is available for from the following locations: |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
L<https://github.com/ioanrogers/Dist-Zilla-Plugin-ChangelogFromGit-CPAN-Changes.git> |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
git clone https://github.com/ioanrogers/Dist-Zilla-Plugin-ChangelogFromGit-CPAN-Changes.git.git |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=head1 AUTHOR |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
Ioan Rogers <ioanr@cpan.org> |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
This software is copyright (c) 2023 by Ioan Rogers. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
526
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=cut |