#!/usr/bin/perl use strict; use warnings; use RPM2; use Data::Dumper; sub compare($$); my $releases = 2; my $releasedir = '/releases'; my $smerel = '7'; my $centosrel = '4'; my $fedorarel = '3'; my $builds = '/builds/rpms'; my $stagedir = '/builds'; my $arch = `uname -i`; chomp $arch; my @repos = ( "$releasedir/$smerel/smeos/$arch/SME", "$releasedir/$smerel/smeos/$arch/SME/RPMS", "$releasedir/$smerel/smeos/$arch/CentOS/RPMS", "$releasedir/$smerel/smeupdates/$arch/RPMS", "$releasedir/$smerel/smeupdates-testing/$arch/RPMS", "$releasedir/$smerel/smeextras/$arch/RPMS", "$releasedir/$smerel/smeaddons/$arch/RPMS", "$releasedir/$smerel/smecontribs/$arch/RPMS", "$releasedir/$smerel/smetest/$arch/RPMS", "$releasedir/$smerel/smedev/$arch/RPMS", "$builds/RPMS/$arch", "$builds/RPMS/i586", "$builds/RPMS/i686", "$builds/RPMS/noarch", "$stagedir/RPMS-$arch", ); my @srcrepos = ( "/mirrors/centos/$centosrel/fasttrack/SRPMS", "/mirrors/centos/$centosrel/updates/SRPMS", "/mirrors/centos/$centosrel/os/SRPMS", "/mirrors/centos/$centosrel/extras/SRPMS", "/mirrors/rpmforge/dag/source", "/mirrors/atrpms/src/el$centosrel-$arch/atrpms/stable", "/mirrors/atrpms/src/el$centosrel-$arch/atrpms/testing", "/mirrors/fedora/epel/$centosrel/SRPMS", "/mirrors/fedora/core/updates/$fedorarel/SRPMS", "/mirrors/fedora/core/$fedorarel/source/SRPMS", "/mirrors/fedora/extras/$fedorarel/SRPMS", "$builds/SRPMS", ); my $rpm_flags = RPM2->vsf_nodsaheader | RPM2->vsf_nodsa; my @rpms; my %srpms; my %sources; my %changed; my %copy; print "\nReading repos...\n"; foreach my $repo ( @repos ) { my $r = $repo; if ( $repo =~ m{$stagedir/RPMS} ) { $r = $stagedir; } elsif ( $repo =~ m{$builds/RPMS} ) { $r = 'builds'; } elsif ( $repo =~ m{^($releasedir/$smerel/sme[^/]*)/} ) { $r = $1; } if ( $r eq $stagedir ) { opendir SRPMS, "$r/SRPMS-$arch" or next; foreach my $srpm ( grep { /\.rpm$/ } readdir SRPMS ) { $srpms{$r}{$srpm} = 0; $sources{$srpm} = "$r/SRPMS-$arch"; } closedir SRPMS; } elsif ( $r ne 'builds' ) { opendir SRPMS, "$r/SRPMS" or next; foreach my $srpm ( grep { /\.rpm$/ } readdir SRPMS ) { $srpms{$r}{$srpm} = 0; $sources{$srpm} = "$r/SRPMS"; } closedir SRPMS; } opendir RPMS, $repo or next; print " - $repo\n"; foreach my $pkg ( reverse sort map { RPM2->open_package("$repo/$_", $rpm_flags); } grep { /\.rpm$/ } readdir RPMS ) { my $rpm = { name => $pkg->tag("NAME"), filename => join("-", map { $pkg->tag($_) } qw/name version release/) . "." . $pkg->tag("ARCH"), version => $pkg->tag("VERSION"), release => $pkg->tag("RELEASE"), repo => $r, rpm => $pkg, }; my $source = $pkg->tag("SOURCERPM"); $source =~ s#-$rpm->{version}-$rpm->{release}.*##; $rpm->{source} = $source; if ( $rpm->{repo} =~ m{^$releasedir/$smerel/} && $rpm->{repo} !~ m{/smedev$} ) { $rpm->{repo} = 'deleted' if grep { $_->{repo} ne $rpm->{repo} && $_->{name} eq $rpm->{name} && $_->{rpm} ge $rpm->{rpm} } @rpms; $rpm->{repo} = 'deleted' if grep { $_->{repo} eq $rpm->{repo} && $_->{name} eq $rpm->{name} && $_->{rpm} gt $rpm->{rpm} } @rpms; $changed{$r}++ if $rpm->{repo} eq 'deleted'; } push @rpms, $rpm; } closedir RPMS; } print "\nReading source repos...\n"; foreach my $repo ( reverse @srcrepos ) { my %temp_repo = map { $_ => $repo } grep { /\.rpm$/ } readdir SRPMS if ( opendir SRPMS, $repo ); closedir SRPMS; %sources = (%sources, %temp_repo); } print "\nFinding latest packages...\n"; my @latest; foreach my $rpm ( reverse grep { $_->{repo} =~ m{^$releasedir/$smerel/} && $_->{repo} !~ m{/sme(addons|contribs|dev|extras)$} } @rpms ) { unless ( grep { $_->{name} eq $rpm->{name} && $_->{rpm} gt $rpm->{rpm} } @latest ) { push @latest, $rpm; unless ( grep { $_->{repo} eq $stagedir && $_->{filename} eq $rpm->{filename} } @rpms ) { push @{$copy{"$stagedir/RPMS-$arch"}}, $rpm->{rpm}->filename; push @rpms, { name => $rpm->{name}, filename => $rpm->{filename}, version => $rpm->{version}, release => $rpm->{release}, repo => $stagedir, rpm => $rpm->{rpm}, source => $rpm->{source} }; } } } foreach my $rpm ( grep { $_->{repo} eq $stagedir } @rpms ) { $rpm->{repo} = 'deleted' unless grep { $_->{filename} eq $rpm->{filename} } @latest; } foreach my $rpm ( reverse grep { $_->{repo} =~ m{^$releasedir/$smerel/} && $_->{repo} =~ m{/sme(addons|contribs|extras)$} } @rpms ) { unless ( grep { $_->{name} eq $rpm->{name} && $_->{rpm} gt $rpm->{rpm} } @latest ) { push @latest, $rpm; } } print "\nFinding development packages...\n"; my @devel; my %versions; foreach my $rpm ( grep { $_->{repo} eq 'builds' } @rpms ) { next if grep { $_->{name} eq $rpm->{name} && $_->{rpm} ge $rpm->{rpm} } @latest; $versions{$rpm->{name}}{$rpm->{version}}++ unless grep { $_->{name} eq $rpm->{name} && $_->{rpm} eq $rpm->{rpm} } @devel; next if $versions{$rpm->{name}}{$rpm->{version}} > $releases || scalar keys %{$versions{$rpm->{name}}} > $releases; print "Possible update " . $rpm->{rpm}->filename . "\n" if grep { $_->{name} eq $rpm->{name} } @latest; push @devel, $rpm; unless ( grep { $_->{repo} =~ m{/smedev$} && $_->{filename} eq $rpm->{filename} } @rpms ) { push @{$copy{"$releasedir/$smerel/smedev/$arch/RPMS"}}, $rpm->{rpm}->filename; $changed{"$releasedir/$smerel/smedev"}++; push @rpms, { name => $rpm->{name}, filename => $rpm->{filename}, version => $rpm->{version}, release => $rpm->{release}, repo => "$releasedir/$smerel/smedev", rpm => $rpm->{rpm}, source => $rpm->{source} }; } } foreach my $rpm ( grep { $_->{repo} =~ m{/smedev$} } @rpms ) { $rpm->{repo} = 'deleted' unless grep { $_->{filename} eq $rpm->{filename} } @devel; } print "\nFinding source packages...\n"; foreach my $rpm ( grep { $_->{repo} !~ m{^(builds|deleted)$} } @rpms ) { my $src; my $srpm = $rpm->{rpm}->tag("SOURCERPM"); my @sources = (); push @sources, ($src = $srpm); push @sources, $src if (($src = $srpm) =~ s/\.el\d\.rf\./\.rf\./); push @sources, $src if (($src = $srpm) =~ s/\.[0-3]\.el\d+\.rf\./\.rf\./); push @sources, $src if (($src = $srpm) =~ s/\.(el|fc)\d\.at//); push @sources, $src if (($src = $srpm) =~ s/\.at//); push @sources, $src if (($src = $srpm) =~ s/\.(el|fc)\d//); push @sources, $src if (($src = $srpm) =~ s/\.\d+\.(el|fc)\d//); my $found = 0; my $repo = $rpm->{repo}; foreach my $source ( @sources ) { if ( $sources{$source} ) { if ($repo eq $stagedir) { push @{$copy{"$repo/SRPMS-$arch"}}, "$sources{$source}/$source" unless -f "$repo/SRPMS-$arch/$source"; } else { unless ( -f "$repo/SRPMS/$source" ) { push @{$copy{"$repo/SRPMS"}}, "$sources{$source}/$source"; $changed{$repo}++; } } $srpms{$repo}{$source}++; $found++; last; } } print "Can't find source for ".$rpm->{rpm}->filename."\n" unless $found; } my @remove; foreach my $repo ( keys %srpms ) { foreach my $rpm ( keys %{$srpms{$repo}} ) { unless ( $srpms{$repo}{$rpm} ) { if ($repo eq $stagedir) { push @remove, "$repo/SRPMS-$arch/$rpm"; } else { push @remove, "$repo/SRPMS/$rpm"; $changed{$repo}++; } } } } print "\n"; foreach my $repo ( sort keys %copy ) { foreach my $rpm ( keys %{{ map { $_ => 1 } @{$copy{$repo}} }} ) { print "copying $rpm to $repo/\n"; mkdir "$repo" unless -d "$repo"; system(qw(cp --preserve=timestamps), $rpm, "$repo/"); } } print "\n"; foreach my $rpm ( keys %{{ map { $_ => 1 } (@remove, map { $_->{rpm}->filename } grep { $_->{repo} eq 'deleted' } @rpms) }} ) { print "removing $rpm\n"; unlink $rpm; } print "\n"; foreach my $repo ( sort keys %changed ) { my $dir=`readlink -f $repo/$arch`; chomp $dir; print "rebuilding $dir...\n"; system(qw(createrepo), "$dir"); system(qw(rm -rf), "$dir/.olddata") if -d "$dir/.olddata"; system(qw(repoview), "$dir"); system(qw(rm -rf), "$dir/.repodata") if "$dir/.repodata"; }