portupgrade and you
portupgrade is a small collection of tools that goes hand in hand with cvsup. Portupgrade does what it says - upgrades your ports - but it actually means your installed ports, even packages that were installed as part of the base system. Portupgrade includes two important programs - portupgrade, and portversion. Between them and cvsup, you'll have the ability to keep all installed software on your system up to date, so long as it exists in the ports tree.
Installing the Portupgrade suite
Installation is very simple:
oyabun# cd /usr/ports/sysutils/portupgrade oyabun# make install clean
Checklist before you run portupgrade...
Reading /usr/ports/UPDATING first to know of important upgrades that portupgrade doesn't handle well and exactly what to do about it. A few of these fixes work much better if done _before_ you run portupgrade so it's important not to skip this step!
If you haven't done a portupgrade in a long while (i.e. a year) you're almost certain to run into situations where two or more actions have to be taken to get a port to work (doing perl5.6* -> perl5.8.1 -> 5.8.4 -> 5.8.5 being an example). You can't just assume you can do steps in any order you like; you might even have to fix some Makefiles... so read all of UPDATING before you do anything.
When done with that, you need to use pkgdb with the -F option to fix any stale dependency first.
Using portupgrade and portversion
Now that that's done, you need to update your ports database.
oyabun# portsdb -Uu
This will likely take a while.
Now you can use portversion to see a list of installed programs that are out of date like so:
oyabun# portversion | grep "<"
or an equivalent command using the -l switch for portversion:
oyabun# portversion -l '<'
and you'll receive output like below:
expat < ezm3 < fontconfig < freetype2 < imake < libnet-devel < libtool < oyabun#
This is a possible example of the output you'd recieve from portversion. Issuing a portversion command without the -l '<' (or the pipe to grep) would produce a list of ALL installed packages on your machine, with < for "out of date", = for "current", and > for "newer". You can also use -v to get a listing with full version numbers for the installed port and port available in the tree.
How can you get "newer" than what's in the ports tree? This happens if you haven't issued a portsdb -uU command to update your ports database. The database contains entries pointing to older versions, while the ports tree itself contains newer versions, leading to situations where portversion reports ">".
Now, to upgrade one of these packages, do this:
oyabun# portupgrade imake
Portupgrade will upgrade the port with the newer version available in the ports tree, and also take care of any dependencies the new version may have - if it needed ANOTHER installed port upgraded to a newer version, for example. If you want to be safe, add -b to the portupgrade command. This will create a binary package of the old application, that you can then use with pkg_add if you need to revert back to the old app.
That's it. You'll have to repeat these steps (portversion, then portupgrade on one of the results) a few times to complete update your software, but all in all it's fairly simple and straightforward.
Another alternative to running portupgrade manually on all of your packages would be to run the following command:
# portupgrade -arR
The -R will check the build dependencies and the -r will check the applications that depend upon the port being upgraded and the -a will upgrade all out of date ports.
Note: Don't use -a unless you have read /usr/ports/UPDATING, know exactly which ports will be updated, and know how to recover from a broken system. This is *NOT* recommended by any knowledgable FreeBSD user.
Note: you may sometimes be prompted to run pkgdb -F to fix inconsistencies with listed dependencies within programs when you issue portversion commands, after upgrading ports. Just do it (pkgdb -F, that is) and it will take care of the problem, allowing you to issue the portversion command.
Once done, go back to /usr/ports/UPDATING and do leftover steps to everything things to work.
On slow computers or for long-delayed updates, you might want to try ps | grep portupgrade on another screen to see how portupgrade is doing. It will get you something like this:
ruby18: portupgrade: [338/352] _name of current port_ (ruby18)
Where [338/352] means there are 352 packages being looked at and portupgrade is currently doing #338. While not every port needs an update, this command is the closest to a progress indicator you'll get for portupgrade.
The version number under _name of current port_ is the OLD version number.
Interrupting portupgrade may lead to various system catastrophes such as a broken package database and inability to reach the internet to get what you need to fix it. The portupgrade command should never be interrupted. See Errors To Avoid.