Today, as I was working
on importing and building geckodriver
I found myself head first down a rabbit hole
trying to figure out why the
mach try command
we use for testing changesets in continuous integration
complained that I didn’t have git-cinnabar installed:
% ./mach try -b do -p all -u all -t none mach try is under development, please file bugs blocking 1149670. ERROR git-cinnabar is required to push from git to try withthe autotry command. More information can by found at https://github.com/glandium/git-cinnabar
As I’ve explained previously, git-cinnabar is a git extension for interacting with remote Mercurial repositories. It’s a godsend written by fellow Mozillian Mike Hommey that lets me do my work without getting my hands dirty with hg.
As one might suspect,
mach try uses whereis(1)
to look for the
However, as it is a helper program
that is not meant to be invoked directly,
but rather be despatched through
git cinnabar (without hyphen),
it gets installed into
Since I had never heard about libexec before,
I decided to do some research.
libexec is meant
for system daemons and system utilities
executed by other programs.
That is, the binaries put in this namespaced directory
are meant for the consumption of other programs,
and are not intended to be executed directly by users.
In fact, libexec is defined in the Filesystem Hierarchy Standard published by the Linux Foundation in this way:
/usr/libexecincludes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under
On my preferred Linux system, Debian,
there is apparently also
which as far as I understand
is meant to complement
in the same way that
It provides a tertiary hierarchy for local data and programs
that may be shared amongst hosts
and that are safe from being overwritten
when the system is upgraded.
This is exactly what I want,
since I installed git-cinnabar from source.
It was somewhat surprising to me to find that whereis(1)—or at least the util-linux version of it—does not provide a flag for searching auxillary support programs located in libexec, when it is capable of searching for manuals and sources, in addition to executable binaries:
% whereis -h Usage: whereis [options] [-BMS <dir>... -f] <name> Locate the binary, source, and manual-page files for a command. Options: -b search only for binaries -B <dirs> define binaries lookup path -m search only for manuals and infos -M <dirs> define man and info lookup path -s search only for sources -S <dirs> define sources lookup path -f terminate <dirs> argument list -u search for unusual entries -l output effective lookup paths For more details see whereis(1).
To further complicate things,
git itself has no option for emitting where
it finds its internally-called programs from.
It does have an
that tells you where internal git commands are kept,
but not where optionally installed git extensions are.
I think the fix to my problem
is to tell
mach try to include
in the search path when it looks for git extensions,
but maybe there is a more elegant way
to check if git has a particular subcommand available?
Certainly it’s conceivable to just call
git cinnabar --help or similar
and check its exit code.