GNU Emacs: вопроизводимая сборка всё ближе

7df6114ddf401ede430ab3d845261347

Проблема

Одна из проблем GNU Emacs заключается в сложности создания воспроизводимой сборки. Разумеется, вы всегда можете сделать себе контейнер, и запускать Emacs с помощью Docker, Podman или даже Kubernetes… Но я сейчас не о таких сложных случаях.

Итак, суть проблемы: если создать файл init.el и отладить его, то через 2–3 месяца запуск с ним Emacs на другом компьютере с большой вероятностью приведёт к ошибкам установки или несовместимости пакетов.

Авторы различных языков программирования и технологий решали проблему несовместимости пакетов разными способами. Поскольку я когда-то писал на Python, мне ближе всего его REQUIREMENTS-файлы.

Джун, скорее всего, заполнит REQUIREMENTS так:

django
django-rest-framework
pillow
psycopg2

Миддл потому и называется так, что видел некоторое дерьмо, поэтому версии пакетов «прибьёт гвоздями»:

django==5.1.1
django-rest-framework==3.15.2
pillow==10.4.0
psycopg2<3

Сеньор соберёт контейнер с указанными зависимостями, и будет использовать его и только его.

Решения

А что насчёт Emacs? Очень долго там не было способа использовать фиксированные версии пакетов из архивов типа MELPA. Дело в том, что архивы не хранят историю версий, а предоставляют доступ только к самому свежему релизу пакета. Надо ли говорить, что пакеты из MELPA часто ломаются?

MELPA Stable не решает проблему, потому что собирает пакеты не стабильной версии, а вообще любой, лишь бы там стоял тег системы контроля версий.

Цитата из README

Packages in MELPA are built directly from the latest package source code in the upstream repositories, but we also build and publish packages corresponding to the latest tagged code in those repositories, where version tags exist. These packages are published in a separate package archive called MELPA Stable. Most users should prefer MELPA over MELPA Stable.

Проблему фиксации зависимостей в Emacs пытались решать разными способами. По этой (но не только по этой) причине родились такие проекты, как:

  • Straight.el

  • El-get

  • Quelpa

  • Cask

  • Eask

У каждого из них свои особенности, а у многих — плохая документация. Особо фееричным в этом плане показался проект Eask, который официально рекомендует не читать сайт с собственной документацией.

Ещё есть решения, предлагающие добавлять код пакетов как суб-модули Git. Но это не наш путь, верно?

package-vc-install

Авторы Emacs придумали, как решить прооблему фиксации версий пакетов, и в то же время сохранить функциональность package.el. Встречайте! package-vc-install.el!

Начиная с версии 29.1 в Emacs стал доступен пакет package-vc-install, который почти такой же как package.el, только позволяет устанавливать указанные версии пакетов из указанных источников.

Функция package-vc-install принимает на вход название пакета и словарь с настройками источника. Ключами этого словаря могут быть следующие значения:

  • :url — ссылка на репозиторий. Можно использовать путь к локальному каталогу.

  • :branch— название ветки, название тега или хеш коммита.

  • :lisp-dir— путь к каталогу с файлами .el. Это поле нужно заполнять, если файлы пакета хранятся не в корневом каталоге.

  • :doc — путь к каталогу с документацией. Это поле нужно заполнять, если вы хотите собрать документацию вместе с пакетом. Но вообще это не обязательно.

Там есть и другие ключи, подробнее смотрите в документации GNU Emacs.

Минусы?

За всё нужно платить, и package-vc-install не исключение. Вам придётся:

  • самостоятельно искать репозитории нужных пакетов;

  • установить в систему клиент соответствующей системы контроля версий;

  • самостоятельно отслеживать обновления пакета.

Есть и хорошие новости: если обновить use-package до версии 2.4.6, то там уже встроена нужная функциональность:

(use-package delight
  :ensure t
  :vc (:url "https://git.savannah.nongnu.org/git/delight.git"
       :rev "1.7"))

(use-package ace-window
  :ensure t
  :vc (
       :url "https://github.com/abo-abo/ace-window.git"
       :rev "0.10.0")
  :bind (:map global-map
              ("M-o" . ace-window)))

Подробности смотрите в документации пакета на сайте GNU ELPA.

© Habrahabr.ru