Hi Guixers,
I’ve seen a few patches for Emacs packages lately which have the
form:
(package emacs-whatever
(name "emacs-whatever")
(description "Emacs interface for Whatever")
(inputs (list whatever))
(arguments
(list
#:phases
(modify-phases %standard-phases
(add-after 'unpack 'set-whatever-path
(lambda (#:key inputs #:allow-other-keys)
(emacs-substitute-variables "whatever.el"
("emacs-whatever-program"
(search-inputs-file inputs
"/bin/whatever")))))))))
...and looking in emacs-xyz.scm, many packages do this. I
understand why this pattern exists -- making the inferior an input
means that installing the Emacs package Just Works -- but it also
means increased disk consumption and somewhat less user
flexibility.
On the flexibility side, it means that if you install
emacs-whatever and my-personal-whatever-fork, emacs-whatever will
continue using the stock whatever, not your fork; making this work
requires transforming emacs-whatever to replace the input. I
think that because this behavior is so different from how most
other operating systems work, it’s surprising, and the solution
isn’t obvious.
On disk space, it means that many packages come with inputs to
serve many possible usecases, whether those are relevant or not.
One fairly trivial example: emacs-emms has inputs for mpg321,
mid3v2, ogg123, ogginfo, and opusinfo. My music library is 100%
FLAC, so these programs are never used, but consume disk on my
Guix install. And on the other hand, I often use EMMS to play
videos, but mpv *isn’t* an input, so this usecase is broken out of
the box.
Another example is emacs-plantuml-mode, which has plantuml as an
input, which has icedtea as an input -- meaning an install of the
Emacs package comes with a whole Java runtime.
For another example, emacs-emacsql is most often used to access a
SQLite database, but supports MySQL and PostgreSQL as well. The
Guix package has mariadb and postgresql in its inputs, so it can
set their program paths. As a consequence, those packages (which
I don’t use otherwise) are consuming 800mb:
$ du -shc $(find /gnu/store -maxdepth 1 -type d -name
\*-postgresql-\* -or -name \*mariadb\*) | tail -1
804M total
I’m not picking on any individual package or contributor here --
as I said, the pattern is widespread -- and I have multiple
generations in the store, which increase those numbers. But this
feels like an area that could be improved.
I’m not sure how to do that, though. I can think of a few
options:
a) Leave it as is. Don’t love it, but if there’s concensus that
this is the right way, then okay.
b) Make packages that align better with specific usecases,
ex. emacs-emacsql-sqlite, -mysql, etc. This feels fraught to me,
and I don’t think it works if you get emacs-emacsql-sqlite as an
input to some other emacs-* package, but want emacs-emacsql-mysql
as a user. Perhaps metapackages which only exist to combine
dependencies would make this a workable approach.
c) Don’t set them at all, and use the same $PATH late binding as
is typical of other Emacs setups. This would mean that
installing Emacs packages wouldn’t Just Work, and users would
have to install the inferiors (and know what packages those are
in) themselves.
d) Have some better policies around when to use inputs and when
not to. This might be the most pragmatic approach, though it
means inconsistency from package to package.
e) Build a suggested package mechanism into Guix. This has been
floated a couple times before. If it defaults to not installing
suggested packages, but telling the user about them, this would
be like option C, but making it easier to find which packages you
might need; if it installs them by default, it would work like
the current setup, but give users some kind of out to avoid the
extra bandwidth/disk usage. I don’t know how this would work for
declarative package setups -- how would I express to Guix Home
that it should install emacs-emms with flac (for metaflac), but
without mpg321, vorbis-tools, and mp3info?
I’d love to hear others’ thoughts.
Thanks,
-- Ian