#!/usr/bin/perl -w # # cachecompare : Compare two repositories using Cache::Apt # Compare: # 1. emdebian/debian (toolchains) vs ftp.uk.debian.org for i386, amd64 & powerpc # 2. emdebian/emdebian (target) vs ftp.uk.debian.org for arm with renaming support. # # { use ftk.uk.debian.org or ftp.de.debian.org due to location of buildd.emdebian.org } # One of the remaining issues with this approach is the apparent lack of support # for creating a sources.list in memory without needing lots of little files. # Copyright (C) 2007 Neil Williams # # This package 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 3 of the License, 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, see . # use Cache::Apt::Lookup; use Cache::Apt::Config; use Cache::Apt::Package; use Data::Dumper; use Cwd; use Term::ANSIColor qw(:constants); use Text::Wrap; use vars qw/ @newer @older @equal @pending $target $toolchain %sources @toolchains @cross_targets %chain @cross_triplet /; # if using emdebian target repository, set $arch = arm # if using debian toolchain repository, set $arch = qw/i386 powerpc amd64/ in turn @toolchains = qw/i386 amd64 powerpc/; @cross_targets = qw/alpha arm armel hppa m68k mips mipsel ia64 powerpc sparc s390 /; $target = 1; $toolchain = 0; foreach my $q (@cross_targets) { $cross_triplet{$q} = &check_cache_arch($q); } my $verbose = 1; my $arch = "arm" if ($target == 1); # only arm packages are built so far. $arch = "i386" if ($toolchain == 1); # need support for tweaking this. my $suite = "unstable"; &set_verbose ($verbose); &set_suite($suite); &check_cache_arch($arch) if (defined ($arch)); my $cache = cwd . "/cache"; mkdir ($cache) or die ("Unable to create the cache directory: $!") if (not -d $cache); # check for (and create) sources.list file. # will need more than one file later. my $force = 0; if (not -f "$cache/sources.$suite") { $force = 1; } open (SOURCE, ">$cache/sources.$suite") or die ("Cannot create sources list: $!"); if ($target == 1) { print SOURCE "deb http://www.emdebian.org/emdebian/ unstable main\n"; print SOURCE "deb-src http://www.emdebian.org/emdebian/ unstable main\n"; } else { print SOURCE "deb http://www.emdebian.org/debian/ unstable main\n"; print SOURCE "deb-src http://www.emdebian.org/debian/ unstable main\n"; } close (SOURCE); open (STATUS, ">$cache/status"); close STATUS; &set_cachedir($cache); &use_mysources("sources.$suite"); &setup_config; &force_update if ($force > 0); &update_sources; my $config = &init_cache($verbose); my $iter = &get_cache_iter(); my $pkg; my @package_names = (); my %h = (); do { $pkg = $iter->next; $h{$pkg}++ if ($pkg); } while ($pkg); @package_names = sort (keys %h); # array of AptCrossPackage structs, ordered by package name my @packages = (); foreach my $p (@package_names) { my $emp = AptCrossPackage->new(); $emp->Package($p); $emp = &lookup_pkg($emp); push @packages, $emp; } if ($toolchain == 1) # working on emdebian/debian { foreach my $package (@packages) { my $vers = $$package->Version; next if (not defined $vers); my $name = $$package->Package; foreach my $run (@cross_targets) { $name =~ s/\Q-$run-cross\E$// if ($name =~ /\Q-$run-cross\E$/); } foreach my $triplet (values %cross_triplet) { $name =~ s/\Q-$triplet\E// if ($name =~ /\Q-$triplet\E/); # there are some special cases but those will have to be ignored. } $chain{$name}++; } print "found " . scalar (keys %chain) . " toolchain packages with a version string.\n"; } if ($target == 1) # working on emdebian/emdebian { foreach my $package (@packages) { my $src = $$package->Source; my $vers = $$package->Version; next if (not defined $vers); $vers =~ s/em[0-9]+$//; $sources{$src} = $vers; } print "found " . scalar (keys %sources) . " source packages with a version string.\n"; } # run through %sources and compare with host_cache. # lookup $emp->Source in host_cache and compare $emp->Version # after removing the em[0-9] suffix. # we don't need the other cache again. Start the host_cache. $arch = 'amd64'; &check_cache_arch ($arch); # probably better to use a separate source file here! :-) unlink ("$cache/sources.$suite"); &use_hostsources; &setup_config; &update_sources; $config = &init_host_cache($verbose); @older = (); @newer = (); @equal = (); @pending = (); my @list = (); @list = sort (keys %sources) if ($target == 1); @list = sort (keys %chain) if ($toolchain == 1); foreach my $check (@list) { my $host; my $name; if ($target == 1) { $host = &srclookup($check); $name = $sources{$check}; } if ($toolchain == 1) { $host = &srclookup($check); next if (not defined($host)); $name = $chain{$check}; } my $cmp = &Cache::Apt::Lookup::ver_compare ($name, $host->{'Version'}); push (@newer, $check) if ($cmp > 0); push (@equal, $check) if ($cmp == 0); if ($cmp < 0) { push (@older, $check); my $svn = &check_svn($check); $cmp = &Cache::Apt::Lookup::ver_compare ($svn, $host->{'Version'}) if (defined ($svn)); push (@pending, $check) if ($cmp == 0); } } unlink ("$cache/sources.$suite"); print "\n"; print BLUE, "The following packages are older in Emdebian than in Debian:\n", RESET; print RED, wrap('', '', @older), RESET if (scalar @older > 0); print "\n"; print BLUE, "The following packages are newer in Emdebian than in Debian:\n", RESET; print wrap('', '', @newer) if ((scalar @newer) > 0); print "\n"; print BLUE, "The following packages are the same version in Emdebian as in Debian:\n", RESET; print GREEN, wrap('', '', @equal), RESET if ((scalar @equal) > 0); print "\n"; print "The following packages are pending upload from SVN:\n"; print wrap('','', @pending) if (scalar @pending > 0); print "\n"; exit; sub check_svn($) { $pkg = shift; my @contents = (); my ($indexchar)=split(//, $pkg); my $path = "/opt/emdebian/trunk/${indexchar}/$pkg/trunk"; if (-d $path) { opendir (DH, "$path") or die ("Cannot read subdirectory $path: $!\n"); @contents = grep(!/^\.\.?$|^\.svn$/, readdir DH); closedir (DH); } foreach my $file (@contents) { if ($file =~ /^emdebian-changelog.patch$/) { open (CHG, "$path/$file") or warn ("no file to open: $!"); my @clog=; close(CHG); foreach my $line (@clog) { if ($line =~ /\Q+$pkg (\E(.*)\) unstable/) { my $emv = $1; $emv =~ s/em[0-9]+$//; return $emv; } } } } }