Entry.pm 6.1 KB

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