Hello everyone,
I noticed a few things after packaging eglot, and installing it
myself.
When I installed elpa-eglot on my own machine, it pulled elpa-xref
(1.0.2-2) as a dependency, which is very normal, since elpa-xref
is in the "Depends:" field of the control file, because dh-elpa(1)
put it there, using the "Package-Requires:" line of eglot.el.
It turns out that a high enough version of xref (1.3.0) is already
bundled with emacs 28.1+. The shadowing rules specify that any
elisp library in /usr/share/emacs/site-lisp overrides any other
library with the same name in /usr/share/emacs/<version number>,
regardless of version. So we now have a suboptimal situation where
any of our users that installs emacs and elpa-eglot from unstable
will have a lower version of an elisp library (xref 1.0.2) shadow
a higher version (xref 1.3.0). This explanation for this behaviour
is in the function dhelpa-filter-deps-for-debian, in the file
dh-elpa.el : the packages let-alist, seq, xref and project are
never pruned from the dependencies of a package, even when they
are built-in. dh-elpa(1) will therefore always include them, even
when they are not needed.
On the other hand, we also have a situation where elpa-org-roam
does not pull elpa-org, despite the fact that the
"Package-Requires:" line of org-roam.el clearly specifies org-roam
version 9.4 as a dependency. When dh-elpa(1) is run on the build
machine, org is pruned from the dependencies because org is built
in the version of emacs executing the function
dhelpa-filter-deps-for-debian. Note that the minimal version is
not taken into account : builtin org could be present with a lower
version than the one required by org-roam, and org would still get
pruned from the dependencies. More important, the fact that org is
present on the build machine does not mean that its going to be
present with the same version on the user's machine. In fact, if a
user were to install org-roam from bullseye, but had chosen to
retain emacs from buster for whatever reason, the version of org
provided (9.1.9) would not be high enough for org-roam to work
correctly.
As a quick side question, why are these four packages (let-alist,
seq, xref and project) always kept in the list of dependencies,
but org is not ?
Back to the matter at hand, the thing we would need to avoid both
these situations would be for dh-elpa(1) to know, for each builtin
package in the dependencies, what minimal version of emacs bundles
a version high enough for the package we're currently building. It
could then, for each dependency listed in "Package-Requires:",
create a line in "Depends:" of the form :
"emacs (>= <smallest emacs version providing a high enough version
of foo>) | elpa-foo (>= <version asked by the package we're
currently building>)".
This would have the benefit of avoiding the two situations I've
described, would only install a package if strictly needed, but
would also allow the user to install the elpa-foo package
explicitly. There may be some drawbacks I am not aware of, please
tell me.
For this purpose, the function package-built-in-p used in
dhelpa-filter-deps-for-debian is not enough. We would need the
data of what versions of builtin versions are provided by which
versions of emacs. The variable package--builtins provides such
data for the currently running emacs. We could maintain a constant
of our own that would consist in a sequence of these variables
from each version of emacs (this would require a few copy-paste
and a lot of text space, but not much more). We would also need a
function that would take a package name and a minimal version, and
return the minimal version of emacs providing a version at least
as high, or nil if none does.
This proposal might be overengineering for situations that are
probably only corner cases. I wanted to have your thoughts on this
idea before I got to work on a patch.
Thank you in advance for your time and sorry for the long mail.
Best,
Aymeric