02/02/2020: This week in KISS (#9)

Alternatives!

Index

Alternatives system

The package manager now includes an "alternatives system". This feature allows you to change the provider of a specific file or set of files.

For example, a user can now swap from busybox to the GNU coreutils by running a simple command.

This works in an entirely dynamic way and required zero changes to the package format or the repository files themselves! [1]

When a conflict is detected between another package during installation, the conflicting files become "choices" in the alternatives system.

Running kiss a or kiss alternatives will list all available choices that can be made.

-> kiss a
-> Alternatives:
ncurses /usr/bin/clear
ncurses /usr/bin/reset

The above command tells me that I have two available choices from the ncurses package. To find out which package owns the current "choice", the kiss-owns utility from kiss-utils can be used (a simple grep in your installed db also works).

-> kiss a ncurses /usr/bin/clear
-> Swapping '/usr/bin/clear' from 'busybox' to 'ncurses'

My system now uses /usr/bin/clear from the ncurses package. Running kiss a again will now show the following output.

-> kiss a
-> Alternatives:
busybox /usr/bin/clear
ncurses /usr/bin/reset

Here's a more complex example showing the swap between a large bulk of choices.

-> kiss a
-> Alternatives:
busybox /usr/bin/clear
coreutils /usr/bin/[
coreutils /usr/bin/base64
coreutils /usr/bin/basename
coreutils /usr/bin/cat
coreutils /usr/bin/chgrp
coreutils /usr/bin/chmod
# Lots of 'coreutils *' lines here.
coreutils /usr/bin/whoami
coreutils /usr/bin/yes
ncurses /usr/bin/reset

The output of kiss a can be directly used as input to kiss a. Each line is a valid set of arguments! Here's how you'd swap to GNU coreutils in a single command.

# The package manager will read each line from stdin.
kiss a | grep ^coreutils | kiss a -

# Running 'kiss a' will show the inverse of the above listing,
# a long output of 'busybox *'.

My system is now using the GNU coreutils!

This system works for any files across the entire filesystem and as it is entirely dynamic (requiring no changes to the repositories or the package format [1]) it is backwards compatible.

The feature allows the user to swap their /bin/sh, coreutils and really anything they desire. Very complex setups are now easily possible when this is paired with the repository system.

The package manager, init scripts and package files are written in POSIX shell allowing any POSIX compatible shell or coreutils to be used in place of the defaults (one exception is made for sed -i which is too useful to let go of [2]).

With this change, the user now has the choice between, init, device manager, coreutils, shell and anything they desire!

[1]: Some minor changes were made to where some packages install their files. coreutils was installed to /usr/local/bin due to the absence of this alternatives feature. This was still not a change to the format of the package system itself though!

[2]: Utilities like tar which have no standard command-line interface may be incompatible when swapped out. There's nothing that can really be done about this.

Official Repositories

Community