package Mkcd::Package; our $VERSION = '0.0.4'; use File::NCopy qw(copy); use File::Path; use rpmtools; use Mkcd::Tools qw(du cleanrpmsrate printDiscsFile); require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(packageOutOfRpmsrate genDeps getLeaves getRPMsKeys getSize rpmVersionCompare); =head1 NAME Packages - mkcd module =head1 SYNOPSYS require Mkcd::Functions; =head1 DESCRIPTION C include the mkcd low level packages functions. =head1 SEE ALSO mkcd =head1 COPYRIGHT Copyright (C) 2000,2001 MandrakeSoft 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 my %ARCH = ( i586 => 1, noarch => 1, k7 => 1, ppc => 1, ia64 => 1, i686 => 2, i486 => 2, i386 => 3 ); sub genDeps{ my ($top,$reps,$deps,$VERBOSE,$TMP) = @_; $top or print "ERROR: no top dir defined\n" and return 0; -d $top or mkpath $top or die "Could not create $top\n"; $VERBOSE and print "REPS @$reps ($top/depslist.ordered)\n"; my $params = new rpmtools("sourcerpm"); my @reps = @$reps; if ($deps || ! -f "$top/depslist.ordered") { map { $_ and $_ .= "/*.rpm"} @reps; $VERBOSE and print "MAP : @reps\n"; my @rpms; my %done; foreach (map glob, @reps){ /src.rpm$/ and next; m,([^/]+)$,; $done{$1} and next; push @rpms, $_; $done{$1} = 1 } $params->build_hdlist(1, 9,"$TMP/.mkcd_build_hdlist", "$top/hdlist.cz", @rpms); $params->clean(); print "generating base files\n"; if (-r "$top/provides") { open F, "$top/provides"; $params->read_provides_files(\*F); close F; } $params->read_hdlists("$top/hdlist.cz"); $params->compute_depslist(); my @unresolved = $params->get_unresolved_provides_files(); if (@unresolved > 0) { $params->clean(); $params->read_hdlists("$top/hdlist.cz"); $params->keep_only_cleaned_provides_files(); $params->read_hdlists("$top/hdlist.cz"); $params->compute_depslist(); } # reorder the hdlist not needed for this # $params->build_hdlist(1, "$tmp/.mkcd_build_hdlist", "$top/hdlist.cz", map (glob, map( { $_ and $_ .= "/*.rpm"} map( {ref and @$_ } @$reps)))); print "writing $top/depslits.ordered\n"; open F, ">$top/depslist.ordered" or die "unable to write depslist file $top/depslist.ordered\n"; $params->write_depslist(\*F); close F; print "writing $top/provides\n"; open F, ">$top/provides" or die "unable to write provides file $top/provides\n"; $params->write_provides(\*F); close F; } else { # TODO must create a real read_depslist function that really recreate a depslist with a file. $params->read_provides_files("$top/provides"); $params->read_hdlists("$top/hdlist.cz"); # # FIXME read_hdlist is not enough and cannot be user to set params deps # $params->read_depslist("$top/depslist.ordered"); $params->compute_depslist(); my @unresolved = $params->get_unresolved_provides_files(); if (@unresolved > 0) { $params->clean(); $params->read_hdlists("$top/hdlist.cz"); $params->keep_only_cleaned_provides_files(); $params->read_hdlists("$top/hdlist.cz"); $params->compute_depslist(); } } return $params } sub packageOutOfRpmsrate{ my ($rpmsrate) = @_; my $rate = cleanrpmsrate($rpmsrate); print join("\n",sort(keys %$rate)),"\n"; 1 } sub getLeaves { my ($depslist) = @_; open DEP, "$depslist" or die "Could not open $depslist\n"; my @name; my %pkg; my $i = 0; foreach (){ chomp; my ($name, undef, @de) = split " ", $_; ($name, my $version, my $release) = $name =~ /(.*)-([^-]*)-([^-]*)/; if ($name){ foreach my $d (@de) { if ($d !~ s/^NOTFOUND_//) { my @t = split '\|',$d ; foreach my $t (@t) { if ($t !~ s/NOTFOUND_//) { $pkg{$name[$t]}++ }} }else { $pkg{$name[$d]}++} } } $name[$i] = $name; $pkg{$name[$i]}++; $i++; } foreach (sort keys %pkg){ print $pkg{$_} - 1, " $_\n"; } 1 } sub getRpmsrate{ print "ERROR: this function is deprecated\n"; return 0; my ($rpmsrate,$reps,$tmp,$name,$VERBOSE) = @_; my $TMP = $tmp || $ENV{TMPDIR}; my $tmprpmsrate = "$TMP/$name/rpmsrate"; local *R; open R, ">$tmprpmsrate" or print "ERROR: cannot open temporary rpmsrate file $tmprpmsrate\n"; my $rate = Mkcd::Tools::cleanrpmsrate($rpmsrate,*R,@$reps); close R; unlink "$rpmsrate" and copy "$tmprpmsrate", "$rpmsrate"; local *R; open R, "$rpmsrate" or print "ERROR: cannot open rpmsrate file $rpmsrate\n"; # my $rate; # my $data; # my $current; # my $max; # while (){ # s/#.*//; # comments # /^\s*$/ and next; # if (/^(\S+)/) { # $current = $1; # next # } # my ($indent,$r,$flags,$data) = /^(\s*)([1-5]?)(\s*(?:(?:!\s*)?[0-9A-Z_]+(?:"[^"]*")?(?:\s+(?:\|\|\s+)?)*)*\s*)(.*)$/; # $rate = $r > 0 ? $r : $rate; # $VERBOSE and print "getRpmsrate: current $current ($flags)\n"; # $data or next; # my @k = split ' ', $data; # $VERBOSE and print "getRpmsrate @k ($rate)\n"; # $rate > $max and $max = $rate; # @rate{@k} = map $rate, @k; # print "DEBUG @k\n"; # push @{$section{$current}}, @k # } [$rate->[0],$rate->[1]]; } # sub getreps{ # my ($lists) = @_; # my @reps; # foreach my $i (@{$lists}){ # my (undef,undef,undef,undef,@list) = @{$config[2][$i][0]}; # foreach (@list){ # my $t = $config[1][$i]; # ref $t or next; # foreach (@{$t->[1]}) { # $VERBOSE and print "REPOSITORY $_->[1] -- $_->[2]\n"; # push @{$reps[$i]} , $_->[0] } # } # } # return (\@reps) #} sub getRPMsKeys{ my ($list,@hdlist) = @_; my %keys; foreach (@hdlist){ my $packer = new packdrake($_); my $count = scalar keys %{$packer->{data}}; print "$count files in archive, uncompression method is \"$packer->{uncompress}\"\n"; foreach my $file (@{$packer->{files}}) { if ($file =~ /(.*):(.*)/){ $keys{rpm}{$1} = $2; $keys{key}{$2} = $1 }else{ $keys{rpm}{$file} = $file; $keys{key}{$file} = $file } $list and printf "l %13c %s -> %s\n", ' ', $file, $packer->{data}{$file}[1] } } return \%keys } sub getSize{ my ($group,$config,$VERBOSE) = @_; my $max; my $redeps; foreach my $listnumber (keys %{$group->{list}}){ print "getSize list $listnumber\n"; my $repnb; $group->{nodeps}{$listnumber} and next; #$config[1][$listnumber][2]{done} and next; my $testarch = join '|', keys %ARCH; foreach (@{$config->{list}[$listnumber]{packages}}) { $repnb++; my ($dir, @srpms) = @{$_}; $VERBOSE and print "getSize DIRECTORY $dir\n"; local *RPMS; opendir RPMS, $dir or print "WARNING: getSize: cannot open $dir\n" and next; foreach (readdir RPMS){ /(.*)\.rpm$/ or next; /src\.rpm$/ and next; my $rpm = $group->{rpmkey}{key}{$1} or print "$1 not in depslist, forcing rebuilt\n" and return 2; my $b = Mkcd::Tools::du("$dir/$_"); $b or print "ERROR getSize: $rpm has a zero size\n"; ref $group->{size}{$rpm}{$listnumber} and print "ERROR getSize: duplicate $rpm in list $listnumber, ignoring\n" and next; $group->{size}{$rpm}{$listnumber} = [$b,$dir,$repnb]; push @{$group->{listrpm}{$listnumber}}, $rpm; $group->{listsize}{$listnumber}{rpm} += $b; $b > $max and $max = $b; } foreach $dir (@srpms){ $VERBOSE and print "getSize DIRECTORY $dir\n"; local *SRPMS; opendir SRPMS, $dir or print "WARNING: getSize: cannot open $dir\n" and next; foreach (readdir SRPMS){ /\.rpm$/ or next; /($testarch)\.rpm$/ and next; my ($srpm,$srpmname,$key); if (($srpm,$srpmname) = /((.*)-[^-]*-[^-]*\.src)\.rpm$/){ $key = $srpm; }else { ($key) = /(.*)\.rpm$/; my %header; tie %header, "RPM::Header", "$dir/$_" or print "ERROR getSize: $RPM::err" and next; $header{'SOURCERPM'} eq "(none)" or next; $srpmname = $header{'NAME'}; $srpm = "$srpmname-$header{'VERSION'}-$header{'RELEASE'}.src"; } $group->{rpmkey}{key}{$key} = $srpm; $group->{rpmkey}{rpm}{$srpm} = $key; my $b = Mkcd::Tools::du("$dir/$_"); $b or print "ERROR getSize: $srpm has a zero size\n"; ref $group->{size}{$srpm}{$listnumber} and print "ERROR getSize: duplicate $srpm in list $listnumber, ignoring\n" and next; $group->{size}{$srpm}{$listnumber} = [$b,$dir,$repnb]; $group->{srpmname}{$srpmname} = $srpm; } } } } $group->{maxsize} = $max; 1 } sub rpmVersionCompare{ my ($pkg1, $pkg2) = @_; my ($n1,$v1,$r1,$a1) = $pkg1 =~ /^(.*)-([^-]+)-([^-]+)\.([^.]+)(\.rpm)?$/; my ($n2,$v2,$r2,$a2) = $pkg2 =~ /^(.*)-([^-]+)-([^-]+)\.([^.]+)(\.rpm)?$/; die "ERROR rpmVersionCompare: trying to compare version of two differently named packages ($pkg1,$pkg2)\n" if (!($n1 eq $n2)) ; my $ret = rpmtools::version_compare($v1,$v2); if ($ret){ return $ret }else{ $ret = rpmtools::version_compare($r1,$r2); if ($ret){ return $ret }else{ if($ARCH{$a1} < $ARCH{$a2}){ return -1 }elsif($ARCH{$a1} > $ARCH{$a2}){ return 1 }else{ return 0 } } } } 1