#!/usr/bin/perl use strict; use warnings; use RPM2; use Data::Dumper; sub compare($$); my $releases = 2; my $releasedir = '/releases'; my $smerel = '7'; my $arch = 'i386'; my $centosrel = '4'; my $fedorarel = '3'; my $builds = '/builds/rpms'; my $stagedir = '/builds'; my @repos = ( "$releasedir/$smerel/smeos/$arch/CentOS/RPMS", "$releasedir/$smerel/smeos/$arch/SME/RPMS", "$releasedir/$smerel/smeos/$arch/RPMS", "$releasedir/$smerel/smeos/$arch/SME", "$releasedir/$smerel/smeupdates/$arch/RPMS", "$releasedir/$smerel/smeupdates-testing/$arch/RPMS", "$releasedir/$smerel/smeextras/$arch/RPMS", "$releasedir/$smerel/smeaddons/$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", ); 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/fedora/epel/$centosrel/SRPMS", "/mirrors/fedora/core/updates/$fedorarel/SRPMS", "/mirrors/fedora/core/$fedorarel/source/SRPMS", "/mirrors/fedora/extras/$fedorarel/SRPMS", "$builds/SRPMS", ); my %repohash; my %srcrepohash; my %changed; my %copy; my @remove; my $rpm_flags = RPM2->vsf_nodsaheader | RPM2->vsf_nodsa; %{$srcrepohash{$stagedir}} = map { $_ => 0 } grep { /\.rpm$/ } readdir SRPMS if ( opendir SRPMS, "$stagedir/SRPMS" ); closedir SRPMS; foreach my $repo ( @repos ) { if ( $repo =~ m{^($releasedir/$smerel/sme[^/]*)/} ) { my $srcrepo = $1; %{$srcrepohash{$srcrepo}} = map { $_ => 0 } grep { /\.rpm$/ } readdir SRPMS if ( opendir SRPMS, "$srcrepo/SRPMS" ); closedir SRPMS; } opendir RPMS, $repo; foreach my $rpm ( grep { m{\.rpm} } readdir RPMS ) { my $header = RPM2->open_package("$repo/$rpm", $rpm_flags); my $pkg = $header->tag("NAME").".".$header->tag("ARCH"); if ( $repo =~ m{$stagedir/RPMS} ) { push @{$repohash{$pkg}{$stagedir}}, $header; } elsif ( $repo =~ m{$builds/RPMS} ) { push @{$repohash{$pkg}{builds}}, $header; } elsif ( $repo =~ m{^($releasedir/$smerel/sme[^/]*)/} ) { my $pos = $1; push @{$repohash{$pkg}{$pos}}, $header; } } closedir RPMS; } my %sources; foreach my $repo ( reverse @srcrepos ) { my %temp_repo = map { $_ => $repo } grep { /\.rpm$/ } readdir SRPMS if ( opendir SRPMS, $repo ); closedir SRPMS; %sources = (%sources, %temp_repo); } foreach my $pkg ( keys %repohash ) { foreach my $repo ( @repos ) { if ( $repo =~ m{$stagedir/RPMS} ) { next unless $repohash{$pkg}; if ( $repohash{$pkg}{$stagedir} ) { my ($latest, @rest) = sort { $b cmp $a } @{$repohash{$pkg}{$stagedir}}; delete $repohash{$pkg}{$stagedir}; push @remove, map { $_->filename } @rest if @rest; if ( $repohash{$pkg}{latest} ) { if ($repohash{$pkg}{latest} ne $latest ) { push @remove, $latest->filename; push @{$copy{"$stagedir/RPMS"}}, $repohash{$pkg}{latest}->filename; $repohash{$pkg}{$stagedir} = $repohash{$pkg}{latest}; } else { $repohash{$pkg}{$stagedir} = $latest; } } else { push @remove, $latest->filename; } } elsif ( $repohash{$pkg}{latest} ) { push @{$copy{"$stagedir/RPMS"}}, $repohash{$pkg}{latest}->filename; $repohash{$pkg}{$stagedir} = $repohash{$pkg}{latest}; } } elsif ( $repo =~ m{^($releasedir/$smerel/sme[^/]*)/} ) { my $pos = $1; next unless $repohash{$pkg}{$pos}; if ( $pos =~ m{/smedev$} ) { next unless $repohash{$pkg}{latest}; my @rest = grep { $_ le $repohash{$pkg}{latest} } @{$repohash{$pkg}{$pos}}; if ( @rest ) { push @remove, map { $_->filename } @rest; $changed{$pos}++; @{$repohash{$pkg}{$pos}} = grep { $_ gt $repohash{$pkg}{latest} } @{$repohash{$pkg}{$pos}}; delete $repohash{$pkg}{$pos}; } } elsif ( ref($repohash{$pkg}{$pos}) eq 'ARRAY' ) { my ($latest, @rest) = sort { $b cmp $a } @{$repohash{$pkg}{$pos}}; delete $repohash{$pkg}{$pos}; if ( $repohash{$pkg}{latest} && $repohash{$pkg}{latest} ge $latest ) { push @rest, $latest; } else { $repohash{$pkg}{latest} = $latest; $repohash{$pkg}{$pos} = $latest; } if ( @rest ) { push @remove, map { $_->filename } @rest; $changed{$pos}++; } } } } } print "\n"; foreach my $pkg ( sort grep { $repohash{$_}{builds} } keys %repohash ) { my %versions = (); foreach my $ver ( sort { $b cmp $a } @{$repohash{$pkg}{builds}} ) { next if $repohash{$pkg}{latest} && $repohash{$pkg}{latest} ge $ver; $versions{$ver->tag("VERSION")}++; if ( $versions{$ver->tag("VERSION")} > $releases || (scalar keys %versions) > $releases ) { foreach my $rpm ( grep { $ver eq $_ } @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}} ) { push @remove, $rpm->filename; @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}} = grep { $rpm ne $_ } @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}}; $changed{"$releasedir/$smerel/smedev"}++; } } else { print "Possible update " . $ver->filename . "\n" if $repohash{$pkg}{latest}; if ( ! grep { $ver eq $_ } @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}} ) { push @{$copy{"$releasedir/$smerel/smedev/$arch/RPMS"}}, $ver->filename; push @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}}, $ver; $changed{"$releasedir/$smerel/smedev"}++; } } } } foreach my $pkg ( grep { $repohash{$_}{"$releasedir/$smerel/smedev"} } keys %repohash ) { foreach my $rpm ( @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}} ) { unless ( grep { $rpm eq $_ } @{$repohash{$pkg}{builds}} ) { push @remove, $rpm->filename; @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}} = grep { $rpm ne $_ } @{$repohash{$pkg}{"$releasedir/$smerel/smedev"}}; $changed{"$releasedir/$smerel/smedev"}++; } } } print "\n"; foreach my $repo ( sort keys %srcrepohash ) { foreach my $pkg ( sort grep { $repohash{$_}{$repo} } keys %repohash ) { my @rpms = ref($repohash{$pkg}{$repo}) eq "ARRAY" ? @{$repohash{$pkg}{$repo}} : ($repohash{$pkg}{$repo}); foreach my $rpm ( sort @rpms ) { my $src = $rpm->tag("SOURCERPM"); my @sources = (); push @sources, $src; push @sources, $src if ($src =~ s/\.\d+\.el\d+\.rf\./\.rf\./); push @sources, $src if ($src =~ s/\.el\d\.rf\./\.rf\./); push @sources, $src if ($src =~ s/\.el\d\.at\./\.at\./); push @sources, $src if ($src =~ s/\.fc\d\.at\./\.at\./); push @sources, $src if ($src =~ s/\.rf\./\.dag\./); my $found = 0; foreach my $source ( @sources ) { if ( $sources{$source} ) { unless ( -f "$repo/SRPMS/$source" ) { push @{$copy{"$repo/SRPMS"}}, "$sources{$source}/$source"; $changed{$repo}++; } $srcrepohash{$repo}{$source}++; $found++; last; } elsif ( -f "$repo/SRPMS/$source" ) { print "Found missing source $repo/SRPMS/$source for ".$rpm->as_nvre()."\n"; $srcrepohash{$repo}{$source}++; $found++; } } print "Can't find source for ".$rpm->as_nvre()."\n" unless $found; } } foreach my $rpm ( keys %{$srcrepohash{$repo}} ) { unless ( $srcrepohash{$repo}{$rpm} ) { push @remove, "$repo/SRPMS/$rpm"; $changed{$repo}++; } } } print "\n"; foreach my $repo ( sort keys %copy ) { foreach my $rpm ( sort keys %{{ map { $_ => 1 } @{$copy{$repo}} }} ) { print "copying $rpm to $repo/\n"; system(qw(cp --preserve=timestamps), $rpm, "$repo/"); } } print "\n"; foreach my $rpm ( sort keys %{{ map { $_ => 1 } @remove }} ) { print "removing $rpm\n"; unlink $rpm; } print "\n"; foreach my $repo ( sort keys %changed ) { next if $repo =~ m{^$stagedir}; my $dir=`readlink -f $repo/$arch`; chomp $dir; print "rebuilding $dir...\n"; system(qw(createrepo), "$dir"); system(qw(repoview), "$dir"); }