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 –
pacman or whatever – to get data on a program instead of relying on a hard-coded list.
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.
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).
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]
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.
pacman 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 email@example.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
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
versionalready knows about the program. If so, just do what it already does.
- If now, check
dnf. 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
- 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.
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
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/