/[soft]/mgatools/trunk/pm/MGATools/rpmsrate.pm
ViewVC logotype

Contents of /mgatools/trunk/pm/MGATools/rpmsrate.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3500 - (show annotations) (download)
Thu Mar 15 13:11:43 2012 UTC (12 years, 1 month ago) by tv
File size: 7992 byte(s)
(cleanrpmsrate) fix matching dkms (broken for years...)
1 package MGATools::rpmsrate;
2
3 use strict;
4 use MDK::Common;
5
6 require Exporter;
7 use URPM;
8 our @ISA = qw(Exporter);
9 our @EXPORT = qw(cleanrpmsrate);
10
11 =head1 NAME
12
13 Mageia rpmsrate tools
14
15 =head1 SYNOPSYS
16
17 require MGATools::rpmsrate;
18
19 =head1 DESCRIPTION
20
21 <MGATools::rpmsrate> includes Mageia rpmsrate tools.
22
23 =head1 COPYRIGHT
24
25 Copyright (C) 2000,2001,2002,2003,2004 Mandriva <warly@mandriva.com>
26
27 This program is free software; you can redistribute it and/or modify
28 it under the terms of the GNU General Public License as published by
29 the Free Software Foundation; either version 2, or (at your option)
30 any later version.
31
32 This program is distributed in the hope that it will be useful,
33 but WITHOUT ANY WARRANTY; without even the implied warranty of
34 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 GNU General Public License for more details.
36
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40
41 =cut
42
43 # must preread to get locale guessed packages
44 sub preread_rpmsrate {
45 my ($rpmsrate, $norpmsrate) = @_;
46 my (@rpmsrate, %potloc);
47 foreach (cat_or_die($rpmsrate)) {
48 chomp;
49 s/#.*//;
50 #s/\s*$//;
51 if (/^(\s*)$/) {
52 push @rpmsrate, [ '', 0, '', [] ];
53 next;
54 }
55 if (/^(\S+)(.*)$/) {
56 push @rpmsrate, [ 0, 0, $1, [], $2 ];
57 next;
58 }
59 if (/^(\s*)([1-5])?(\s?[0-9A-Z_]+)$/) {
60 push @rpmsrate, [ $1, $2, $3, [] ];
61 next;
62 }
63 my ($indent, $r, $flags, $data) = /^(\s*)([1-5])?(\s*(?:(?:(?:!\s*)?[0-9A-Z_]+(?:"[^"]*")?(?:\s+(?:\|\|\s+)?)*)+\s+)|\s*)(.*)$/;
64 # postfix is just used not to break the diff when checking if the result is correct
65 my ($postfix) = $data =~ /(\s*)$/;
66 my (@data, $i);
67 foreach ([$data =~ /(?:^|\s)(\S+)-(?:\S+)\s+\1-(?:\S+)(?:\s|$)/g], [split ' ', $data]) {
68 $data[$i++] = [ @$norpmsrate ? any { my $r = $_; any { $r =~ /$_/ } @$norpmsrate ? @{[]} : $r } @$_ : @$_ ];
69 }
70 $potloc{$_} = [] foreach @{$data[0]};
71 push @rpmsrate, [ $indent,$r, $flags, $data[1], $postfix ];
72 }
73 (\@rpmsrate, \%potloc);
74 }
75
76 sub lookup_pkg {
77 my ($key, $fullpath, $urpm2, $o_urpm) = @_;
78
79 # try to lookup package in urpm first (if we got an $urpm and if media were parsed):
80 return $o_urpm->{rpm}{$o_urpm->{rpmkey}{key}{$key}} if ref($o_urpm);
81
82 # if package is not urpmi' synthesis, try to parse it directly:
83 my $id = $urpm2->parse_rpm($fullpath);
84 return $urpm2->{depslist}[$id];
85 }
86
87 sub check_if_expandable {
88 my ($key, $raw, $fullpath, $potloc, $locale, $localized_pkg, $urpm2, $o_urpm) = @_;
89 my ($pg, $loc) = $raw =~ /^(.*)-([^-+]+)$/;
90 return if !$pg || !$loc;
91 return if !$potloc->{$pg};
92
93 my $pkg = lookup_pkg($key, $fullpath, $urpm2, $o_urpm);
94
95 # still nothing? bailout:
96 if (!$pkg) {
97 print "ERROR cleanrpmsrate: parse_rpm $fullpath ($key) failed\n";
98 next;
99 }
100
101 # some i18n packages does not require the same locale, e.g. kde-i18n-nb and nn requires locales-no
102 # if (grep { s/locales-// && $loc =~ /^$_(_|$)/ } @{$header{REQUIRENAME}}) {
103 if (any { /^locales-...?$/ } $pkg->requires) {
104 push @{$locale->{$pg}}, $loc;
105 $localized_pkg->{"$pg-$loc"} = 1;
106 }
107 }
108
109 # function copied from Mkcd::Tools
110 sub cleanrpmsrate {
111 my ($rpmsrate_file, $output, $norpmsrate, $reprpms, $o_urpm) = @_;
112 $norpmsrate ||= [];
113
114 my ($rpmsrate, $potloc) = preread_rpmsrate($rpmsrate_file, $norpmsrate);
115
116 my (%rpms, $text, %rate, %section, %keyword, %locale, %localized_pkg);
117 my @plain_flags = qw(INSTALL LIVE);
118 my $kernel_like = "((?:(?:NVIDIA_)?kernel|NVIDIA_nforce|cm2020).*)";
119 my $dkms_like = '(.*)([-_])kernel-([0-9]+(?:\.[0-9]+){2,3}-\w+-[0-9]+(?:.[^.]+){0,2}\.?mga\d+)(.*)';
120 my $rpmsrate_dkms_like = "(.*[-_]kernel)(.*)";
121 my $urpm2 = URPM->new;
122
123 foreach my $dir (keys %$reprpms) {
124 foreach (@{$reprpms->{$dir}}) {
125 my $rpm = "$_.rpm";
126 my $key = $_;
127 s/-[^-]+-[^-]+\.[^.]+$// or next;
128 any { $rpm =~ /$_/ } @$norpmsrate and next;
129
130 if (/(.*?)([_-]*[\d._]+)(-.*)?-devel$/ || /^$kernel_like(-[^.]+(?:\.[^.]+){3,6}\.?mga\d+)$/) {
131 if (!$rpms{"$1$3"} || URPM::ranges_overlap("== $2", "> $rpms{'$1$3'}")) {
132 $rpms{"$1$3"} = [ $2, $1, $3 ];
133 }
134 if (/^$kernel_like-(\d+\.\d+)(.*)/) {
135 $rpms{"$1-$2"} = [ $3, "$1-$2" ];
136 }
137 } elsif (/^$dkms_like$/) {
138 my $vname = "$1$2kernel$4";
139 if (!$rpms{$vname}) {
140 $rpms{$vname} = [ $3, $vname ];
141 } elsif (URPM::ranges_overlap("== $3", "> $rpms{$vname}[0]")) {
142 $rpms{$vname} = [ $3, $vname ];
143 }
144 } else {
145 check_if_expandable($key, $_, "$dir/$rpm", $potloc, \%locale, \%localized_pkg, $urpm2, $o_urpm);
146 }
147 }
148 }
149
150 my (%done, @flags, @tree_rate, $prev_level);
151 foreach (@$rpmsrate) {
152 if (!$_->[0]) {
153 $text .= "$_->[2]$_->[4]\n";
154 @flags = $_->[2] if $_->[2];
155 next;
156 }
157
158 my ($indent, $r, $flags, $data, $postfix) = @$_;
159 my $level = (length $indent)/2 - 1;
160 my $rate;
161 if ($r) {
162 #print "tree_rate[$level] = $r\n";
163 $rate = $r;
164 $tree_rate[$level] = $r;
165 } else {
166 if (@$data) {
167 if ($level > $prev_level) {
168 $level--;
169 } else {
170 # fix a syntax error in rpmsrate such as
171 # A
172 # 1 toto
173 # B tata <---
174 # 4 titi
175 @$data = ();
176 }
177 }
178 $rate = $tree_rate[$level];
179 }
180
181 $prev_level = $level;
182 @flags = @flags[0 .. $level];
183 push @flags, split(' ', $flags);
184 #push @flags, grep { s/\s//; !/(\|\||[A-Z_]+"[^"]+")/ } split(' ', $flags);
185
186 if (!@$data) {
187 $text .= "$indent$r$flags$postfix\n";
188 next;
189 }
190
191 my @k;
192 my $flat_path = join ' ', @flags;
193 foreach (@$data) {
194 my $c = $_;
195 next if ref $done{$_} && any { $flat_path eq $_ } @{$done{$_}};
196
197 my $is_plain_flag = member($flags[0], @plain_flags);
198
199 die "FATAL: too complicated flags for duplicate entry $c ($flat_path and " . join ',', @{$done{$_}}
200 if !$is_plain_flag && @flags > 1 && any {
201 my ($f) = $flat_path =~ /^[^ ]+ (.*)/;
202 !/^[^ ]+ (.*)/ || $1 ne $f;
203 } @{$done{$_}};
204
205 my ($name) = /(.*)-[^-]+/;
206 my ($e, $do);
207
208 if (!$is_plain_flag) {
209 my ($a, $b);
210 if ((s/(-devel)// ? ($b = "-devel") : /^$kernel_like/) &&
211 ($rpms{$_} || (defined $rpms{"lib$_"} and $a = "lib") || (defined $rpms{"lib64$_"} and $a = "lib64")
212 || (s/^lib(.*?)[_-]*[\d._]*(-.*)?$/$1$2/g && defined $rpms{"lib64$_"} and $a = 'lib64'))) {
213 warn ">> looking at $c\n";
214 $e = $rpms{"$a$_"}[1] . $rpms{"$a$_"}[0] . $rpms{"$a$_"}[2] . $b;
215 $do = 1;
216 } elsif (/^$rpmsrate_dkms_like$/ && $rpms{"$1$2"}) {
217 $e = "$1-" . $rpms{"$1$2"}[0] . $2;
218 $do = 1;
219 }
220
221 }
222
223 if ($do) {
224 $keyword{$c} = $e;
225 if (!ref $done{$e} || $is_plain_flag && !(any { $flat_path eq $_ } @{$done{$e}}) || $flat_path =~ /DRIVER|HW/) {
226 push @{$done{$e}}, $flat_path;
227 push @k, $e;
228 }
229 }
230
231 # process localized packages (eg: man-pages-XX, hunspell-XX, firefox-XX, ...)
232 if ($locale{$name} && $localized_pkg{$c}) {
233 foreach (sort @{$locale{$name}}) {
234 next if member($flat_path, @{$done{"$name-$_"}});
235 push @{$done{"$name-$_"}}, $flat_path;
236 push @k , "$name-$_";
237 }
238 next;
239 }
240 push @k, $c;
241 push @{$done{$c}}, $flat_path;
242 }
243
244 $text .= "$indent$r$flags@k$postfix\n" if @k;
245 @rate{@k} = ($rate) x @k;
246 my $path;
247 foreach (@flags) {
248 $path .= $path ? "/$_" : $_;
249 push @{$section{$path}}, @k;
250 }
251 }
252
253 if (%rpms || $output || %locale) {
254 if (%$reprpms || $output) {
255 $output ||= $rpmsrate_file;
256 if (open my $A, ">$output") {
257 print $A $text;
258 } else {
259 warn "ERROR cleanrpmsrate: cannot open $rpmsrate_file for writing\n";
260 print $text;
261 }
262 }
263 }
264
265 [\%rate, \%section, \%keyword];
266 }
267
268 1
269

  ViewVC Help
Powered by ViewVC 1.1.30