On 04/11/07 at 23:44 +0100, Luk Claes wrote: > Lucas Nussbaum wrote: > > On 03/11/07 at 15:55 +0100, Luk Claes wrote: > >> Hi > >> > >> Attached my first version at a conversion to perl. Note that it is *NOT* > >> tested very well. Please don't hesitate to report any issue you find > >> with it (to this bug report?). > > > > Hi Luk, > > > > it seems that there's a problem with the scope of $datadir (and maybe > > also of $dist) in subs. I can't get chdist apt-get sid update to work, > > for example. > > No, other causes, though tnx for a sample command to test things a bit > more :-) > > Attached an updated version with quite some mistakes fixed. Now that I > have a clearer idea about what it's supposed to do I could fix some > trivial and not so trivial mistakes. There will probably more bugs, so > please test it some more before I add it to the repository...
Ok, looks better! Attached is an updated version with some fixes (`` -> system mostly). There's still a problem I don't understand in compare_packages: chdist compare-packages sid hardy should display a list of packages, but this part seems to be broken: sub dist_compare(\@;$) { my (@argv, $do_compare) = @_; $do_compare = 0 if $do_compare eq 'false'; my @dists; my $n = 0; # read params foreach my $a (@argv) { # lucas 05/11 print $a; $dists[$n] = $a; dist_check($dists[$n]); $n += 1; } - Lucas
#!/usr/bin/perl # Debian GNU/Linux chdist. Copyright (C) 2007 Lucas Nussbaum and Luk Claes. # # 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 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use Getopt::Long; my $datadir = $ENV{'HOME'} . '/.chdist'; sub usage { return <<EOF; Usage: chdist [options] [command] [command parameters] Options: -h, --help Show this help -d, --data-dir DIR Choose data directory (default: \$HOME/.chdist/ Commands: create DIST : prepare a new tree named DIST apt-get DIST (update|source|...) : run apt-get inside DIST apt-cache DIST (show|showsrc|...) : run apt-cache inside DIST apt-rdepends DIST [...] : run apt-rdepends inside DIST src2bin DIST PKG : get binary packages for a source package in DIST bin2src DIST PKG : get source package for a binary package in DIST compare-packages DIST1 DIST2 [DIST3, ...] : list versions of packages in several DISTributions compare-versions DIST1 DIST2 : same as compare-packages, but also run dpkg --compare-versions and display where the package is newer grep-dctrl-packages DIST [...] : run grep-dctrl on *_Packages inside DIST grep-dctrl-sources DIST [...] : run grep-dctrl on *_Sources inside DIST EOF } # specify the options we accept and initialize # the option parser my $help = ''; GetOptions( "help" => \$help, "data-dir=s" => \$datadir, ); if ($help) { print usage(0); exit; } ######################################################## sub dist_check { my $dist = $_; my $dir = $datadir . '/' . $dist; return 0 if (-d $dir); print "Could not find $dist in $datadir. Exiting.\n"; exit(1); } sub aptopts { my $dist = @_[0]; return "-o Dir=$datadir/$dist -o Dir::State::status=$datadir/$dist/var/lib/dpkg/status"; } sub compare_versions { my $va = $_[0]; my $vb = $_[1]; return `dpkg --compare-versions $va lt $vb; echo $?`; } ### sub aptcache { my @args = @_; my $dist = shift @args; dist_check($dist); my $args = aptopts($dist) . " @args"; system("/usr/bin/apt-cache $args"); } sub aptget { my @args = @_; my $dist = shift @args; dist_check($dist); my $args = aptopts($dist) . " @args"; system("/usr/bin/apt-get $args"); } sub aptrdepends { my @args = @_; my $dist = shift @args; dist_check($dist); my $args = aptopts($dist) . " @args"; system("/usr/bin/apt-rdepends $args"); } sub bin2src { my @args = @_; my $dist = $args[0]; dist_check($dist); my $args = aptopts($dist) . " show $args[1]"; my $source = `/usr/bin/apt-cache $args|grep '^Source:'`; exit($?) if($? != 0); $source =~ s/Source: (.*)/$1/; print $args[1] if($source eq ''); print $source if($source ne ''); } sub src2bin { my @argv = @_; my $dist = $argv[0]; dist_check($dist); my $args = aptopts($dist) . " showsrc $argv[1]"; my $bins = `/usr/bin/apt-cache $args|sed 's/\(Package: .*\)\n/\(Binary: .*\)/\1\t\2/'|grep "Package: $argv[1]"|sed 's/.*Binary: \(.*\)\n/\1/'`; exit($?) if ($? != 0); my @bins = split /, /, $bins; print join "\n", @bins; } sub dist_create { my @argv = @_; my $dist = $argv[0]; my $dir = $datadir . '/' . $dist; if (-d $dir) { print "$dir already exists, exiting.\n"; exit(1); } if (! -d $datadir) { mkdir($datadir); } mkdir($dir); foreach $d (('/etc/apt', '/var/lib/apt/lists/partial', '/var/lib/dpkg', '/var/cache/apt/archives/partial')) { my @temp = split /\//, $d; my $tres = $dir; foreach my $piece (@temp) { $tres .= "/$piece"; mkdir($tres); } } open(FH, ">$dir/etc/apt/sources.list"); print FH <<EOF; #deb http://ftp.debian.org/debian/ unstable main contrib non-free #deb-src http://ftp.debian.org/debian/ unstable main contrib non-free #deb http://archive.ubuntu.com/ubuntu dapper main restricted #deb http://archive.ubuntu.com/ubuntu dapper universe multiverse #deb-src http://archive.ubuntu.com/ubuntu dapper main restricted #deb-src http://archive.ubuntu.com/ubuntu dapper universe multiverse EOF close FH; open(FH, ">$dir/var/lib/dpkg/status"); close FH; #empty file print "Now edit $dir/etc/apt/sources.list\n"; print "Then run chdist apt-get $dist update\n"; print "And enjoy.\n"; } sub dist_compare(\@;$) { my (@argv, $do_compare) = @_; $do_compare = 0 if $do_compare eq 'false'; my @dists; my $n = 0; # read params foreach my $a (@argv) { # lucas 05/11 print $a; $dists[$n] = $a; dist_check($dists[$n]); $n += 1; } if ($do_compare && $n != 2) { print "Can only compare if there are two distros.\n"; exit(1); } # read Sources my %packages; foreach my $dist (@dists) { foreach $f (glob($datadir . '/' . $dist . "/var/lib/apt/lists/*_Sources")) { my $pkg; foreach my $l (<$f>) { if ($l =~ /^Package: /) { (my $ign, $pkg) = split /: /, $l; } elsif ($l =~ /^Version: /) { (my $ign, $packages{$dist}{$pkg}) = split /: /, $l; } } } } # output packages list #dists.inject([]) { |tot, d| tot += packages[d].keys }.sort.uniq.each do |pkg| my @tot = (); my %hash = $packages{$dist}; foreach $dist (@dists) { push @tot, keys %hash; } # @out contains the uniq elements of @tot my %saw; @[EMAIL PROTECTED] = (); my @out = keys %saw; foreach my $pkg (@out) { my $str = "$pkg"; foreach $dist (@dists) { if ($packages{$dist}{$pkg}) { $str .= " $packages{$dist}{$pkg}"; } else { $str .= " UNAVAIL"; } } if ($do_compare) { # compare versions if run as compare-versions if (! $packages{$dists[0]}{$pkg}) { $dist = $dists[0]; $str .= " not_in_$dist"; } elsif (! $packages{$dists[1]}{$pkg}) { $dist = $dists[1]; $str .= " not_in_$dist"; } elsif ($packages{$dists[0]}{$pkg} eq $packages{$dists[1]}{$pkg}) { $str .= " same_version"; } elsif (compare_versions($packages{$dists[0]}{$pkg}, $packages{$dists[1]}{$pkg})) { $dist = $dists[0]; $str .= " newer_in_$dist"; } else { $dist = $dists[1]; $str .= " newer_in_$dist"; } } print "$str\n"; } } sub grep_file { my (@argv, $file) = @_; $dist = shift @argv; dist_check($dist); $f = glob($datadir . '/' . $dist . "/var/lib/apt/lists/*_$file"); # FIXME avoid shell invoc, potential quoting problems here system("cat $f | grep-dctrl @argv"); } ######################################################## # Command parsing my $command = shift @ARGV; if ($command eq 'create') { dist_create(@ARGV); } elsif ($command eq 'apt-get') { aptget(@ARGV); } elsif ($command eq 'apt-cache') { aptcache(@ARGV); } elsif ($command eq 'apt-rdepends') { aptrdepends(@ARGV); } elsif ($command eq 'bin2src') { bin2src(@ARGV); } elsif ($command eq 'src2bin') { src2bin(@ARGV); } elsif ($command eq 'compare-packages') { dist_compare(@ARGV); } elsif ($command eq 'compare-versions') { dist_compare(@ARGV, 1); } elsif ($command eq 'grep-dctrl-packages') { grep_file(@ARGV, 'Packages'); } elsif ($command eq 'grep-dctrl-sources') { grep_file(@ARGV, 'Sources'); } else { print "Command unknown. Try $0 -h\n"; exit(1); }