Date: Tue, 4 Apr 2006 16:36:11 -0700 (PDT) From: Luke Dean <LukeD@pobox.com> To: wc_fbsd@xxiii.com Cc: freebsd-questions@freebsd.org Subject: Re: Update from Ports removes dependency data Message-ID: <20060404150614.T41459@border.crystalsphere.multiverse> In-Reply-To: <6.2.5.6.2.20060403135639.033d6db0@xxiii.com> References: <6.2.5.6.2.20060403135639.033d6db0@xxiii.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 3 Apr 2006, wc_fbsd@xxiii.com wrote: > I recently noticed if I update a package from ports, the package manager > looses the dependency data for the package. eg: updating old version of > gettext > > # pkg_info -R gett* > Information for gettext-0.14.5_1: > Required by: > libgpg-error-1.1 > libgcrypt-1.2.2 > gnutls-1.2.9 > p5-gettext-1.03 > gmake-3.80_2 > > [[[ update from ports - make ; make deinstall ; make reinstall ]]] > > # pkg_info -R gett* > Information for gettext-0.14.5_2: > > Is my procedure incorrect, or is this normal behavior? > > -Thanks, Wayne This is normal. It's what makes upgrading those ports that are required by lots of other ports so difficult. Dependency information is version-specific. If you run "pkg_info -r libgpg-error-1.1" you'll find that it still depends on gettext-0.14.5_1 until you rebuild libgpg-error. Last weekend I wrote some scripts to help me deal with stale dependencies like this. My code is such an ugly perl hack that I'm ashamed to post it, and my algorithm isn't really airtight, but I'll give you the algorithm I'm using. The script just uses pkg_info, pkg_version, and grep. 1) I build a dependency hash by parsing the output of "pkg_info -ra". The keys to the hash are the names of the installed ports with the versions stripped off. The right-hand-side of the hash are the lists of dependencies with the version numbers stripped off. 2) I build what I call a "full" dependency hash from the dependency hash I built in step 1. I do this by recursively getting the dependencies for every dependency in the hash from step 1. The result is a hash just like the one from step one, only with the list of dependencies expanded to show all of the dependencies' dependencies, etc. all the way down the the ports that don't require anything. As I'm building this, I also count how many levels down I have to recurse to build each entry and remember this number for each port. I call this number the "degree" for the port. To avoid rebuilding the same ports over and over again, ports with high degrees should be built after ports with low degrees. 3) I get a list of everything I want to upgrade by parsing the output of "pkg_version -qL "="". That shows me which of my installed ports are not the same version as the port in the ports tree. Usually I'll want to upgrade those ports. 4) I add to that list all of the ports that have outdated dependencies. I get that list by parsing "pkg_info -ra" for each port and checking "pkg_info -e " for each dependency to see if it exists. If it doesn't exist, then I assume I need to upgrade the requiring port. Many times the only thing I gain by doing this is an update to the dependency information in the ports database, but sometimes (like with the recent libiconv upgrade) it's truly necessary. I don't know of any way to programmatically gauge the importance of an upgrade - all I can tell is whether the version of the port listed as a dependency still exists. 5) I take the list of ports that I built in step 3 and 4, look them up in the "degrees" hash I built at the end of step 2, sort the output by the degree I determined in step 2 and then print the list. Then I use that list to tell me which ports that I should consider rebuilding and in what order. I used this script to help me upgrade all the ports on a system that hadn't been upgraded in about six months. It worked pretty well. It's not always perfect, though. Dependencies can change dramatically between versions sometimes, and sometimes a port will depend on a port that doesn't exist in the database (like "linux_base") but this approach is far far better than me trying to do a big upgrade of several ports by hand when I can't immediately see the dependencies. It also gives me the freedom/power to choose to build the ports I want to build, and to build them with the options I want to use.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060404150614.T41459>