File: | Dpkg/Changelog/Entry.pm |
Coverage: | 62.9% |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | # Copyright © 2009 Raphaël Hertzog <hertzog@debian.org> | ||||||
2 | # | ||||||
3 | # This program is free software; you can redistribute it and/or modify | ||||||
4 | # it under the terms of the GNU General Public License as published by | ||||||
5 | # the Free Software Foundation; either version 2 of the License, or | ||||||
6 | # (at your option) any later version. | ||||||
7 | # | ||||||
8 | # This program is distributed in the hope that it will be useful, | ||||||
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
11 | # GNU General Public License for more details. | ||||||
12 | # | ||||||
13 | # You should have received a copy of the GNU General Public License | ||||||
14 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
15 | |||||||
16 | package Dpkg::Changelog::Entry; | ||||||
17 | |||||||
18 | 6 6 6 | 12 6 67 | use strict; | ||||
19 | 6 6 6 | 8 4 138 | use warnings; | ||||
20 | |||||||
21 | our $VERSION = '1.01'; | ||||||
22 | |||||||
23 | 6 6 6 | 13 2 126 | use Carp; | ||||
24 | |||||||
25 | 6 6 6 | 14 3 132 | use Dpkg::Gettext; | ||||
26 | 6 6 6 | 14 4 283 | use Dpkg::ErrorHandling; | ||||
27 | 6 6 6 | 54 31 269 | use Dpkg::Control::Changelog; | ||||
28 | |||||||
29 | use overload | ||||||
30 | '""' => \&output, | ||||||
31 | 42 | 50 | 'eq' => sub { defined($_[1]) and "$_[0]" eq "$_[1]" }, | ||||
32 | 6 6 6 | 14 4 26 | fallback => 1; | ||||
33 | |||||||
34 | =encoding utf8 | ||||||
35 | |||||||
36 - 55 | =head1 NAME Dpkg::Changelog::Entry - represents a changelog entry =head1 DESCRIPTION This class represents a changelog entry. It is composed of a set of lines with specific purpose: a header line, changes lines, a trailer line. Blank lines can be between those kind of lines. =head1 METHODS =over 4 =item $entry = Dpkg::Changelog::Entry->new() Creates a new object. It doesn't represent a real changelog entry until one has been successfully parsed or built from scratch. =cut | ||||||
56 | |||||||
57 | sub new { | ||||||
58 | 319 | 1 | 194 | my $this = shift; | |||
59 | 319 | 446 | my $class = ref($this) || $this; | ||||
60 | |||||||
61 | 319 | 602 | my $self = { | ||||
62 | header => undef, | ||||||
63 | changes => [], | ||||||
64 | trailer => undef, | ||||||
65 | blank_after_header => [], | ||||||
66 | blank_after_changes => [], | ||||||
67 | blank_after_trailer => [], | ||||||
68 | }; | ||||||
69 | 319 | 244 | bless $self, $class; | ||||
70 | 319 | 240 | return $self; | ||||
71 | } | ||||||
72 | |||||||
73 - 84 | =item $str = $entry->output() =item "$entry" Get a string representation of the changelog entry. =item $entry->output($fh) Print the string representation of the changelog entry to a filehandle. =cut | ||||||
85 | |||||||
86 | sub _format_output_block { | ||||||
87 | 2348 | 1132 | my $lines = shift; | ||||
88 | 2348 5154 2348 | 1049 3660 1249 | return join('', map { $_ . "\n" } @{$lines}); | ||||
89 | } | ||||||
90 | |||||||
91 | sub output { | ||||||
92 | 587 | 1 | 4542 | my ($self, $fh) = @_; | |||
93 | 587 | 325 | my $str = ''; | ||||
94 | 587 | 509 | $str .= $self->{header} . "\n" if defined($self->{header}); | ||||
95 | 587 | 360 | $str .= _format_output_block($self->{blank_after_header}); | ||||
96 | 587 | 383 | $str .= _format_output_block($self->{changes}); | ||||
97 | 587 | 340 | $str .= _format_output_block($self->{blank_after_changes}); | ||||
98 | 587 | 479 | $str .= $self->{trailer} . "\n" if defined($self->{trailer}); | ||||
99 | 587 | 358 | $str .= _format_output_block($self->{blank_after_trailer}); | ||||
100 | 587 0 | 388 0 | print { $fh } $str if defined $fh; | ||||
101 | 587 | 671 | return $str; | ||||
102 | } | ||||||
103 | |||||||
104 - 111 | =item $entry->get_part($part) Return either a string (for a single line) or an array ref (for multiple lines) corresponding to the requested part. $part can be "header, "changes", "trailer", "blank_after_header", "blank_after_changes", "blank_after_trailer". =cut | ||||||
112 | |||||||
113 | sub get_part { | ||||||
114 | 1660 | 1 | 991 | my ($self, $part) = @_; | |||
115 | 1660 | 1177 | croak "invalid part of changelog entry: $part" unless exists $self->{$part}; | ||||
116 | 1660 | 2299 | return $self->{$part}; | ||||
117 | } | ||||||
118 | |||||||
119 - 124 | =item $entry->set_part($part, $value) Set the value of the corresponding part. $value can be a string or an array ref. =cut | ||||||
125 | |||||||
126 | sub set_part { | ||||||
127 | 636 | 1 | 435 | my ($self, $part, $value) = @_; | |||
128 | 636 | 521 | croak "invalid part of changelog entry: $part" unless exists $self->{$part}; | ||||
129 | 636 | 434 | if (ref($self->{$part})) { | ||||
130 | 0 | 0 | if (ref($value)) { | ||||
131 | 0 | 0 | $self->{$part} = $value; | ||||
132 | } else { | ||||||
133 | 0 | 0 | $self->{$part} = [ $value ]; | ||||
134 | } | ||||||
135 | } else { | ||||||
136 | 636 | 487 | $self->{$part} = $value; | ||||
137 | } | ||||||
138 | } | ||||||
139 | |||||||
140 - 146 | =item $entry->extend_part($part, $value) Concatenate $value at the end of the part. If the part is already a multi-line value, $value is added as a new line otherwise it's concatenated at the end of the current line. =cut | ||||||
147 | |||||||
148 | sub extend_part { | ||||||
149 | 3712 | 1 | 2353 | my ($self, $part, $value, @rest) = @_; | |||
150 | 3712 | 2665 | croak "invalid part of changelog entry: $part" unless exists $self->{$part}; | ||||
151 | 3712 | 2306 | if (ref($self->{$part})) { | ||||
152 | 3712 | 2144 | if (ref($value)) { | ||||
153 | 3096 3096 | 1446 2691 | push @{$self->{$part}}, @$value; | ||||
154 | } else { | ||||||
155 | 616 616 | 336 660 | push @{$self->{$part}}, $value; | ||||
156 | } | ||||||
157 | } else { | ||||||
158 | 0 | 0 | if (defined($self->{$part})) { | ||||
159 | 0 | 0 | if (ref($value)) { | ||||
160 | 0 | 0 | $self->{$part} = [ $self->{$part}, @$value ]; | ||||
161 | } else { | ||||||
162 | 0 | 0 | $self->{$part} .= $value; | ||||
163 | } | ||||||
164 | } else { | ||||||
165 | 0 | 0 | $self->{$part} = $value; | ||||
166 | } | ||||||
167 | } | ||||||
168 | } | ||||||
169 | |||||||
170 - 176 | =item $is_empty = $entry->is_empty() Returns 1 if the changelog entry doesn't contain anything at all. Returns 0 as soon as it contains something in any of its non-blank parts. =cut | ||||||
177 | |||||||
178 | sub is_empty { | ||||||
179 | 347 | 1 | 188 | my $self = shift; | |||
180 | return !(defined($self->{header}) || defined($self->{trailer}) || | ||||||
181 | 347 | 597 | scalar(@{$self->{changes}})); | ||||
182 | } | ||||||
183 | |||||||
184 - 189 | =item $entry->normalize() Normalize the content. Strip whitespaces at end of lines, use a single empty line to separate each part. =cut | ||||||
190 | |||||||
191 | sub normalize { | ||||||
192 | 0 | 1 | 0 | my $self = shift; | |||
193 | 0 | 0 | if (defined($self->{header})) { | ||||
194 | 0 | 0 | $self->{header} =~ s/\s+$//g; | ||||
195 | 0 | 0 | $self->{blank_after_header} = ['']; | ||||
196 | } else { | ||||||
197 | 0 | 0 | $self->{blank_after_header} = []; | ||||
198 | } | ||||||
199 | 0 0 | 0 0 | if (scalar(@{$self->{changes}})) { | ||||
200 | 0 0 | 0 0 | s/\s+$//g foreach @{$self->{changes}}; | ||||
201 | 0 | 0 | $self->{blank_after_changes} = ['']; | ||||
202 | } else { | ||||||
203 | 0 | 0 | $self->{blank_after_changes} = []; | ||||
204 | } | ||||||
205 | 0 | 0 | if (defined($self->{trailer})) { | ||||
206 | 0 | 0 | $self->{trailer} =~ s/\s+$//g; | ||||
207 | 0 | 0 | $self->{blank_after_trailer} = ['']; | ||||
208 | } else { | ||||||
209 | 0 | 0 | $self->{blank_after_trailer} = []; | ||||
210 | } | ||||||
211 | } | ||||||
212 | |||||||
213 - 217 | =item $src = $entry->get_source() Return the name of the source package associated to the changelog entry. =cut | ||||||
218 | |||||||
219 | sub get_source { | ||||||
220 | 0 | 1 | 0 | return; | |||
221 | } | ||||||
222 | |||||||
223 - 227 | =item $ver = $entry->get_version() Return the version associated to the changelog entry. =cut | ||||||
228 | |||||||
229 | sub get_version { | ||||||
230 | 0 | 1 | 0 | return; | |||
231 | } | ||||||
232 | |||||||
233 - 237 | =item @dists = $entry->get_distributions() Return a list of target distributions for this version. =cut | ||||||
238 | |||||||
239 | sub get_distributions { | ||||||
240 | 0 | 1 | 0 | return; | |||
241 | } | ||||||
242 | |||||||
243 - 248 | =item $fields = $entry->get_optional_fields() Return a set of optional fields exposed by the changelog entry. It always returns a Dpkg::Control object (possibly empty though). =cut | ||||||
249 | |||||||
250 | sub get_optional_fields { | ||||||
251 | 0 | 1 | 0 | return Dpkg::Control::Changelog->new(); | |||
252 | } | ||||||
253 | |||||||
254 - 258 | =item $urgency = $entry->get_urgency() Return the urgency of the associated upload. =cut | ||||||
259 | |||||||
260 | sub get_urgency { | ||||||
261 | 0 | 1 | 0 | return; | |||
262 | } | ||||||
263 | |||||||
264 - 268 | =item $maint = $entry->get_maintainer() Return the string identifying the person who signed this changelog entry. =cut | ||||||
269 | |||||||
270 | sub get_maintainer { | ||||||
271 | 0 | 1 | 0 | return; | |||
272 | } | ||||||
273 | |||||||
274 - 278 | =item $time = $entry->get_timestamp() Return the timestamp of the changelog entry. =cut | ||||||
279 | |||||||
280 | sub get_timestamp { | ||||||
281 | 0 | 1 | 0 | return; | |||
282 | } | ||||||
283 | |||||||
284 - 290 | =item $time = $entry->get_timepiece() Return the timestamp of the changelog entry as a Time::Piece object. This function might return undef if there was no timestamp. =cut | ||||||
291 | |||||||
292 | sub get_timepiece { | ||||||
293 | 0 | 1 | 0 | return; | |||
294 | } | ||||||
295 | |||||||
296 - 301 | =item $str = $entry->get_dpkg_changes() Returns a string that is suitable for usage in a C<Changes> field in the output format of C<dpkg-parsechangelog>. =cut | ||||||
302 | |||||||
303 | sub get_dpkg_changes { | ||||||
304 | 738 | 1 | 369 | my $self = shift; | |||
305 | 738 | 509 | my $header = $self->get_part('header') // ''; | ||||
306 | 738 | 891 | $header =~ s/\s+$//; | ||||
307 | 738 738 | 450 497 | return "\n$header\n\n" . join("\n", @{$self->get_part('changes')}); | ||||
308 | } | ||||||
309 | |||||||
310 | =back | ||||||
311 | |||||||
312 - 322 | =head1 CHANGES =head2 Version 1.01 (dpkg 1.18.8) New method: $entry->get_timepiece(). =head2 Version 1.00 (dpkg 1.15.6) Mark the module as public. =cut | ||||||
323 | |||||||
324 | 1; |