diff options
-rwxr-xr-x | clean-rpmsrate | 19 | ||||
-rw-r--r-- | pm/MGATools/rpmsrate.pm | 214 |
2 files changed, 233 insertions, 0 deletions
diff --git a/clean-rpmsrate b/clean-rpmsrate new file mode 100755 index 0000000..c8b11d4 --- /dev/null +++ b/clean-rpmsrate @@ -0,0 +1,19 @@ +#!/usr/bin/perl +# +# + +use strict; +use MGATools::rpmsrate qw(cleanrpmsrate); + +$ARGV[0] =~ /-o/ and shift @ARGV and my $rpmsrate = shift; + +$ARGV[1] or print "\nUsage: + clean-rpmsrate [options] <rpmsrate file> <RPMs dir 1> <RPMs dir 2> ... <RPMs dir n> + + options: + -o file: output file\n\n" and exit; + +my %rpm; +my $rpmsrate_base = shift @ARGV; +foreach my $d (@ARGV) { $rpm{$d} = [ map { s/$d\/?(.*)\.rpm$/$1/; $_ } glob "$d/*.rpm" ] }; +cleanrpmsrate($rpmsrate_base,$rpmsrate,0, \%rpm); diff --git a/pm/MGATools/rpmsrate.pm b/pm/MGATools/rpmsrate.pm new file mode 100644 index 0000000..d92ecd8 --- /dev/null +++ b/pm/MGATools/rpmsrate.pm @@ -0,0 +1,214 @@ +package MGATools::rpmsrate; + +use strict; +use MDK::Common qw(any member); + +require Exporter; +use URPM; +our @ISA = qw(Exporter);; +our @EXPORT = qw(cleanrpmsrate); + +=head1 NAME + +Mageia rpmsrate tools + +=head1 SYNOPSYS + + require MGATools::rpmsrate; + +=head1 DESCRIPTION + +<MGATools::rpmsrate> includes Mageia rpmsrate tools. + +=head1 COPYRIGHT + +Copyright (C) 2000,2001,2002,2003,2004 Mandriva <warly@mandriva.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +=cut + +# function copied from Mkcd::Tools +sub cleanrpmsrate { + my ($rpmsrate, $output, $norpmsrate, $reprpms, $urpm) = @_; + $norpmsrate ||= []; + my $LOG; open $LOG, ">&STDERR"; + open my $A, $rpmsrate or print $LOG "ERROR: cannot open $rpmsrate\n"; + my (@rpmsrate, %potloc); + # must preread to get locale guessed packages + # postfix is just used not to break the diff when checking if the result is correct + while (<$A>) { + chomp; + s/#.*//; + #s/\s*$//; + /^(\s*)$/ and push @rpmsrate, [ '', 0, '', [] ] and next; + if (/^(\S+)(.*)$/) { + push @rpmsrate, [ 0, 0, $1, [], $2 ]; + next + } + if (/^(\s*)([1-5])?(\s?[0-9A-Z_]+)$/) { + push @rpmsrate, [ $1, $2, $3, [] ]; + next + } + my ($indent, $r, $flags, $data) = /^(\s*)([1-5])?(\s*(?:(?:(?:!\s*)?[0-9A-Z_]+(?:"[^"]*")?(?:\s+(?:\|\|\s+)?)*)+\s+)|\s*)(.*)$/; + my ($postfix) = $data =~ /(\s*)$/; + my @data; + my $i; + foreach ([$data =~ /(?:^|\s)(\S+)-(?:\S+)\s+\1-(?:\S+)(?:\s|$)/g], [split ' ', $data]) { + $data[$i++] = [ @$norpmsrate ? any { my $r = $_; $r if !any { $r =~ /$_/ } @$norpmsrate } @$_ : @$_ ] + } + $potloc{$_} = [] foreach @{$data[0]}; + push @rpmsrate, [ $indent,$r, $flags, $data[1], $postfix ]; + } + my (%rpms, $text); + my (%rate, %section, %keyword); + my (%locale, %localized_pkg, %kernel_version); + my @plain_flags = qw(INSTALL LIVE); + my $kernel_like = "((?:(?:NVIDIA_)?kernel|NVIDIA_nforce|cm2020).*)"; + my $dkms_like = "(.*)([-_])kernel-([0-9]+(?:\.[0-9]+){2,3}-[0-9]+(?:.[^.]+){0,2}md[vk])(.*)"; + my $rpmsrate_dkms_like = "(.*[-_]kernel)(.*)"; + my $urpm2 = new URPM; + foreach my $dir (keys %$reprpms) { + foreach (@{$reprpms->{$dir}}) { + my $rpm = "$_.rpm"; + my $key = $_; + s/-[^-]+-[^-]+\.[^.]+$// or next; + any { $rpm =~ /$_/ } @$norpmsrate and next; + if (/(.*?)([_-]*[\d._]+)(-.*)?-devel$/ || /^$kernel_like(-[^.]+(?:\.[^.]+){3,6}md[vk])$/) { + if (!$rpms{"$1$3"}) { $rpms{"$1$3"} = [ $2, $1, $3 ] } + elsif (URPM::ranges_overlap("== $2", "> $rpms{'$1$3'}")) { $rpms{"$1$3"} = [ $2, $1, $3 ] } + if (/^$kernel_like-(\d+\.\d+)(.*)/) { $rpms{"$1-$2"} = [ $3, "$1-$2" ]} + } elsif (/^$dkms_like$/) { + my $vname = "$1$2kernel$4"; + if (!$rpms{$vname}) { $rpms{$vname} = [ $3, $vname ] } + elsif (URPM::ranges_overlap("== $3", "> $rpms{$vname}[0]")) { $rpms{$vname} = [ $3, $vname ] } + } elsif (my ($pg, $loc) = /^(.*)-([^-+]+)$/) { + if ($potloc{$pg}) { + my $pkg; + $pkg = $urpm->{rpm}{$urpm->{rpmkey}{key}{$key}} if ref $urpm; + if (!$pkg) { + my $id = $urpm2->parse_rpm("$dir/$rpm"); + $pkg = $urpm2->{depslist}[$id]; + } + if (!$pkg) { + print "ERROR cleanrpmsrate: parse_rpm $dir/$rpm ($key) failed\n"; + next + } + # some i18n packages does not require the same locale, e.g. kde-i18n-nb and nn requires locales-no + # if (grep { s/locales-// && $loc =~ /^$_(_|$)/ } @{$header{REQUIRENAME}}) { + if (any { /^locales-...?$/ } $pkg->requires) { + push @{$locale{$pg}}, $loc; + $localized_pkg{"$pg-$loc"} = 1 + } + } + } + } + } + my (%done, @flags, $prev, @tree_rate, $prev_level); + foreach (@rpmsrate) { + if (!$_->[0]) { + $text .= "$_->[2]$_->[4]\n"; + if ($_->[2]) { + @flags = $_->[2] + } + next + } + my ($indent, $r, $flags, $data, $postfix) = @$_; + my $level = (length $indent)/2 - 1; + my $rate; + if ($r) { + #print "tree_rate[$level] = $r\n"; + $rate = $r; + $tree_rate[$level] = $r + } else { + if (@$data) { + if ($level > $prev_level) { + $level-- + } else { + # fix a syntax error in rpmsrate such as + # A + # 1 toto + # B tata <--- + # 4 titi + @$data = () + } + } + $rate = $tree_rate[$level]; + } + $prev_level = $level; + @flags = @flags[0 .. $level]; + push @flags, split(' ', $flags); + #push @flags, grep { s/\s//; !/(\|\||[A-Z_]+"[^"]+")/ } split(' ', $flags); + my $flat_path = join ' ', @flags; + if (!@$data) { $text .= "$indent$r$flags$postfix\n"; next } + my @k; + foreach (@$data) { + my $c = $_; + next if ref $done{$_} && any { $flat_path eq $_ } @{$done{$_}}; + die "FATAL: too complicated flags for duplicate entry $c ($flat_path and " . join ',', @{$done{$_}} + if !member($flags[0], @plain_flags) && @flags > 1 && any { + my ($f) = $flat_path =~ /^[^ ]+ (.*)/; + !/^[^ ]+ (.*)/ || $1 ne $f + } @{$done{$_}}; + my ($d) = /(.*)-[^-]+/; + my ($a, $b, $e); + my $do; + if ((!member($flags[0], @plain_flags) && s/(-devel)// ? ($b = "-devel") : /^$kernel_like/) && (($rpms{$_}) || (defined $rpms{"lib$_"} and $a = "lib") || (defined $rpms{"lib64$_"} and $a = "lib64") || ($_ =~ s/^lib(.*?)[_-]*[\d._]*(-.*)?$/$1$2/g && defined $rpms{"lib64$_"} and $a = 'lib64'))) { + $e = $rpms{"$a$_"}[1] . $rpms{"$a$_"}[0] . $rpms{"$a$_"}[2] . $b; + $do = 1 + } elsif ((!member($flags[0], @plain_flags) && /^$rpmsrate_dkms_like$/ && $rpms{"$1$2"})) { + $e = "$1-" . $rpms{"$1$2"}[0] . "$2"; + $do = 1 + } + if ($do) { + $keyword{$c} = $e; + if (! ref $done{$e} || member($flags[0], @plain_flags) && ! (any { $flat_path eq $_ } @{$done{$e}}) || $flat_path =~ /DRIVER|HW/ ) { push @{$done{$e}}, $flat_path; push @k, $e } + } + if ($locale{$d} && $localized_pkg{$c}) { + foreach (sort @{$locale{$d}}) { + next if any { $_ eq $flat_path } @{$done{"$d-$_"}}; + push @{$done{"$d-$_"}}, $flat_path; + push @k , "$d-$_" + } + next + } + push @k, $c; + push @{$done{$c}}, $flat_path + } + if (@k) { $text .= "$indent$r$flags@k$postfix\n" } + @rate{@k} = ($rate) x @k; + my $path; + foreach (@flags) { + $path .= $path ? "/$_" : $_; + push @{$section{$path}}, @k + } + } + if (%rpms || $output || %locale) { + if (%$reprpms || $output) { + $output ||= $rpmsrate; + if (open A, ">$output") { + print A $text; + close A + } else { + print $LOG "ERROR cleanrpmsrate: cannot open $rpmsrate for writing\n"; + print $text + } + } + } + [\%rate, \%section, \%keyword] +} + +1 + |