1 # Copyright © 2009 Raphaël Hertzog <hertzog@debian.org>
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.
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.
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/>.
16 package Dpkg::Changelog::Entry;
21 our $VERSION = '1.01';
26 use Dpkg::ErrorHandling;
27 use Dpkg::Control::Changelog;
31 'eq' => sub { defined($_[1]) and "$_[0]" eq "$_[1]" },
38 Dpkg::Changelog::Entry - represents a changelog entry
42 This object represents a changelog entry. It is composed
43 of a set of lines with specific purpose: an header line, changes lines, a
44 trailer line. Blank lines can be between those kind of lines.
50 =item $entry = Dpkg::Changelog::Entry->new()
52 Creates a new object. It doesn't represent a real changelog entry
53 until one has been successfully parsed or built from scratch.
59 my $class = ref($this) || $this;
65 blank_after_header => [],
66 blank_after_changes => [],
67 blank_after_trailer => [],
73 =item $str = $entry->output()
77 Get a string representation of the changelog entry.
79 =item $entry->output($fh)
81 Print the string representation of the changelog entry to a
86 sub _format_output_block {
88 return join('', map { $_ . "\n" } @{$lines});
94 $str .= $self->{header} . "\n" if defined($self->{header});
95 $str .= _format_output_block($self->{blank_after_header});
96 $str .= _format_output_block($self->{changes});
97 $str .= _format_output_block($self->{blank_after_changes});
98 $str .= $self->{trailer} . "\n" if defined($self->{trailer});
99 $str .= _format_output_block($self->{blank_after_trailer});
100 print { $fh } $str if defined $fh;
104 =item $entry->get_part($part)
106 Return either a string (for a single line) or an array ref (for multiple
107 lines) corresponding to the requested part. $part can be
108 "header, "changes", "trailer", "blank_after_header",
109 "blank_after_changes", "blank_after_trailer".
114 my ($self, $part) = @_;
115 croak "invalid part of changelog entry: $part" unless exists $self->{$part};
116 return $self->{$part};
119 =item $entry->set_part($part, $value)
121 Set the value of the corresponding part. $value can be a string
127 my ($self, $part, $value) = @_;
128 croak "invalid part of changelog entry: $part" unless exists $self->{$part};
129 if (ref($self->{$part})) {
131 $self->{$part} = $value;
133 $self->{$part} = [ $value ];
136 $self->{$part} = $value;
140 =item $entry->extend_part($part, $value)
142 Concatenate $value at the end of the part. If the part is already a
143 multi-line value, $value is added as a new line otherwise it's
144 concatenated at the end of the current line.
149 my ($self, $part, $value, @rest) = @_;
150 croak "invalid part of changelog entry: $part" unless exists $self->{$part};
151 if (ref($self->{$part})) {
153 push @{$self->{$part}}, @$value;
155 push @{$self->{$part}}, $value;
158 if (defined($self->{$part})) {
160 $self->{$part} = [ $self->{$part}, @$value ];
162 $self->{$part} .= $value;
165 $self->{$part} = $value;
170 =item $is_empty = $entry->is_empty()
172 Returns 1 if the changelog entry doesn't contain anything at all.
173 Returns 0 as soon as it contains something in any of its non-blank
180 return !(defined($self->{header}) || defined($self->{trailer}) ||
181 scalar(@{$self->{changes}}));
184 =item $entry->normalize()
186 Normalize the content. Strip whitespaces at end of lines, use a single
187 empty line to separate each part.
193 if (defined($self->{header})) {
194 $self->{header} =~ s/\s+$//g;
195 $self->{blank_after_header} = [''];
197 $self->{blank_after_header} = [];
199 if (scalar(@{$self->{changes}})) {
200 s/\s+$//g foreach @{$self->{changes}};
201 $self->{blank_after_changes} = [''];
203 $self->{blank_after_changes} = [];
205 if (defined($self->{trailer})) {
206 $self->{trailer} =~ s/\s+$//g;
207 $self->{blank_after_trailer} = [''];
209 $self->{blank_after_trailer} = [];
213 =item $src = $entry->get_source()
215 Return the name of the source package associated to the changelog entry.
223 =item $ver = $entry->get_version()
225 Return the version associated to the changelog entry.
233 =item @dists = $entry->get_distributions()
235 Return a list of target distributions for this version.
239 sub get_distributions {
243 =item $fields = $entry->get_optional_fields()
245 Return a set of optional fields exposed by the changelog entry.
246 It always returns a Dpkg::Control object (possibly empty though).
250 sub get_optional_fields {
251 return Dpkg::Control::Changelog->new();
254 =item $urgency = $entry->get_urgency()
256 Return the urgency of the associated upload.
264 =item $maint = $entry->get_maintainer()
266 Return the string identifying the person who signed this changelog entry.
274 =item $time = $entry->get_timestamp()
276 Return the timestamp of the changelog entry.
284 =item $time = $entry->get_timepiece()
286 Return the timestamp of the changelog entry as a Time::Piece object.
288 This function might return undef if there was no timestamp.
296 =item $str = $entry->get_dpkg_changes()
298 Returns a string that is suitable for usage in a C<Changes> field
299 in the output format of C<dpkg-parsechangelog>.
303 sub get_dpkg_changes {
305 my $header = $self->get_part('header') // '';
307 return "\n$header\n\n" . join("\n", @{$self->get_part('changes')});
314 =head2 Version 1.01 (dpkg 1.18.8)
316 New method: $entry->get_timepiece().
318 =head2 Version 1.00 (dpkg 1.15.6)
320 Mark the module as public.