Me again, talking about this silly version
program still.
Actually, there are some pretty cool updates over the past few point releases. They came fast and on the heels of each other. The idea was posed to use the Linux package manager – apt
or pacman
or whatever – to get data on a program instead of relying on a hard-coded list.
Background
After some back and forth I warmed up to the idea, but as a backup to the known program list, not as a replacement. My reasoning is that you might have multiple versions of foo
installed. Maybe one was through the default package manager, one through some download-and-run-an-install-script method. They might get installed to different locations in your PATH
. But when you call foo
on the command line, you’ll only get one of them.
If you query the package manager, it’s going to tell you about the one that it knows, which may or may not be the default. But when you run foo -v
on the command line, you will get the one that’s going to be actually run in most cases. So that should be the first place we look. If version
doesn’t know about foo
then it can turn to the package manager.
Details
I decided to tackle two of the major Linux package managers first – apt
(used on Ubuntu and most other Debian derivatives) and pacman
(used on Manjaro and other Arch derivatives).
On apt
, you can find info about a package, say neovim
, you’d type:
apt list neovim --installed
This will give you something like:
neovim/focal,now 0.4.3-3 amd64 [installed]
That 0.4.3-3
is the version number that we’re looking for. It took a bit of regex trickery, but I was able to parse that bit out of it.
On pacm
an you’d type pacman -Qi neovim
and the result would look something like:
Name : neovim Version : 0.4.4-1 Description : Fork of Vim aiming to improve user experience, plugins, and GUIs Architecture : x86_64 URL : https://neovim.io Licenses : custom:neovim Groups : None Provides : vim-plugin-runtime Depends On : libtermkey libuv msgpack-c unibilium libvterm luajit libluv Optional Deps : python-neovim: for Python 3 plugin support (see :help python) xclip: for clipboard support on X11 (or xsel) (see :help clipboard) [installed] xsel: for clipboard support on X11 (or xclip) (see :help clipboard) [installed] wl-clipboard: for clipboard support on wayland (see :help clipboard) Required By : None Optional For : None Conflicts With : None Replaces : None Installed Size : 20.45 MiB Packager : Sven-Hendrik Haase svenstaro@gmail.com Build Date : Wed 05 Aug 2020 04:16:43 AM EDT Install Date : Fri 21 Aug 2020 07:37:52 AM EDT Install Reason : Explicitly installed Install Script : No Validated By : Signature
So we can use grep
and/or sed
to find the one line of that which starts with Version:
and grab the 0.4.4-1
part of it.
I then did basically the same thing for dnf
which is the package manager on Redhat, Fedora, and derivatives.
So the process is:
- Check to see if
version
already knows about the program. If so, just do what it already does. - If now, check
apt
,pacman
anddnf
. First we can just check to see if each one of those exist and only run the one that does exist. It’s unlikely that many people will have more than one of those. If we find one of those, we do the parsing and spit out the version it tells us about. - If those all fail, then we can just tell the user we couldn’t find any information on that command.
Can we do more?
There are all kinds of other package managers on both Linux and Mac. I started making a list of the different ways you can find and install software and came up with
- snaps
- flatpaks
- pip
- npm
- homebrew / linuxbrew
There are others, but those all cover a huge amount of ground. And it turns out that most of them were able to be solved with the same general strategy:
- Does this package manager exist?
- Does it know about this program and what info does it have?
- Parse out the version number from the info it returns.
So, now version
supports all of those. It just looks at each one of them in turn until it finds one that give an answer.
This also has the added functionality of being able to return the version of more than just executable programs. Package managers know about various libraries and other assets that aren’t directly executable or don’t have any way of querying them directly for their version. But version
can tell you about them. Want to know what version of libusb
you have installed? Typing version libusb
will tell you.
A personal perk of doing this project is that I was forced to really learn grep
and sed
. Two programs that ranged from confusing to very mysterious in my mind. Now I get them and really like them. I wrote something up about them too: https://www.bit-101.com/blog/2020/09/grep-and-sed-demystified/