Pacman and Optional Dependencies
Table of Contents
Archlinux packages list optional dependencies: "An array of packages that are not needed for the software to function, but provide additional features." But there's no special treatment built in for these packages, which can lead to problems (or at least needlessly left behind packages piling up).
Scenario 1 ∆
The end user has to install optional dependencies manually, and choose between marking them as explicit (--asexplicit
) or as a dependency (--asdeps
), there's no third way.
The default for manually installed packages is as explicit; the casual user might forget about this and lose the overview over various explicitely installed packages that are not needed anymore!
Scenario 2 ∆
You installed package Y, and package X got pulled in automatically as a (non-optional) dependency. Now you uninstall package Y, and get a list of orphans to uninstall. This can be automated thusly:
shalias orphrem='sudo pacman -R $(pacman -Qdtq)'
However, package X is not on that list because it's an optional dependency for some other installed package. But you do not desire this. One could change above alias:
shalias orphrem='sudo pacman -R $(pacman -Qdttq)'
The second 't' would also list optional dependencies as orphans - and the alias would uninstall them, all of them. That isn't desirable either.
And so unneeded installed packages tend to pile up.
What to do? ∆
Make it a habit to install optional dependencies as dependencies:
shoptinst() { echo "Install $@ as dependencies (w. pacman):" [[ "$@" == "" ]] && echo "Must provide at least one argument." && return 1 sudo pacman -S --asdeps "$@" }
Then I also wrote a function that helps me get an overview of which installed dependencies come up as true orphans, and which as optional, and a way to quickly change an optional dependency's status to explicitely installed, or remove it.
shred() { tput setaf 9; echo "$@"; tput sgr0; } orph() { local i j skip list local orphans=( $(pacman -Qdtq) ) red "True Orphans:" if [[ "${orphans[@]}" != "" ]]; then for i in "${orphans[@]}"; do echo $i; done return else echo None fi # now repeat for ALL orphans including optional dependencies local allorphans=( $(pacman -Qdttq) ) local optsonly=() # and filter out optional dependencies for i in "${allorphans[@]}"; do skip= for j in "${orphans[@]}"; do [[ $i == $j ]] && { skip=1; break; } done [[ -n $skip ]] || optsonly+=("$i") done # display result in a select list, with additional info & options when selected if [[ "${optsonly[@]}" != "" ]]; then red "Optional Dependencies:" select i in "${optsonly[@]}"; do [[ "$i" == "" ]] && return red -n $i expac -l ' ' ' (%d) is optional for:' $i list=( $(pacsift --local --exact --optdep $i) ) for j in ${list[@]}; do red -n " - ${j##*/}:" expac -l '\n' %O $j | grep "$i: "| cut -d: -f2 done read -p "Mark as explicitly installed (e) or remove (r) no action? " j case $j in e) sudo pacman -D --asexplicit $i ;; r) sudo pacman -R $i return ;; *) [[ "$j" != "" ]] && echo -n "Didn't understand. "; echo "Back to main list." ;; esac done fi }
You will require both expac
and pacutils
for this.
Now I can modify the orphrem
alias slightly:
shalias orphrem='sudo pacman -R $(pacman -Qdtq); orph'
Example ∆
I had previously installed germinal
which pulled in these dependencies:
extra/appstream-glib / -> 0.7.15-1
extra/gcab / -> 1.2-1
aur/germinal / -> 25-1
extra/intltool / -> 0.51.0-4
extra/libstemmer / -> 0+337-3
community/tmux / -> 2.9_a-4
extra/vte-common / -> 0.56.3-1
extra/vte3 / -> 0.56.3-1
I have now uninstalled it. This leaves me with some orphans:
$ orphrem
checking dependencies...
Package (2) Old Version Net Change
appstream-glib 0.7.15-1 -2.95 MiB
intltool 0.51.0-4 -0.15 MiB
Total Removed Size: 3.10 MiB
:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
(1/2) removing intltool [#################################] 100%
(2/2) removing appstream-glib [#################################] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
True Orphans:
gcab
libstemmer
$ orphrem
checking dependencies...
Package (2) Old Version Net Change
gcab 1.2-1 -0.36 MiB
libstemmer 0+337-3 -0.36 MiB
Total Removed Size: 0.72 MiB
:: Do you want to remove these packages? [Y/n]
:: Processing package changes...
(1/2) removing libstemmer [#################################] 100%
(2/2) removing gcab [#################################] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
True Orphans:
None
Optional Dependencies:
1) enca 9) libtiger 17) python-html5lib 25) rrdtool
2) ghostscript 10) libusb-compat 18) python-lxml 26) timidity++
3) gst-plugins-bad 11) libvncserver 19) python-pysocks 27) tmux
4) gtk2-perl 12) ocl-icd 20) python-setproctitle 28) unixodbc
5) java8-openjfx 13) perl-file-mimeinfo 21) python2-mutagen 29) vte3
6) lib32-openal 14) perl-net-dbus 22) qt5-multimedia
7) lib32-v4l-utils 15) perl-x11-protocol 23) qt5-script
8) libfbclient 16) python-dbus 24) qt5-xmlpatterns
Choice:
As you can see, the packages vte3
and tmux
, that were only just installed as dependencies for germinal
, do not show up as orphans. They show up in a long list of optional dependencies, and I have an option to uninstall them now.