Subject: Alternatives system, 2nd round
To: None <tech-pkg@NetBSD.org>
From: Julio M. Merino Vidal <jmmv84@gmail.com>
List: tech-pkg
Date: 01/21/2005 17:45:06
Hi again,

I've uploaded a preliminary version of the alternatives system here:

	ftp://ftp.NetBSD.org/pub/NetBSD/misc/jmmv/alternatives.diff
	ftp://ftp.NetBSD.org/pub/NetBSD/misc/jmmv/alternatives.tar.gz

Apply the patch and extract the tarball on the top directory of pkgsrc,
if you want to try it.  (The diff contains some minor changes in mk
and makes nvi, vim* and all the java packages use alternatives.)

Now some details: I've almost rewritten it from scratch using wrappers,
following tv@'s comments, and I like the new implementation a lot more
than what I had before.  Less error prone, more flexible and works
better in general.

Wrappers have the following advantages:

- They don't break in the case described by dillo@.  Suppose you have
  /usr/pkg shared and a local PKG_SYSCONFDIR (say /etc/pkg).  Now you
  have nvi set as the default on machine A, and vim on machine B.
  If you remove one of them from the system, one of the machines could
  end up containing broken links.

  With wrappers, this does not happen.  They maintain a list of
  candidates that can be executed, and if one is not available, they
  automatically fall back to the other one.

- It's also easier to solve the other problem described by dillo@.
  If you have nvi and vim installed, being the later the default,
  if you remove vim to update it, you'd end up with a different value
  for the alternative.  This does not happen now, assuming you have
  configured it manually (trivial).

- 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 then 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 symlinks, I tried setting gvim as an alternative for
  vi, but that was useless.  Now, it works fine.

- Alternatives can have command line arguments.  As tv@ showed as an
  example, you'd now add emacs in viper mode as an alternative for vi.

There are some restrictions in the code in case a user wants to do
complex things.  Anyway, lets keep it simple for now.  All extra fancy
stuff can be added at a later point, when it has proved to work fine.

Now I have some questions:

- I've placed the package under pkgtools, but I'm a bit doubtful.
  Maybe sysutils is a better place?

- Should alternatives.mk be moved inside the package's directory
  instead of living in mk/?

- I have to add a way so that bulk builds do not generate any of the
  wrappers.  Why?  Suppose you install a single python implementation
  and the 'python' wrapper is generated.  Then, while building other
  packages, it might happen that they find the wrapper instead of the
  real program (thus causing inconsistencies - expecting one version
  but finding a different one - during the build).

  Do you think this is correct?  If so, is it possible to define a
  global env var during bulk builds that is picked up by all commands?
  (Something like setting USE_ALTERNATIVES=NO).

- Does it seem better now? ;)

Cheers,

-- 
Julio M. Merino Vidal <jmmv84@gmail.com>
http://www.livejournal.com/users/jmmv/
The NetBSD Project - http://www.NetBSD.org/