dpkg (1.18.25) stretch; urgency=medium
[dpkg] / scripts / Dpkg / Changelog / Parse.pm
CommitLineData
1479465f
GJ
1# Copyright © 2005, 2007 Frank Lichtenheld <frank@lichtenheld.de>
2# Copyright © 2009 Raphaël Hertzog <hertzog@debian.org>
3# Copyright © 2010, 2012-2015 Guillem Jover <guillem@debian.org>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18=encoding utf8
19
20=head1 NAME
21
22Dpkg::Changelog::Parse - generic changelog parser for dpkg-parsechangelog
23
24=head1 DESCRIPTION
25
26This module provides a set of functions which reproduce all the features
27of dpkg-parsechangelog.
28
29=cut
30
31package Dpkg::Changelog::Parse;
32
33use strict;
34use warnings;
35
36our $VERSION = '1.02';
37our @EXPORT = qw(
38 changelog_parse_debian
39 changelog_parse_plugin
40 changelog_parse
41);
42
43use Exporter qw(import);
44
45use Dpkg ();
46use Dpkg::Util qw(none);
47use Dpkg::Gettext;
48use Dpkg::ErrorHandling;
49use Dpkg::Control::Changelog;
50
51sub _changelog_detect_format {
52 my $file = shift;
53 my $format = 'debian';
54
55 # Extract the format from the changelog file if possible
56 if ($file ne '-') {
57 local $_;
58
59 open my $format_fh, '-|', 'tail', '-n', '40', $file
60 or syserr(g_('cannot create pipe for %s'), 'tail');
61 while (<$format_fh>) {
62 $format = $1 if m/\schangelog-format:\s+([0-9a-z]+)\W/;
63 }
64 close $format_fh or subprocerr(g_('tail of %s'), $file);
65 }
66
67 return $format;
68}
69
70=head1 FUNCTIONS
71
72=over 4
73
74=item $fields = changelog_parse_debian(%opt)
75
76This function is deprecated, use changelog_parse() instead, with the changelog
77format set to "debian".
78
79=cut
80
81sub changelog_parse_debian {
82 my (%options) = @_;
83
84 warnings::warnif('deprecated',
85 'deprecated function changelog_parse_debian, use changelog_parse instead');
86
87 # Force the plugin to be debian.
88 $options{changelogformat} = 'debian';
89
90 return _changelog_parse(%options);
91}
92
93=item $fields = changelog_parse_plugin(%opt)
94
95This function is deprecated, use changelog_parse() instead.
96
97=cut
98
99sub changelog_parse_plugin {
100 my (%options) = @_;
101
102 warnings::warnif('deprecated',
103 'deprecated function changelog_parse_plugin, use changelog_parse instead');
104
105 return _changelog_parse(%options);
106}
107
108=item $fields = changelog_parse(%opt)
109
110This function will parse a changelog. In list context, it returns as many
111Dpkg::Control objects as the parser did create. In scalar context, it will
112return only the first one. If the parser did not return any data, it will
113return an empty list in list context or undef on scalar context. If the
114parser failed, it will die.
115
116The changelog file that is parsed is F<debian/changelog> by default but it
117can be overridden with $opt{file}. The default output format is "dpkg" but
118it can be overridden with $opt{format}.
119
120The parsing itself is done by a parser module (searched in the standard
121perl library directories. That module is named according to the format that
122it is able to parse, with the name capitalized. By default it is either
123Dpkg::Changelog::Debian (from the "debian" format) or the format name looked
124up in the 40 last lines of the changelog itself (extracted with this perl
125regular expression "\schangelog-format:\s+([0-9a-z]+)\W"). But it can be
126overridden with $opt{changelogformat}.
127
128All the other keys in %opt are forwarded to the parser module constructor.
129
130=cut
131
132sub _changelog_parse {
133 my (%options) = @_;
134
135 # Setup and sanity checks.
136 if (exists $options{libdir}) {
137 warnings::warnif('deprecated',
138 'obsolete libdir option, changelog parsers are now perl modules');
139 }
140
141 $options{file} //= 'debian/changelog';
142 $options{label} //= $options{file};
143 $options{changelogformat} //= _changelog_detect_format($options{file});
144 $options{format} //= 'dpkg';
145
146 my @range_opts = qw(since until from to offset count all);
147 $options{all} = 1 if exists $options{all};
148 if (none { defined $options{$_} } @range_opts) {
149 $options{count} = 1;
150 }
151 my $range;
152 foreach my $opt (@range_opts) {
153 $range->{$opt} = $options{$opt} if exists $options{$opt};
154 }
155
156 # Find the right changelog parser.
157 my $format = ucfirst lc $options{changelogformat};
158 my $changes;
159 eval qq{
160 pop \@INC if \$INC[-1] eq '.';
161 require Dpkg::Changelog::$format;
162 \$changes = Dpkg::Changelog::$format->new();
163 };
164 error(g_('changelog format %s is unknown: %s'), $format, $@) if $@;
165 $changes->set_options(reportfile => $options{label}, range => $range);
166
167 # Load and parse the changelog.
168 $changes->load($options{file})
169 or error(g_('fatal error occurred while parsing %s'), $options{file});
170
171 # Get the output into several Dpkg::Control objects.
172 my @res;
173 if ($options{format} eq 'dpkg') {
174 push @res, $changes->format_range('dpkg', $range);
175 } elsif ($options{format} eq 'rfc822') {
176 push @res, $changes->format_range('rfc822', $range);
177 } else {
178 error(g_('unknown output format %s'), $options{format});
179 }
180
181 if (wantarray) {
182 return @res;
183 } else {
184 return $res[0] if @res;
185 return;
186 }
187}
188
189sub changelog_parse {
190 my (%options) = @_;
191
192 if (exists $options{forceplugin}) {
193 warnings::warnif('deprecated', 'obsolete forceplugin option');
194 }
195
196 return _changelog_parse(%options);
197}
198
199=back
200
201=head1 CHANGES
202
203=head2 Version 1.02 (dpkg 1.18.8)
204
205Deprecated functions: changelog_parse_debian(), changelog_parse_plugin().
206
207Obsolete options: $forceplugin, $libdir.
208
209=head2 Version 1.01 (dpkg 1.18.2)
210
211New functions: changelog_parse_debian(), changelog_parse_plugin().
212
213=head2 Version 1.00 (dpkg 1.15.6)
214
215Mark the module as public.
216
217=cut
218
2191;