Minor improvements in gencl
* mu-aux/gencl: Don't use Time::ParseDate. Work over bug in Text::Wrap 2012.0818. New option --ignore-errors (-i). Ensure consistent error code. * Makefile.am (dist-hook): Relax checking for intermediate releases.
Showing
2 changed files
with
62 additions
and
32 deletions
... | @@ -133,7 +133,7 @@ amend_file=ChangeLog.amend | ... | @@ -133,7 +133,7 @@ amend_file=ChangeLog.amend |
133 | .PHONY: ChangeLog | 133 | .PHONY: ChangeLog |
134 | ChangeLog: | 134 | ChangeLog: |
135 | $(AM_V_at)if test -d .git; then \ | 135 | $(AM_V_at)if test -d .git; then \ |
136 | cmd="$(top_srcdir)/mu-aux/gencl --file=ChangeLog --verbose --append-dot";\ | 136 | cmd="$(top_srcdir)/mu-aux/gencl --verbose --append-dot"; \ |
137 | if test -n "$(prev_change_log)" && test -f "$(prev_change_log)"; \ | 137 | if test -n "$(prev_change_log)" && test -f "$(prev_change_log)"; \ |
138 | then \ | 138 | then \ |
139 | cmd="$$cmd --append=$(prev_change_log)"; \ | 139 | cmd="$$cmd --append=$(prev_change_log)"; \ |
... | @@ -148,14 +148,14 @@ ChangeLog: | ... | @@ -148,14 +148,14 @@ ChangeLog: |
148 | fi | 148 | fi |
149 | 149 | ||
150 | dist-hook: ChangeLog | 150 | dist-hook: ChangeLog |
151 | @if head -n 6 ChangeLog | grep -q 'Uncommitted changes' ; \ | 151 | @PATCHLEV=`echo "$(PACKAGE_VERSION)" | sed -r "s/[0-9]+\.[0-9]+\.?//"`;\ |
152 | then \ | ||
153 | echo >&2 "*** Source tree contains uncommitted changes"; \ | ||
154 | echo >&2 "*** Aborting"; \ | ||
155 | exit 1; \ | ||
156 | fi; \ | ||
157 | PATCHLEV=`echo "$(PACKAGE_VERSION)" | sed -r "s/[0-9]+\.[0-9]+\.?//"`;\ | ||
158 | if test $${PATCHLEV:-0} -lt 50; then \ | 152 | if test $${PATCHLEV:-0} -lt 50; then \ |
153 | if head -n 6 ChangeLog | grep -q 'Uncommitted changes' ; \ | ||
154 | then \ | ||
155 | echo >&2 "*** Source tree contains uncommitted changes"; \ | ||
156 | echo >&2 "*** Aborting"; \ | ||
157 | exit 1; \ | ||
158 | fi; \ | ||
159 | if grep -q FIXME NEWS; then \ | 159 | if grep -q FIXME NEWS; then \ |
160 | echo >&2 "*** NEWS file contains FIXMEs"; \ | 160 | echo >&2 "*** NEWS file contains FIXMEs"; \ |
161 | echo >&2 "*** Aborting"; \ | 161 | echo >&2 "*** Aborting"; \ | ... | ... |
... | @@ -9,7 +9,6 @@ use Text::Wrap; | ... | @@ -9,7 +9,6 @@ use Text::Wrap; |
9 | use Data::Dumper; | 9 | use Data::Dumper; |
10 | use threads; | 10 | use threads; |
11 | use Thread::Queue; | 11 | use Thread::Queue; |
12 | use Time::ParseDate; | ||
13 | use Safe; | 12 | use Safe; |
14 | use Pod::Usage; | 13 | use Pod::Usage; |
15 | use Pod::Man; | 14 | use Pod::Man; |
... | @@ -25,15 +24,9 @@ my $strip_cherry_pick; | ... | @@ -25,15 +24,9 @@ my $strip_cherry_pick; |
25 | my $amend_file; | 24 | my $amend_file; |
26 | my %amendment; | 25 | my %amendment; |
27 | my $append_dot; | 26 | my $append_dot; |
27 | my $ignore_errors; | ||
28 | 28 | ||
29 | sub set_date { | 29 | my $exit_status = 0; |
30 | my ($time, $err) = parsedate($_[1], PREFER_PAST => 1, UK => 1); | ||
31 | unless (defined($time)) { | ||
32 | print STDERR "--$_[0]=$_[1]: $err\n"; | ||
33 | exit(1); | ||
34 | } | ||
35 | return strftime('%Y-%m-%d', localtime($time)); | ||
36 | } | ||
37 | 30 | ||
38 | =head1 NAME | 31 | =head1 NAME |
39 | 32 | ||
... | @@ -42,7 +35,7 @@ gencl - generate ChangeLog from git log output | ... | @@ -42,7 +35,7 @@ gencl - generate ChangeLog from git log output |
42 | =head1 SYNOPSIS | 35 | =head1 SYNOPSIS |
43 | 36 | ||
44 | B<gencl> | 37 | B<gencl> |
45 | [B<-fv>] | 38 | [B<-fiv>] |
46 | [B<-a> I<FILE>] | 39 | [B<-a> I<FILE>] |
47 | [B<-F> I<FILE>] | 40 | [B<-F> I<FILE>] |
48 | [B<--amend=>I<FILE>] | 41 | [B<--amend=>I<FILE>] |
... | @@ -50,6 +43,7 @@ B<gencl> | ... | @@ -50,6 +43,7 @@ B<gencl> |
50 | [B<--append=>I<FILE>] | 43 | [B<--append=>I<FILE>] |
51 | [B<--file=>I<FILE>] | 44 | [B<--file=>I<FILE>] |
52 | [B<--force>] | 45 | [B<--force>] |
46 | [B<--ignore-errors>] | ||
53 | [B<--since=>I<DATE>] | 47 | [B<--since=>I<DATE>] |
54 | [B<--strip-cherry-pick>] | 48 | [B<--strip-cherry-pick>] |
55 | [B<--until=>I<DATE>] | 49 | [B<--until=>I<DATE>] |
... | @@ -101,6 +95,11 @@ Create I<FILE> instead of the B<ChangeLog>. | ... | @@ -101,6 +95,11 @@ Create I<FILE> instead of the B<ChangeLog>. |
101 | 95 | ||
102 | Force recreating the ChangeLog, even if no new commits were added to the | 96 | Force recreating the ChangeLog, even if no new commits were added to the |
103 | repository since its creation. | 97 | repository since its creation. |
98 | |||
99 | =item B<-i>, B<--ignore-errors> | ||
100 | |||
101 | Ignore non-fatal errors. With this option in effect, B<gencl> exits with | ||
102 | code 0 even if some errors were encountered while running. | ||
104 | 103 | ||
105 | =item B<-v>, B<--verbose> | 104 | =item B<-v>, B<--verbose> |
106 | 105 | ||
... | @@ -108,13 +107,11 @@ Increase output verbosity. | ... | @@ -108,13 +107,11 @@ Increase output verbosity. |
108 | 107 | ||
109 | =item B<--since=>I<DATE> | 108 | =item B<--since=>I<DATE> |
110 | 109 | ||
111 | Convert only the logs since I<DATE>. See B<Time::ParseDate>(3), for | 110 | Convert only the logs since I<DATE> (B<YYYY-MM-DD>). |
112 | a list of valid I<DATE> formats. | ||
113 | 111 | ||
114 | =item B<--until=>I<DATE> | 112 | =item B<--until=>I<DATE> |
115 | 113 | ||
116 | Convert only the logs until I<DATE>. See B<Time::ParseDate>(3), for | 114 | Convert only the logs until I<DATE> (B<YYYY-MM-DD>). |
117 | a list of valid I<DATE> formats. | ||
118 | 115 | ||
119 | =item B<--strip-cherry-pick> | 116 | =item B<--strip-cherry-pick> |
120 | 117 | ||
... | @@ -132,6 +129,25 @@ punctuation the end. | ... | @@ -132,6 +129,25 @@ punctuation the end. |
132 | 129 | ||
133 | =back | 130 | =back |
134 | 131 | ||
132 | =head1 EXIT CODES | ||
133 | |||
134 | =over 4 | ||
135 | |||
136 | =item B<0> | ||
137 | |||
138 | Success. | ||
139 | |||
140 | =item B<1> | ||
141 | |||
142 | Fatal error. | ||
143 | |||
144 | =item B<2> | ||
145 | |||
146 | Non-fatal error. The B<--ignore-errors> (B<-i>) option instructs B<gencl> | ||
147 | to exit with code B<0>, instead of B<2>. | ||
148 | |||
149 | =back | ||
150 | |||
135 | =head1 DIFFERENCES FROM GITLOG-TO-CHANGELOG | 151 | =head1 DIFFERENCES FROM GITLOG-TO-CHANGELOG |
136 | 152 | ||
137 | =over 4 | 153 | =over 4 |
... | @@ -163,7 +179,7 @@ Each entry is reformatted using B<Text::Wrap>. | ... | @@ -163,7 +179,7 @@ Each entry is reformatted using B<Text::Wrap>. |
163 | =item 6 | 179 | =item 6 |
164 | 180 | ||
165 | The following B<gitlab-to-changelog> options are not implemented: B<--cluster>, | 181 | The following B<gitlab-to-changelog> options are not implemented: B<--cluster>, |
166 | B<--ignore-matching>, B<--ignore_line>. | 182 | B<--ignore-matching>, B<--ignore-line>. |
167 | 183 | ||
168 | =back | 184 | =back |
169 | 185 | ||
... | @@ -204,11 +220,12 @@ GetOptions( | ... | @@ -204,11 +220,12 @@ GetOptions( |
204 | 'file|F=s' => \$changelog_file, | 220 | 'file|F=s' => \$changelog_file, |
205 | 'force|f' => \$force, | 221 | 'force|f' => \$force, |
206 | 'verbose|v' => \$verbose, | 222 | 'verbose|v' => \$verbose, |
207 | 'since=s' => sub { $since_date = set_date(@_) }, | 223 | 'since=s' => \$since_date, |
208 | 'until=s' => sub { $until_date = set_date(@_) }, | 224 | 'until=s' => \$until_date, |
209 | 'strip-cherry-pick' => \$strip_cherry_pick, | 225 | 'strip-cherry-pick' => \$strip_cherry_pick, |
210 | 'amend=s' => \$amend_file, | 226 | 'amend=s' => \$amend_file, |
211 | 'append-dot' => \$append_dot | 227 | 'append-dot' => \$append_dot, |
228 | 'ignore-errors|i' => \$ignore_errors | ||
212 | ) or exit(1); | 229 | ) or exit(1); |
213 | 230 | ||
214 | if (! -d '.git') { | 231 | if (! -d '.git') { |
... | @@ -218,9 +235,12 @@ if (! -d '.git') { | ... | @@ -218,9 +235,12 @@ if (! -d '.git') { |
218 | read_amend_file($amend_file) if $amend_file; | 235 | read_amend_file($amend_file) if $amend_file; |
219 | 236 | ||
220 | $Text::Wrap::columns = 72; | 237 | $Text::Wrap::columns = 72; |
221 | 238 | # Work over bug #79766 in Text::Wrap | |
239 | $Text::Wrap::huge = 'overflow' if $Text::Wrap::VERSION eq '2012.0818'; | ||
240 | |||
222 | create_changelog(); | 241 | create_changelog(); |
223 | 242 | $exit_status = 0 if $ignore_errors; | |
243 | exit $exit_status; | ||
224 | 244 | ||
225 | sub toplevel_entry { | 245 | sub toplevel_entry { |
226 | my ($hash, $date) = split / /, | 246 | my ($hash, $date) = split / /, |
... | @@ -303,6 +323,7 @@ sub read_amend_file { | ... | @@ -303,6 +323,7 @@ sub read_amend_file { |
303 | if (exists($amendment{$hash})) { | 323 | if (exists($amendment{$hash})) { |
304 | warn "$file:$.: duplicate SHA1 hash"; | 324 | warn "$file:$.: duplicate SHA1 hash"; |
305 | warn $amendment{$hash}{locus} . ": previously defined here"; | 325 | warn $amendment{$hash}{locus} . ": previously defined here"; |
326 | $exit_status = 2; | ||
306 | } | 327 | } |
307 | $code = ''; | 328 | $code = ''; |
308 | $locus = "$file:$."; | 329 | $locus = "$file:$."; |
... | @@ -313,6 +334,7 @@ sub read_amend_file { | ... | @@ -313,6 +334,7 @@ sub read_amend_file { |
313 | } else { | 334 | } else { |
314 | warn "$file:$.: expected SHA1, but found $_" | 335 | warn "$file:$.: expected SHA1, but found $_" |
315 | unless $silent; | 336 | unless $silent; |
337 | $exit_status = 2; | ||
316 | $silent = 1; | 338 | $silent = 1; |
317 | } | 339 | } |
318 | } elsif ($state == STATE_HASH) { | 340 | } elsif ($state == STATE_HASH) { |
... | @@ -348,6 +370,7 @@ sub tokenize_gitlog { | ... | @@ -348,6 +370,7 @@ sub tokenize_gitlog { |
348 | my %ent = (); | 370 | my %ent = (); |
349 | unless (/^log size (\d+)/) { | 371 | unless (/^log size (\d+)/) { |
350 | warn "unexpected input: '$_'"; | 372 | warn "unexpected input: '$_'"; |
373 | $exit_status = 2; | ||
351 | next; | 374 | next; |
352 | } | 375 | } |
353 | my $size = $1; | 376 | my $size = $1; |
... | @@ -369,6 +392,7 @@ sub tokenize_gitlog { | ... | @@ -369,6 +392,7 @@ sub tokenize_gitlog { |
369 | } else { | 392 | } else { |
370 | warn "$.:$ent{hash}: failed to eval \"$code\" on \"$_\": \n$@\n"; | 393 | warn "$.:$ent{hash}: failed to eval \"$code\" on \"$_\": \n$@\n"; |
371 | warn $amendment{$ent{hash}}{locus} . ": code was defined here"; | 394 | warn $amendment{$ent{hash}}{locus} . ": code was defined here"; |
395 | $exit_status = 2; | ||
372 | } | 396 | } |
373 | } | 397 | } |
374 | 398 | ||
... | @@ -433,10 +457,12 @@ sub tokenize_gitlog { | ... | @@ -433,10 +457,12 @@ sub tokenize_gitlog { |
433 | $line =~ s/^.*://; | 457 | $line =~ s/^.*://; |
434 | push @unused, [ $line, $ref->{locus}, $hash ]; | 458 | push @unused, [ $line, $ref->{locus}, $hash ]; |
435 | } | 459 | } |
436 | foreach my $ent (sort { $a->[0] <=> $b->[0] } @unused) { | 460 | if (@unused) { |
437 | warn "$ent->[1]: unused entry: $ent->[2]\n"; | 461 | $exit_status = 2; |
462 | foreach my $ent (sort { $a->[0] <=> $b->[0] } @unused) { | ||
463 | warn "$ent->[1]: unused entry: $ent->[2]\n"; | ||
464 | } | ||
438 | } | 465 | } |
439 | |||
440 | print STDERR "tokenize_gitlog finished\n" if $verbose > 1; | 466 | print STDERR "tokenize_gitlog finished\n" if $verbose > 1; |
441 | } | 467 | } |
442 | 468 | ||
... | @@ -492,7 +518,10 @@ sub create_changelog { | ... | @@ -492,7 +518,10 @@ sub create_changelog { |
492 | my $cvt_thr = threads->create(\&convert_entry, $q); | 518 | my $cvt_thr = threads->create(\&convert_entry, $q); |
493 | $tok_thr->join(); | 519 | $tok_thr->join(); |
494 | $cvt_thr->join(); | 520 | $cvt_thr->join(); |
495 | 521 | if ($tok_thr->error() || $cvt_thr->error()) { | |
522 | exit 1; | ||
523 | } | ||
524 | |||
496 | # Print additional files | 525 | # Print additional files |
497 | foreach my $file (@append_files) { | 526 | foreach my $file (@append_files) { |
498 | if (open(my $in, '<', $file)) { | 527 | if (open(my $in, '<', $file)) { |
... | @@ -505,6 +534,7 @@ sub create_changelog { | ... | @@ -505,6 +534,7 @@ sub create_changelog { |
505 | close $in; | 534 | close $in; |
506 | } else { | 535 | } else { |
507 | warn "can't open $file: $!"; | 536 | warn "can't open $file: $!"; |
537 | $exit_status = 2; | ||
508 | } | 538 | } |
509 | } | 539 | } |
510 | 540 | ... | ... |
-
Please register or sign in to post a comment