Declarative Package Management on Arch
Background
Something that bothers me with most operating systems, is that the longer you use them, the dirtier they get. You accumulate files, and install software/packages, and over time forget what you even installed and why. This can lead to instability, and just a bloated system. I had this problem on Arch Linux for a long time, then some years ago I discovered NixOS. NixOS was amazing to me because this problem didn’t exist anymore. All my config files and all my packages were defined in a single place. I’d make changes to the file, nixos-rebuild then my system would have those packages and configs in place. But NixOS came with it’s own headaches, mainly that it forced me to do things the NixOS way, and it also made it difficult to use some programs because it places the packages you install in read-only filesystems. Eventually I found myself installing Arch again, and just accepting that it got dirty. But with the news about the AUR having loads of malware, it’s more important than ever to keep good track of what you have installed and why. I wasn’t too worried though because I found something called metapac.
My metapac setup
The nice thing about Arch is that I have a Linux system that is very normal. Software made for Linux, pretty much always works on my system, which I can’t say for NixOS. But thanks to metapac, I also get to manage the list of installed packages on my system in a file. I edit the file, run a command, then my system has the packages listed in that file (and nothing that isn’t in that file). Here’s how my setup works:
I created the directory ~/.config/metapac/, inside which is a file called config.toml, and a directory called groups/. Inside groups/ is a file called packages.toml.
My config.toml contains:
# Backends to enable. These will be merged with any hostname-specific backends
# from the [hostname_enabled_backends] config table.
enabled_backends = ["arch"]
[arch]
# Since pacman, pamac, paru, pikaur and yay all operate on the same package database
# they are mutually exclusive and so you must pick which one you want
# metapac to use.
# Must be one of: ["pacman", "pamac", "paru", "pikaur", "yay"]
# Default: "pacman"
package_manager = "paru"
This is so metapac can get packages from the AUR, the default config.toml for metapac has more settings you might want to look at yourself.
My packages.toml is where I put my list of packages to install. It looks like this:
[arch]
packages = [
# base (packages that come with a normal arch install plus other important things for me)
"base",
"base-devel",
"bluez",
"bluez-utils",
"btrfs-progs",
"cups",
...
# kde
"ark",
"dolphin",
"kate",
"konsole",
"plasma-desktop",
"plasma-login-manager",
"plasma-meta", # bloat but good
"plasma-workspace",
...
# explicit (packages i want from the arch repos)
"anki",
"ardour",
"audacity",
"zsh",
...
# aur
"blender-bin",
"metapac",
"paru",
...
]
The important thing in this file is that you need to make sure it has all the packages you want on your system, or the next step will screw things up. To get the list of packages to define in this file, I ran the command pacman -Qeq. That lists your explicitly installed packages and you should put them all in that file.
The last thing I did is in my ~/.zshrc, I added two aliases:
To quickly edit my package list:
alias emetapac="nvim /home/norawibb/.config/metapac/groups/packages.toml"
To update my system and make all the packages match what is in packages.toml:
alias update="metapac clean && metapac update-all && metapac sync"
That update command will ask for confirmation on what packages it is planning to remove, if any, then updates the system and installs the new packages, if any.
That’s my rant. I haven’t bothered declaratively managing config files, and I don’t think I will any time soon as I’ve been quite happy with this so far.