#!/usr/bin/perl # # $Id$ # #- Copyright (C) 1999-2005 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. use strict; use Cwd; use URPM; use URPM::Build; use Getopt::Long; use Distribconf::Build; my $urpm = new URPM; my $headers_dir = (-d $ENV{TMPDIR} ? $ENV{TMPDIR} : -d "$ENV{HOME}/tmp" ? "$ENV{HOME}/tmp" : "/tmp") . "/.build_hdlist"; sub usage { print STDERR < sub { usage(); exit }, 'compss=s' => \$urpmfiles{compss}, 'depslist=s' => \$urpmfiles{depslist}, 'distrib=s' => \my $rootdistrib, 'fermetagueule|s' => \my $nooutput, 'hdlists=s' => \$urpmfiles{hdlists}, 'mediacfg=s' => \$urpmfiles{mediacfg}, 'headersdir=s' => \$headers_dir, 'nobadrpm' => \my $dontdie, 'skipmissingdir' => \my $skipmissingdir, 'nochkdep' => \my $nochkdep, 'noclean' => \my $noclean, 'provides=s' => \$urpmfiles{provides}, 'nomediainfo' => \my $nomediainfo, 'nomd5sum' => \my $nomd5sum, ); my @root = grep { $_ } ($rootdistrib, @ARGV); @root > 0 or do { usage(); exit 1 }; my $distrib = Distribconf::Build->new($root[0]); $distrib->loadtree or die "$root[0] does not seems to be a distrib tree"; if (defined($urpmfiles{mediacfg})) { $distrib->parse_mediacfg($urpmfiles{mediacfg}) or die "Can't read $urpmfiles{mediacfg}"; } elsif (defined($urpmfiles{hdlists})) { $distrib->parse_hdlists($urpmfiles{hdlists}) or die "Can't read $urpmfiles{hdlists}"; } else { $distrib->parse_mediacfg || $distrib->parse_hdlists or die "Can't read the dsitrib config"; } my %default_urpmfiles = ( depslist => $distrib->getfullpath(undef, "infodir") . "/depslist.ordered", provides => $distrib->getfullpath(undef, "infodir") . "/provides", compss => $distrib->getfullpath(undef, "infodir") . "/compss", version => $distrib->getfullpath(undef, "VERSION"), md5sum => $distrib->getfullpath(undef, "infodir") . "/MD5SUM", ); while (my ($k, $v) = each(%default_urpmfiles)) { $urpmfiles{$k} ||= $v; } $distrib->check(\*STDERR) unless($nooutput); my @hdlists; foreach ($distrib->listmedia) { $distrib->getvalue($_, 'askmedia') || $distrib->getvalue($_, 'suppl') and next; if (! -d $distrib->getfullpath($_, 'path')) { if ($skipmissingdir) { printf STDERR "Skipping missing media %s\n", $distrib->getpath($_, 'path') unless $nooutput; next; } else { die sprintf("Missing dir '%s' for media '%s'", $distrib->getpath($_, 'path'), $distrib->getvalue($_, 'name')); } } push @hdlists, { synthesis => $distrib->getfullpath($_, 'synthesis'), hdlist => $distrib->getfullpath($_, 'hdlist'), dir => $distrib->getpath($_, 'path'), descr => $distrib->getvalue($_, 'name'), mediainfo => $distrib->getfullpath(undef, 'infodir'), thismediainfo => $distrib->getfullpath($_, 'path') . "/media_info", synthesis2 => $distrib->getfullpath($_, 'path') . "/media_info/synthesis.hdlist.cz", hdlist2 => $distrib->getfullpath($_, 'path') . "/media_info/hdlist.cz", md5sum => $distrib->getfullpath($_, 'path') . "/media_info/MD5SUM", }; } sub clean_cache { unless ($noclean) { system($ENV{LD_LOADER} ? $ENV{LD_LOADER} : @{[]}, "rm", "-rf", $headers_dir); mkdir $headers_dir or print STDERR qq(Can't create directory "$headers_dir": $!\n); } } clean_cache(); foreach (0..$#hdlists) { my $e = $hdlists[$_]; my $r; #- try to find the right repository where can be found the directory #- listed in the hdlist file. #- if the number of root is equal the number of medium, assume a medium #- foreach root, else try to find a valid root containing the medium. $r ||= $root[0]; if (scalar(@hdlists) == scalar(@root)) { $r = $root[$_]; } else { foreach (@root) { -d "$_/$e->{dir}" and $r = $_, last; } } #- fake build of architecture dependent directory. my @files; if ($e->{dir} =~ /%{ARCH}/) { foreach my $arch (qw(i686 i586 i486 i386 k8 k7 k6 amd64 amd32 x86_64 x86_32 ia64 ia32 ppc sparc sparc32 sparc64 alpha noarch)) { my $dir = $e->{dir}; $dir =~ s|%{ARCH}|$arch|g; push @files, glob("$r/$dir/*.$arch.rpm"); } } else { push @files, glob("$r/$e->{dir}/*.rpm"); } @files or die "unable to find rpm files in $e->{dir}\n"; print STDERR "parsing rpm files in directory $r/$e->{dir}\n" unless $nooutput; my @headers = $urpm->parse_rpms_build_headers( dir => $headers_dir, rpms => \@files, dontdie => $dontdie, silent => $nooutput, ); $e->{headers} = \@headers; } #- clean everything to start second pass. print STDERR "clean data for second pass\n" unless $nooutput; $urpm->unresolved_provides_clean; foreach (0..$#hdlists) { my $e = $hdlists[$_]; print STDERR qq(parsing headers for "$e->{descr}"\n) unless $nooutput; my ($start, $end) = $urpm->parse_headers(dir => $headers_dir, headers => $e->{headers}, dontdie => $dontdie, silent => $nooutput); print STDERR "computing deps\n" unless $nooutput; $urpm->compute_deps; print STDERR qq(building hdlist for medium "$e->{descr}"\n) unless $nooutput; $urpm->build_hdlist(start => $start, end => $end, dir => $headers_dir, hdlist => $e->{hdlist}, ratio => 9); print STDERR qq(building synthesis for medium "$e->{descr}"\n) unless $nooutput; $urpm->build_synthesis(start => $start, end => $end, synthesis => $e->{synthesis}); unless ($nomediainfo && $nomd5sum) { if (! -d $e->{mediainfo}) { mkdir $e->{mediainfo}, 0755 or print STDERR qq(Can't create directory "$e->{mediainfo}": $!\n); } } unless ($nomediainfo) { if (! -d $e->{thismediainfo}) { mkdir $e->{thismediainfo}, 0755 or print STDERR qq(Can't create directory "$e->{thismediainfo}": $!\n); } print STDERR qq(link alternate locations of synthesis and hdlists\n) unless $nooutput; unlink $e->{hdlist2}, $e->{synthesis2}; link $e->{hdlist}, $e->{hdlist2} or print STDERR qq(link failed for "$e->{hdlist2}": $!\n); link $e->{synthesis}, $e->{synthesis2} or print STDERR qq(link failed for "$e->{synthesis2}": $!\n); } unless ($nomd5sum) { print STDERR qq(generate MD5SUM for media\n); my $here = getcwd(); chdir $e->{mediainfo}; my $md5sum = `/usr/bin/md5sum hdlist* synthesis*`; chdir $here; if (open my $md5sumfh, '>', $e->{md5sum}) { print $md5sumfh $md5sum; close $md5sumfh; } else { print STDERR qq(Can't create "$e->{md5sum}": $!\n); } } } clean_cache(); print STDERR "building base files\n" unless $nooutput; $urpm->build_base_files(depslist => $urpmfiles{depslist}, provides => $urpmfiles{provides}, compss => $urpmfiles{compss}); #compatibility if (-f $distrib->getpath(undef, 'root') . '/' . $distrib->getpath(undef, 'infodir') . '/media.cfg') { if (! -f $distrib->getpath(undef, 'root') . '/' . $distrib->getpath(undef, 'infodir') . '/hdlists' || ((stat($distrib->getpath(undef, 'root') . '/' . $distrib->getpath(undef, 'infodir') . '/media.cfg'))[9] > (stat($distrib->getpath(undef, 'root') . '/' . $distrib->getpath(undef, 'infodir') . '/hdlists'))[9])) { print STDERR "Write hdlists files\n" unless($nooutput); $distrib->write_hdlists(); } } #- safety cleaning unlink $urpmfiles{md5sum}; unless ($nomd5sum) { my $here = getcwd(); chdir $distrib->getpath(undef, 'root') . "/" . $distrib->getpath(undef, 'infodir'); my $md5sum = `/usr/bin/md5sum hdlist* synthesis*`; chdir $here; if (open my $md5sumfh, '>', $urpmfiles{md5sum}) { print $md5sumfh $md5sum; close $md5sumfh; } else { print STDERR qq(Can't create "$urpmfiles{md5sum}": $!\n); } } print STDERR "Building Version file\n" unless($nooutput); $distrib->write_version($urpmfiles{version}); #- check if there are NOTFOUND in dependencies, check if they are in other media, warn the user. if ($nooutput || !$nochkdep) { foreach (0 .. $#{$urpm->{depslist}}) { my $pkg = $urpm->{depslist}[$_]; foreach (split " ", $urpm->{deps}[$_]) { /NOTFOUND_(.*)/ or next; print STDERR $pkg->fullname . " requires [$1] which\n"; if ($urpm->{provides}{$1}) { print STDERR " is available on packages not listed in this medium or previous medium:\n"; foreach (keys %{$urpm->{provides}{$1}}) { my $dep_pkg = $urpm->{depslist}[$_]; print STDERR " " . $dep_pkg->fullname . "\n"; } } else { print STDERR " is not available in any medium listed\n"; if (/NOTFOUND_(\D*)(\d+[\.\-\d]*)?(.*)?\.so\./) { my $re = (quotemeta $1) . '(\d+[\.\-\d]*)' . (!$2 && "?") . '\.so\.'; foreach (keys %{$urpm->{provides}}) { /$re/ or next; print STDERR " but a similar provides is available as [$_], need rebuild ?\n"; } } } } } }