Todd Vierling made some interesting suggestions about the alternatives stuff. I didn't like them at first, but the more I thought about them, the more I realized they were the way to go :-P

So I've rewritten the alternatives framework almost from scratch, to make it use little wrappers instead of symbolic links (you can forget most things from the previous post, specially the example code). For those that don't know it, a wrapper is a little program that encapsulates another one; it does some preliminary tasks, but ends up running the program it's wrapping. Here are some of the advantages of using wrappers (really, some of them are only due to the new implementation):

  • They don't break if the original program disappears. How can this happen, if the alternatives are managed by packages?. Suppose you have /usr/pkg shared among several computers, but PKG_SYSCONFDIR is local to them (say /etc/pkg). Having this scenario, you have nvi set as the default for vi on machine A, while you have vim on machine B. If you remove one of them from one system, the other machine will end up with dangling symbolic links.

    Wrappers, however, check a list of alternatives when they are run and walk the entire list looking for a valid candidate. This means that the problem described above cannot happen (and if it does, you get a nice error message).

  • If you have multiple candidates available and you choose one manually to be the default, you want it to stay as the default even if you deinstall the package (think on updates, for example). This is now possible, and in fact very easy to achieve.

  • They let the user (not the administrator) configure which utility to use in each case. I.e., the wrapper will first look inside the ~/.alternatives directory for settings, then inside PKG_SYSCONFDIR, and at last inside the database stored in PREFIX/libdata/alternatives.

    The first two locations are optional and can be edited by hand at will (or even through the alternatives utility). The later one, though, is only managed by packages at (de)install time.

  • They don't "break" if the application changes its behavior depending on argv[0]. With symbolic links, you cannot use gvim as an alternative for vi (in fact, you can, but you won't get the graphical window).

  • Alternatives can have command line arguments. Todd showed an example: "emacs -l vip" as an alternative for vi.

There are some disadvantages too. The main one is that wrappers are restricted to programs. I.e., you cannot use them to provide alternatives for other stuff such as documentation, libraries, manual pages... But anyway, supporting these is not really a good idea if you think about it. However, one could argue about manual pages; I've mitigated this problem by generating one for each wrapper on the fly. They are simple, but I think can solve the inconvenient fairly well.

Check this message for some more information as well to links to the existing implementation.