4 # Convert a SUSE or Debian changelog file to rpm format
7 ################################################################
9 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License version 2 or 3 as
13 # published by the Free Software Foundation.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program (see the file COPYING); if not, write to the
22 # Free Software Foundation, Inc.,
23 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 ################################################################
28 unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
36 my @wday = qw{Sun Mon Tue Wed Thu Fri Sat};
37 my @mon = qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec};
47 if ($ARGV[0] eq '--test') {
52 if ($ARGV[0] eq '--type') {
57 if (@ARGV > 1 && $ARGV[0] eq '--target') {
59 $target = shift @ARGV;
65 if (@ARGV == 2 && $ARGV[0] eq '--file') {
66 die("bad --file arg\n") unless $ARGV[1] =~ /^(.*)\/([^\/]+)$/;
67 my ($dir, $file) = ($1, $2);
68 $file =~ s/\.(?:spec|dsc)$//;
69 opendir(D, $dir) || die("$dir: $!\n");
70 my @changes = grep {/\.changes$/} readdir(D);
72 # support _service: prefixes, they need to be stripped
73 $file =~ s/^_service:.*://;
74 my %changes = map {/^((?:_service:.*:)?(.*?))$/ ? ($2, $1) : ($_, $_)} @changes;
75 @changes = keys %changes;
76 @changes = sort {length($a) <=> length($b) || $a cmp $b} @changes;
77 exit(1) unless @changes; # nothing to do
80 my @c = grep {/\Q$file\E/} @changes;
85 last unless $file =~ s/[-.][^-.]*$//;
88 @ARGV = ("$dir/$changes{$changes[0]}");
95 die("bad changelog heading\n") unless /^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/;
101 $dt =~ /([0-9][0-9][0-9][0-9])/;
104 if (!defined($zone) && $dt =~ /\s([a-z]{3,4})(dst)?\s[0-9]{4}/) {
106 $zone = tz_offset($1);
107 $zone += 3600 if defined($zone) && $dst;
109 my $tdt = str2time($dt);
113 if ($dt =~ /([a-z]{3})\s+([a-z]{3})/) {
114 $tdt = str2time("$1 $2 $day $year");
118 if ($dt =~ /([a-z]{3})/) {
119 $tdt = str2time("$1 $day $year");
123 $tdt = str2time("$year-1-1");
125 $tdt += 12 * 3600 unless $dt =~ /\d:\d/; # 12:00 if not specified
126 $tdt += ($zone || 0);
131 last if /^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/;
132 next if (/^--------------/);
133 next if (/^========================/);
136 s/^\s*-/-/ if $ok == 1; # obsolete?
140 s/^\s*/ / unless s/^ \s*/ /;
145 return ($_, $tdt, $dline, $who, $change);
151 die("bad line: $_\n") unless /^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((\s+[-+0-9a-z.]+)+)\;.*$/;
154 my $distribution = $3;
157 my $changes = "- version $version\n";
163 die("bad maintainer line\n") unless /^ \-\- (.* <.*>) (.*)$/;
168 die("bad change details line: $_\n") unless s/^ //;
170 s/\s*\(closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*\)//i;
175 die("no maintainer line in last entry\n") unless defined $date;
176 if (!defined($zone) && ($date =~ /([-+])(\d\d)(\d\d)$/)) {
177 $zone = 60 * ($3 + 60 * $2);
178 $zone = -$zone if $1 eq '-';
180 my $tdt = str2time($date);
181 return ('', $tdt, $_, $who, $changes);
188 next if (/^--------------/);
189 next if (/^========================/);
190 if (/^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/) {
191 # suse : * Fri Jun 07 2013 First Last <first.last@example.com>
192 # tizen: * Fri Jun 07 2013 First Last <first.last@example.com> tagname@commitid
194 } elsif (/^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((\s+[-+0-9a-z.]+)+)\;.*$/) {
197 die("unknown changelog format\n");
201 exit(0) unless $format;
208 if ($target eq $format) {
216 die("don't know how to convert changelog to format '$target'\n") if $target ne 'rpm';
218 my ($lastt, $t, $dline, $who, $changes);
226 if ($format eq 'suse') {
227 ($_, $t, $dline, $who, $changes) = parse_suse($_);
228 } elsif ($format eq 'debian') {
229 ($_, $t, $dline, $who, $changes) = parse_debian($_);
231 if (defined($lastt) && $lastt < $t) {
232 die("changes file not incremental: $dline\n") if $test;
233 warn("changes file not incremental: $dline\n");
237 # silly rpm can't hande dates < 1997, so we fold everything to
239 @gm = (0, 0, 0, 2, 0, 97, 4) if $gm[5] < 97 || ($gm[5] == 97 && $gm[4] == 0 && $gm[3] <= 1);
240 printf("* %s %s %2d %4d %s\n", $wday[$gm[6]], $mon[$gm[4]], $gm[3], $gm[5] + 1900, $who);
241 $changes =~ s/%/%%/g;
242 $changes =~ s/^(\s*)%%(\S*)/$1\[%%$2\]/;
243 $changes =~ s/^(\s*)(\#\d*)/$1\[$2\]/mg;
244 $changes =~ s/^\*/ */mg;