Entry.pm 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 <http://www.gnu.org/licenses/>.
  15. package Dpkg::Changelog::Entry;
  16. use strict;
  17. use warnings;
  18. use Dpkg::Gettext;
  19. use Dpkg::ErrorHandling;
  20. use Dpkg::Control::Changelog;
  21. use overload
  22. '""' => \&output,
  23. 'eq' => sub { defined($_[1]) and "$_[0]" eq "$_[1]" },
  24. fallback => 1;
  25. =head1 NAME
  26. Dpkg::Changelog::Entry - represents a changelog entry
  27. =head1 DESCRIPTION
  28. This object represents a changelog entry. It is composed
  29. of a set of lines with specific purpose: an header line, changes lines, a
  30. trailer line. Blank lines can be between those kind of lines.
  31. =head1 FUNCTIONS
  32. =over 4
  33. =item my $entry = Dpkg::Changelog::Entry->new()
  34. Creates a new object. It doesn't represent a real changelog entry
  35. until one has been successfully parsed or built from scratch.
  36. =cut
  37. sub new {
  38. my ($this) = @_;
  39. my $class = ref($this) || $this;
  40. my $self = {
  41. 'header' => undef,
  42. 'changes' => [],
  43. 'trailer' => undef,
  44. 'blank_after_header' => [],
  45. 'blank_after_changes' => [],
  46. 'blank_after_trailer' => [],
  47. };
  48. bless $self, $class;
  49. return $self;
  50. }
  51. =item my $str = $entry->output()
  52. =item "$entry"
  53. Get a string representation of the changelog entry.
  54. =item $entry->output($fh)
  55. Print the string representation of the changelog entry to a
  56. filehandle.
  57. =cut
  58. sub output {
  59. my ($self, $fh) = @_;
  60. my $str = '';
  61. sub _block {
  62. my $lines = shift;
  63. return join('', map { $_ . "\n" } @{$lines});
  64. }
  65. $str .= $self->{header} . "\n" if defined($self->{header});
  66. $str .= _block($self->{blank_after_header});
  67. $str .= _block($self->{changes});
  68. $str .= _block($self->{blank_after_changes});
  69. $str .= $self->{trailer} . "\n" if defined($self->{trailer});
  70. $str .= _block($self->{blank_after_trailer});
  71. print $fh $str if defined $fh;
  72. return $str;
  73. }
  74. =item $entry->get_part($part)
  75. Return either a string (for a single line) or an array ref (for multiple
  76. lines) corresponding to the requested part. $part can be
  77. "header, "changes", "trailer", "blank_after_header",
  78. "blank_after_changes", "blank_after_trailer".
  79. =cut
  80. sub get_part {
  81. my ($self, $part) = @_;
  82. internerr("invalid part of changelog entry: %s") unless exists $self->{$part};
  83. return $self->{$part};
  84. }
  85. =item $entry->set_part($part, $value)
  86. Set the value of the corresponding part. $value can be a string
  87. or an array ref.
  88. =cut
  89. sub set_part {
  90. my ($self, $part, $value) = @_;
  91. internerr("invalid part of changelog entry: %s") unless exists $self->{$part};
  92. if (ref($self->{$part})) {
  93. if (ref($value)) {
  94. $self->{$part} = $value;
  95. } else {
  96. $self->{$part} = [ $value ];
  97. }
  98. } else {
  99. $self->{$part} = $value;
  100. }
  101. }
  102. =item $entry->extend_part($part, $value)
  103. Concatenate $value at the end of the part. If the part is already a
  104. multi-line value, $value is added as a new line otherwise it's
  105. concatenated at the end of the current line.
  106. =cut
  107. sub extend_part {
  108. my ($self, $part, $value, @rest) = @_;
  109. internerr("invalid part of changelog entry: %s") unless exists $self->{$part};
  110. if (ref($self->{$part})) {
  111. if (ref($value)) {
  112. push @{$self->{$part}}, @$value;
  113. } else {
  114. push @{$self->{$part}}, $value;
  115. }
  116. } else {
  117. if (defined($self->{$part})) {
  118. if (ref($value)) {
  119. $self->{$part} = [ $self->{$part}, @$value ];
  120. } else {
  121. $self->{$part} .= $value;
  122. }
  123. } else {
  124. $self->{$part} = $value;
  125. }
  126. }
  127. }
  128. =item $is_empty = $entry->is_empty()
  129. Returns 1 if the changelog entry doesn't contain anything at all.
  130. Returns 0 as soon as it contains something in any of its non-blank
  131. parts.
  132. =cut
  133. sub is_empty {
  134. my ($self) = @_;
  135. return !(defined($self->{header}) || defined($self->{trailer}) ||
  136. scalar(@{$self->{changes}}));
  137. }
  138. =item $entry->normalize()
  139. Normalize the content. Strip whitespaces at end of lines, use a single
  140. empty line to separate each part.
  141. =cut
  142. sub normalize {
  143. my ($self) = @_;
  144. if (defined($self->{header})) {
  145. $self->{header} =~ s/\s+$//g;
  146. $self->{blank_after_header} = [''];
  147. } else {
  148. $self->{blank_after_header} = [];
  149. }
  150. if (scalar(@{$self->{changes}})) {
  151. s/\s+$//g foreach @{$self->{changes}};
  152. $self->{blank_after_changes} = [''];
  153. } else {
  154. $self->{blank_after_changes} = [];
  155. }
  156. if (defined($self->{trailer})) {
  157. $self->{trailer} =~ s/\s+$//g;
  158. $self->{blank_after_trailer} = [''];
  159. } else {
  160. $self->{blank_after_trailer} = [];
  161. }
  162. }
  163. =item my $src = $entry->get_source()
  164. Return the name of the source package associated to the changelog entry.
  165. =cut
  166. sub get_source {
  167. return undef;
  168. }
  169. =item my $ver = $entry->get_version()
  170. Return the version associated to the changelog entry.
  171. =cut
  172. sub get_version {
  173. return undef;
  174. }
  175. =item my @dists = $entry->get_distributions()
  176. Return a list of target distributions for this version.
  177. =cut
  178. sub get_distributions {
  179. return () if wantarray;
  180. return undef;
  181. }
  182. =item $fields = $entry->get_optional_fields()
  183. Return a set of optional fields exposed by the changelog entry.
  184. It always returns a Dpkg::Control object (possibly empty though).
  185. =cut
  186. sub get_optional_fields {
  187. return Dpkg::Control::Changelog->new();
  188. }
  189. =item $urgency = $entry->get_urgency()
  190. Return the urgency of the associated upload.
  191. =cut
  192. sub get_urgency {
  193. return undef;
  194. }
  195. =item my $maint = $entry->get_maintainer()
  196. Return the string identifying the person who signed this changelog entry.
  197. =cut
  198. sub get_maintainer {
  199. return undef;
  200. }
  201. =item my $time = $entry->get_timestamp()
  202. Return the timestamp of the changelog entry.
  203. =cut
  204. sub get_timestamp {
  205. return undef;
  206. }
  207. =item my $str = $entry->get_dpkg_changes()
  208. Returns a string that is suitable for usage in a C<Changes> field
  209. in the output format of C<dpkg-parsechangelog>.
  210. =cut
  211. sub get_dpkg_changes {
  212. my ($self) = @_;
  213. my $header = $self->get_part("header") || "";
  214. $header =~ s/\s+$//;
  215. return "\n$header\n\n" . join("\n", @{$self->get_part("changes")});
  216. }
  217. =back
  218. =head1 AUTHOR
  219. Raphaël Hertzog <hertzog@debian.org>.
  220. =cut
  221. 1;