Re: Merging updates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2002-01-28 at 15:48, John Summerfield wrote:
> I've seen the question asked, but I don't recall a good answer.
> 
> Does anyone have a reliable script that will take a package set (as 
> from the original CD collection) and merge in an updates tree, removing 
> old versions of packages?

Why, yes.  Here is one that we use.  It needs rpm-perl to be installed
to operate properly.

Thanks.
Peter



#!/usr/bin/perl -w
#
# $Id: overlay.pl,v 1.5 2002/01/25 00:57:21 pzb Exp $
#
# Overlays a set of RPMS on another directory of RPMs deleting old
# versions as necessary.
#
# Licensed under the GPL
#

use File::Basename;
use RPM::Header;
$arches = "alpha axp noarch";

while ($ARGV[0] =~ /^--/) {
	$_ = shift;
	chomp;
	$arches = shift if /--arches/;
	$linkdir = shift if /--linkdir/;
	$passcond = shift if /--passcond/;
	$pkglist = shift if /--pkglist/;
}

$basedir = shift;
$patchdir = join " ", @ARGV;
$notupdated = 0;

if ($patchdir eq "" || $basedir eq "") {
    print STDERR "Usage: overlay basedir patchdir\n";
    exit 0;
}

@archlist = split / /, $arches;
foreach (@archlist) {
	$validarch{$_} = 1;
}

sub rpm_fullname {
    local($rpm) = @_;
    return basename($rpm->source_name());
    return $rpm->{"NAME"} . "-" . $rpm->{"VERSION"} . "-" . $rpm->{"RELEASE"} . "." . &rpm_arch($rpm) . ".rpm";
}

sub rpm_arch {
    local($rpm) = @_;
    return $rpm->is_source() ? "src" : $rpm->{"ARCH"};
}

sub make_rpmlist {
    local($dirs) = @_;
    local($dirhandle, $file, $dir);
    local(@allfiles, @rpmlist);
    @rpmlist = ();
    foreach $dir (split ' ', $dirs) {
        opendir $dirhandle, $dir or die "Couldn't open", $dir;
        $file = readdir $dirhandle;
        while (defined($file)) {
             $basename = $file;
             $file = $dir . "/" . $file;
             if ((substr $basename, 0, 1) eq ".") {
             } elsif (-d $file) {
                 push @rpmlist, make_rpmlist($file);
             } elsif (substr($file, -4) eq ".rpm") {
                 $allfiles[++$#allfiles] = $file;
             }
             $file = readdir $dirhandle;
        }
        closedir $dirhandle;
    }
    foreach $file (@allfiles) {
        $rpmlist[++$#rpmlist] = new RPM::Header $file;
    }
    return @rpmlist;
}

sub make_rpmlist_from_file {
    local($pfile) = @_;
    local(@rpmlist);
    @rpmlist = ();
    open PKGLIST, $pfile or die "Error opening file";
    while (<PKGLIST>) {
	chomp;
        $rpmlist[++$#rpmlist] = new RPM::Header $_;
    }
    close PKGLIST;
    return @rpmlist;
}

# Format: name <TAB> arch <TAB> EVR <TAB> fullname <TAB> source rpm <TAB> filename <CRLF>
$oldpipe=$|;
$|=1;
print STDOUT "Getting new rpm info";
if ($pkglist and -r $pkglist) {
    @patchrpms = &make_rpmlist_from_file($pkglist);
} else {
    @patchrpms = &make_rpmlist($patchdir);
}
print STDOUT "\nGetting original rpm info";
@oldrpms = &make_rpmlist($basedir);
print STDOUT "\n";
$|=$oldpipe;

foreach (@oldrpms) {
	$rpm = $_;
	print STDERR "WARNING: " .$rpm->{"name"}."(".&rpm_arch($rpm).") already found!\n"
		if (exists $baserpms{$rpm->{"name"},&rpm_arch($rpm)});
	$baserpms{$rpm->{"name"},&rpm_arch($rpm)} = $rpm;
}

foreach $rpm (@patchrpms) {
	$name = $rpm->{'name'};
	$arch = &rpm_arch($rpm);
	next if (!exists $validarch{$arch});
	if (exists $baserpms{$name,$arch}) {
                $rpmcmp = $rpm->cmpver($baserpms{$name,$arch});
                if ($rpmcmp == 1) {
			print "Updating $name($arch)\n";
			system("rm " . $baserpms{$name,$arch}->source_name());
			$newname = $basedir."/".&rpm_fullname($rpm);
			$sysres = system("cp -p " . $rpm->source_name() . " " .  $newname);
			if ($linkdir) {
				$linkname = $linkdir."/".&rpm_fullname($rpm);
				system("ln $newname $linkname");
			}
                        # Make new object to change the ->source_name()
			$baserpms{$name,$arch}= new RPM::Header $newname if ($sysres == 0);
		} elsif ($rpmcmp == -1) {
			print "Not updating $name($arch) - old package\n";
			$notupdated++ unless ($passcond eq "passlt");
		} elsif ($rpmcmp == 0) {
			print "Not updating $name($arch) - same version found\n";
			$notupdated++ unless ($passcond eq "passeq" or $passcond eq "passlt");
		} else {
			print "RPM version comparision failed -- unknown return: $rpmcmp";
			exit 255;
		}
	} else {
		print "Adding $name($arch)\n";
		$newname = $basedir."/".&rpm_fullname($rpm);
		$sysres = system("cp -p " . $rpm->source_name() . " " . $newname);
		if ($linkdir) {
			$linkname = $linkdir."/".&rpm_fullname($rpm);
			system("ln $newname $linkname");
		}
                # Make new object to change the ->source_name()
		$baserpms{$name,$arch} = new RPM::Header $newname if ($sysres == 0);
	}
}

exit $notupdated;

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux