Please describe the problem.
Installing git-annex via the Makefile results in a zsh completion installed to $(PREFIX)/$(SHAREDIR)/zsh/vendor-completions
This is not used by zsh, since the builtin zsh fpath is $(PREFIX)/$(SHAREDIR)/zsh/site-functions
-- as a result, zsh completions do not work.
Some system distributions of zsh may change the builtin fpath, in which case git-annex may have working zsh completions out of the box -- I believe the current installation method is designed based on Debian's preferred layout.
What steps will reproduce the problem?
Install git-annex on a non-Debian system
What version of git-annex are you using? On what operating system?
version 7.20190730 on an Arch Linux system.
Recommended fix
Make the installation directory configurable. Use /etc/os-release to check if the system is a Debian-based system, and if so, continue to use vendor-completions, if not, use site-functions.
Debian also supports /usr/local/share/zsh/site-functions/, it's just that it's for local sysadmin use and not a place that packages should install files, so they added /usr/share/zsh/vendor-completions/ for that.
However, checking
/etc/os_release
probably entails keeping track of the name of every debian derivative, so I'd really rather not do that.Also, even if the Makefile were changed to use /usr/local/share/zsh/site-functions/, it sounds as if that might not be a path that works universally either.
Surely there must be a way to ask zsh where to install completions to? But short of taking the first item from $fpath, which doesn't seem robust, I don't know how to. And zsh may not even be installed when building a package that should later integrate with zsh.
FWIW, I checked half a dozen packages like curl that include zsh completions, and none of them installed them with
make install
, they were just there to be installed manually. It seems zsh is making this too hard for software to bother integrating with it.The greatness of os-release (dash, not underscore) is that you can use the ID_LIKE field. From the os-release(5) man page:
"A space-separated list of operating system identifiers in the same syntax as the ID= setting. It should list identifiers of operating systems that are closely related to the local operating system in regards to packaging and programming interfaces [...]". If "debian" is the value of ID, or is contained in the space-separated value of ID_LIKE, then you don't need to know what the specific OS is.
Before os-release, it was common to check if the file /etc/debian_version existed, and if not, check for other distros using /etc/arch-release, /etc/fedora-release, and so on. Ubuntu historically included /etc/debian_version just so tools could identify the distro as debian-compatible, while identifying as Ubuntu only if you used lsb-release...
...
The site-functions directory should work everywhere, I think, since both the /usr/share and /usr/local/share equivalents are defined by the zsh build system (and I'm not aware of any distributors other than Debian which override the former). On my Arch system:
Specifically, if you look at the configure.ac, it will:
It's regrettable that unlike bash-completion, there is no pkg-config file for this.
That would at least allow the build system to build-depend on zsh in order to automatically grab this information. But ultimately, the only thing you need to worry about is which distribution-modified value to use for/instead of /usr/share/zsh/site-functions
In the case of curl, the make install only installs to site-functions, but provides an option --with-zsh-functions-dir=/usr/share/zsh/vendor-completions used at https://salsa.debian.org/debian/curl/blob/27e07a35cb9c727d6005c0afa291e2a3dc3bc5af/debian/rules#L20
Various other programs I have seen will often install to site-functions and let debian's packaging move it if needed, or try to check whether any of several known directories exist. Here is an elaborate detection mechanism which works for a proliferation of possible locations, and can be successfully packaged in a distro build recipe if you first mkdir -p "$DESTDIR/usr/share/zsh/site-functions" (or vendor-completions, depending): https://github.com/kovidgoyal/calibre/blob/7460a12a4bcd05efc822f7fe421626772e2f6575/src/calibre/linux.py#L192-L210
The downside of that is that the packager needs to know they should do this first.