On Thu, 4 Nov 2004 15:45:39 +0000
Ciaran McCreesh <ciaranm@g.o> wrote:
> Say we have a group of packages. For the sake of argument, we'll
> call them 'vim', 'nvi', 'elvis' and 'vi'. Each of these packages
> provides a binary with the same name as the package. So far no
> problem...
>
> Now let's say that each of these packages were clones or
> derivatives of a traditional unix package, which provided
> binaries named 'vi', 'view' and 'ex'. A user installing any one
> of these packages would expect to be given convenience symlinks
> which would allow them to access the packages via the
> traditional names. Suddenly we have a problem -- what if a user
> has more than one of these packages installed?
I would do something like this:
1) Write an eclass that deals with that issue in a generic way.
Lets call it alternatives-symlink.eclass. What are the different
alternatives is declared by the ebuild using an env var, for
instance:
ALTERNATIVES="/usr/bin/vi:vim /usr/bin/view:vim /usr/bin/ex:vim"
(you can also use absolute path in second hand of each
declaration if needed.)
The eclass would provide 4 functions:
- declare_alternative(): it takes two arguments. Its purpose is
to maintain a file where are declared all available alternatives
on the system(for instance "/var/lib/portage/alternatives"). This
file is like this:
/usr/bin/vi nvi vi.system
/usr/bin/view nvi view.system
/usr/bin/ex nvi ex.system
When called with "/usr/bin/vi" and "vim" as arguments,
declare_alternative() will add "vim" to the first line. Also, if
/usr/bin/vi does not exists, it is created as a symlink on vim.
- pkg_postinst(): it's a loop on $ALTERNATIVES that makes all the
appropriate declare_alternative() calls. It also print an einfo:
einfo "To use ${PN} as default for all its alternatives, try:"
einfo " # alternatives-config -s ${ALTERNATIVES}"
- remove_alternative() is a function that remove an entry in the
alternatives base. If the removed alternative was still in use
(ie. linked), it fixes the link using an other entry and ewarns
the user.
- pkg_postrm() that iterates on ${ALTERNATIVES} to call
remove_alternative().
2) write a generic "alternatives-config" tool to allow users
choosing among all the available alternatives that are in
/var/lib/portage/alternatives. Some classical usages would be:
# alternatives-config --list
* Available alternatives:
/usr/bin/vi: vim nvi [vi.system]
/usr/bin/view: vim [nvi] view.system
/usr/bin/ex: [vim] nvi ex.system
(ie, list all available alternatives, with the current one in
brackets)
# alternatives-config --set /usr/bin/vi:vim /usr/bin/view:vim
* Symlinking /usr/bin/vi to vim
* Symlinking /usr/bin/view to vim
(ie., set some of the alternatives to your favorite choice)
> Oh, and to make it even more fun we'll say that certain
> non-Linux systems already provide a binary with the traditional
> name...
That's the "*.system" above. In declare_alternative(), if a target
/path/to/foo already exists, then it is moved to foo.system. Then,
/path/to/foo is linked to foo.system (to not change the default),
and `declare_alternative /path/to/foo foo.system` is called to add
it as a new entry in the/var/lib/portage/alternatives file.
Other random thoughts:
- that system can also be used for directories (useful for
some libs for instance), not only binary commands
- sometimes it would be useful to be able to declare that a set
of alternatives must be changed a coherent way (for instance, a
command and a lib dir that must be from the same package). I have
no idea how to add that feature (i think that's part of where a
dedicated "something-config" starts to be really required)
- I was suggesting a new eclass, but writing that as an extension
to the alternatives.eclass may be a better idea
Oh, and seeing more emails coming in that thread, I realize that
part of what I suggest is already suggested by others, so sorry
for any redundancy.
--
TGL.
--
gentoo-dev@g.o mailing list
|