#!/usr/bin/perl -w # vim: nowrap ts=4 # apt-mkpkglist -- create consistent package list with resolved dependencies # Copyright 2001 Roland Bauerschmidt , GPL # with lots of help from Brenden O'Dea over mail and IRC... use strict; use AptPkg::Config '$_config'; use AptPkg::System '$_system'; use AptPkg::Cache; (my $self = $0) =~ s#.*/##; $_config->init(); $_system = $_config->system or die 'system'; $_config->{quiet} = 2; my @ARGV = $_config->parse_cmdline([ [ 'v', 'verbose', 'verbose' ], [ 'R', 'recommends', 'recommends' ], [ 'S', 'suggests', 'suggests' ], ], @ARGV); my $input = shift(@ARGV) or die "$self: no input file given\n"; my $output = shift(@ARGV) or die "$self: no output file given\n"; open(IN, "<$input"); open(OUT, ">$output"); my @packages; my @virtual; my $cache = AptPkg::Cache->new(0); foreach() { chomp(); $_ =~ s/ *\#.*//; next if($_ eq ""); push_package($_); } foreach(@packages) { print OUT $_."\n"; } sub push_package { my $pkg = shift; dprintf("processing package %s\n", $pkg); if(in_array($pkg, @packages)) { dprintf(" already satisfied\n"); return; } my @depends; # for real package we get all the dependencies for later recursion. if(defined($cache->{$pkg}{VersionList})) { # add all the packages this package depends on into an array, since # those dependencies will also have to be satisfied. This is # recursive. if($cache->{$pkg}{VersionList}[0]{DependsList}) { foreach(@{$cache->{$pkg}{VersionList}[0]{DependsList}}) { if($_->{DepType} eq "Depends" || $_->{DepType} eq "PreDepends" || $_->{DepType} eq "Recommends" && $_config->get_bool('recommends') || $_->{DepType} eq "Suggests" && $_config->get_bool('suggests')) { dprintf(" %s %s\n", lc($_->{DepType}), $_->{TargetPkg}->{Name}); push(@depends, $_->{TargetPkg}{Name}); } } } # push all the packages this package provides into an array, so we # don't need to add any other packages later if dependencies on # virtual packages are already satisfied through this package if($cache->{$pkg}{ProvidesList}) { foreach(@{$cache->{$pkg}{ProvidesList}}) { push(@virtual, $_->{Name}); } } push(@packages, $pkg); # for virtual packages check if dependency is already satisfied, # otherwise add a package to satisfy the dependency } elsif(!in_array($pkg, @virtual) && defined($cache->{$pkg}{ProvidesList})) { dprintf(" virtual package provided by %s\n", $cache->{$pkg}->{ProvidesList}[0]{OwnerPkg}{Name}); # since the code for selecting package with highest priority # is not there yet, just take the first one push(@depends, $cache->{$pkg}->{ProvidesList}[0]{OwnerPkg}{Name}); # choose package with highest priority should be done here later # it'd be nice if it could be done like this, but it can't # need to do this with VerFile #my $highest; #foreach(@{$cache->{$_}{ProvidesList}}) { #print "reverse provides: ".$_->{OwnerPkg}{Name}."\n"; #push(@depends, $_->{OwnerPkg}{Name}); #if($highest->{Priority} < $_->{OwnerPkg}{Priority}) { # $highest = $_->{OwnerPkg}; #} #} #push(@depends, $highest->{Name}); } foreach(@depends) { push_package($_) if(!in_array($_, @packages)); } } sub in_array { my $key = shift; foreach(@_) { return(1) if($key eq $_); } return(0); } sub dprintf { printf(@_) if $_config->get_bool("verbose"); }