Проблема

Одна из проблем 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.

Комментарии (9)


  1. MAXH0
    01.10.2024 15:38
    +8

    Удивляюсь Хабру. У человека пишущего годные профильные статьи такая низкая карма. У всяких переводчиков новостей карма под потолок.


    1. Rigidus
      01.10.2024 15:38

      Думаю, минусуют карму ему за проскальзывающую в комментариях манеру учить других и категоричность в суждениях (которая кстати часто встречается у матерых системщиков). А вот за хорошие статьи плюсуют реже чем за плохие комментарии. Я плюсанул.


      1. MAXH0
        01.10.2024 15:38

        Об этом я и говорю. Например, я в своем профиле честно написал, что обожаю учить - это моя профессиональная деформация. Кстати, сейчас я тоже поучаю других и намекаю на неверное поведение большинства.

        НО. В отличии от меня, автор пишет годные статьи технической направленности. Статьи для которых как бы и был создан Хабр. Но один холливар в который влез легко это все перечеркнет. Поскольку противоположная сторона не просто отбомбится в карму, но ее и друзей приведет побомбить. Плюсы-минусы в карму от статей ни как не зависят. Это такой бинарный признак - нравится ли тебе здесь такой человек или нет. Т.е. отбираются по критериям конформизма, а не профессионализма. ЧТО ПЛОХО!


  1. Kurnevsky
    01.10.2024 15:38
    +4

    Nix вместе с emacs-overlay прекрасно решают эту проблему. emacs-overlay парсит init.el и добавляет в зависимости системы все необходимые пакеты, и их версии фиксируются через flacke.lock. Полагаю, emacs-overaly можно использовать на любой системе, но если дествительно интересует воспроизводимость, рекомендую взглянуть на NixOS.


  1. unreal_undead2
    01.10.2024 15:38

    Может зря я начал Elpa использовать (хотя сейчас только четыре пакета оттуда)... В основном сторонние пакеты - просто свалка el файлов, которую перетаскиваю руками с компа на комп, никакой системы, зато работает и не ломается, часть ещё с 19.34 живёт; что-то периодически вычищал, когда втаскивали в стандартную поставку.

    Кстати, что за мода использовать init.el вместо ~/.emacs ?


    1. dunmaksim Автор
      01.10.2024 15:38

      Содержимым каталога ~/.emacs.d/ проще управлять через системы контроля версий, чем содержимым всего ~/.


      1. EgorBakulin
        01.10.2024 15:38

        Сейчас есть еще вариант использовать `~/.config/emacs/init.el`. тогда можно просто всю папку .config положить в репозиторий и спокойно синхронизировать между машинами все конфиги


        1. unreal_undead2
          01.10.2024 15:38

          Во всём .config надо как то аккуратно выделять части, зависящие от системы и конкретной машины, синхронизировать скопом я бы не рискнул. Ну и последние несколько лет Emacs использую в основном на виндовом лаптопе, файлы редактируются через tramp.


      1. unreal_undead2
        01.10.2024 15:38

        Да, соглашусь, что это правильно (так и не заставил себя версионировать конфиги).