Something I have been toying with for a while now is fink being able to use apt-get-able packages. Sometimes when building something large, many of the dependency packages are already in a bindist somewhere, and I'd rather not build each and every one, just the packages newer than what is in the bindist. So, I thought about using apt-get to get the ones that I could.
My requirements were: 1) Don't break what currently works. If a package can't be fetched from apt-get, then fall back to building from scratch. Also as a result of this requirement, fink's dependency engine must be used instead of apt-get's. Fink also must perform all package installations instead of apt-get. 2) Don't download things that won't be used to satisfy the request. apt-get has its own dependency engine and it might not necissarily agree with what fink wants to install. We don't want apt-get going off and downloading everything, and then fink not using it later on. As a result of these, this patch may end up not downloading things that it might otherwise be able to. Part of the problem here is apt-get does not allow downloading arbitrary files. It wants all dependencies installed to satisfy the requirements of the file it is downloading, even if its not actually going to install the file. I've come up with a patch that does this. I've been testing the patch locally, but have not tested it extensively. I'll test it with larger dependency chains later, when I get access to better connectivity. Known issues: it is not controllable by a switch (command line or otherwise). The plan is to not have this on by default, but use a switch of some sort to enable it. I'm open to suggestions on how best to toggle this. Also, it does not run apt-get update from fink index, so you'll need to do that seperately. It should update apt-get's notion of reality. Rob
diff -udr Fink.orig/Engine.pm Fink/Engine.pm --- Fink.orig/Engine.pm Mon Sep 6 11:34:09 2004 +++ Fink/Engine.pm Mon Sep 6 11:41:26 2004 @@ -1382,6 +1382,20 @@ foreach $pkgname (sort keys %deps) { $item = $deps{$pkgname}; next if $item->[OP] == $OP_INSTALL and $item->[PKGVER]->is_installed(); + if (!$item->[PKGVER]->is_present() && $item->[OP] != $OP_REBUILD) { + my ($aptcmd, $pkgg, $package); + $package = $item->[PKGVER]; + if (exists $package->{_relatives}) { + foreach $pkgg (@{$package->{_relatives}}){ + if (!$pkgg->is_present() && $pkgg->is_aptgetable()) { + $pkgg->apt_fetch(); + &real_install($OP_INSTALL, 0, 1, $pkgg->get_name()); + } + } + } + $item->[PKGVER]->apt_fetch(); + } + if ($item->[OP] == $OP_REBUILD or not $item->[PKGVER]->is_present()) { $item->[PKGVER]->phase_fetch(1, 0); } diff -udr Fink.orig/Package.pm Fink/Package.pm --- Fink.orig/Package.pm Mon Sep 6 11:34:09 2004 +++ Fink/Package.pm Mon Sep 6 16:15:08 2004 @@ -44,6 +44,7 @@ our $essential_valid = 0; our $db_outdated = 1; our $db_mtime = 0; +our $aptdb = {}; END { } # module clean-up code here (global destructor) @@ -221,6 +222,19 @@ return 0; } +### Find a specific package name/version in aptdb + +sub is_in_apt{ + my $self = shift; + my $name = shift; + my $version = shift; + + if (defined $aptdb->{$name}{$version}) { + return 1; + } + return 0; +} + ### get version object by exact name sub get_version { @@ -340,6 +354,7 @@ if (not $db_outdated) { $packages = Storable::retrieve("$basepath/var/db/fink.db"); } + $aptdb = Storable::retrieve("$basepath/var/db/finkapt.db"); } } @@ -407,6 +422,33 @@ ? 1 : 0; } +### update the apt-get db file + +sub update_aptdb { + shift; + + my ($pkg, $ver); + open(APTDUMP, "apt-cache dump |") || die "Can't run apt-cache dump: $!\n"; + $aptdb = {}; + while(<APTDUMP>) { + if (grep(/Package:/,$_)) { + chomp; + $pkg = $_; + $pkg =~ s/.*Package:[\ ]*//; + } + if (grep(/Version:/,$_)) { + my $count; + chomp; + $ver = $_; + $ver =~ s/.*Version:[\ ]*//; + $aptdb->{$pkg}{$ver}++; + } + } + close APTDUMP; + + Storable::lock_store($aptdb, "$basepath/var/db/finkapt.db"); +} + ### read the packages and update the database, if needed and we are root sub update_db { @@ -440,6 +482,7 @@ } }; $db_outdated = 0; + Fink::Package->update_aptdb(); } ### scan one tree for package desccriptions diff -udr Fink.orig/PkgVersion.pm Fink/PkgVersion.pm --- Fink.orig/PkgVersion.pm Mon Sep 6 11:34:09 2004 +++ Fink/PkgVersion.pm Mon Sep 6 16:17:15 2004 @@ -1037,6 +1037,26 @@ return 1; } +sub is_aptgetable { + my $self = shift; + if (defined Fink::Package->is_in_apt($self->get_name(), $self->get_fullversion())) { + return 1; + } + return 0; +} + +sub apt_fetch { + my $self = shift; + my $aptcmd = "apt-get -d --trivial-only -q install " . $self->get_name() . "=" . $self->get_fullversion() . " > /dev/null 2>&1"; + print STDERR "Retrieving " . $self->get_debname() . " via apt-get\n"; + if (!&execute($aptcmd)) { + my $tmpdeb = "$basepath/fink/debs/" . $self->get_debname(); + symlink "$basepath/var/cache/apt/archives/" . $self->get_debfile(), $tmpdeb; + return 1; + } + return 0; +} + sub is_present { my $self = shift; @@ -1098,6 +1118,11 @@ return $fn; } } + $fn = "$basepath/var/cache/apt/archives/$self->{_debname}"; + if (-f $fn) { + return $fn; + } + return undef; }