Слово автору @alurm
---
Привет, читатели! 🙂
Меня зовут Алан, на GitHub alurm. Я хочу вам рассказать про мой проект json2dir: конвертор из JSON в папку, который я использую в основном для декларативного менеджмента дотфайлов в связке с Nix.
Как это выглядит
Вот скрипт, который я назвал
apply-dotfiles:cd ~
nix eval ~/Code/alurm/dotfiles/mac#home --json --quiet --quiet "$@" | json2dir
Запустим его через
time, чтобы посмотреть, насколько быстро конфиг применится:$ time apply-dotfiles
________________________________________________________
Executed in 1.60 secs fish external
usr time 1.43 secs 0.38 millis 1.43 secs
sys time 0.21 secs 1.65 millis 0.21 secs
Как видим, мой конфиг применился примерно за полторы секунды.
Суть в том, что мы каким-то образом описываем состояние наших дотфайлов через Nix (или любой другой язык), просим Nix выплюнуть JSON и передаём его в мою утилиту json2dir, которая уже создаёт или перезаписывает необходимые папки и файлы в месте запуска утилиты.
Как именно состояние папки представляется в JSON?
Я определил формат (если угодно, схему) для представления состояния папок через JSON. Формат довольно простой. Используется модель данных, совместимая с Git: есть папки, файлы, исполняемые файлы и символические ссылки. Пример:
{
"название файла": "содержимое файла",
"название папки": {
"единственный файл внутри папки": "содержимое файла"
},
"название символической ссылки": ["link", "цель символической ссылки"],
"название скрипта": ["script", "содержимое скрипта"]
}Таким образом, json2dir ожидает получить JSON-объект. Для представления папок используются JSON-объекты, причём ключи обозначают названия элементов папки, а значения — их содержимое. JSON-строки представляют содержимое файлов. Для представления символических ссылок и исполняемых файлов используются JSON-массивы вида
["link", <target>] и ["script", <content>] соответственно.Так что утилита
json2dir — это интерпретатор подобного формата.Также в разработке находится полноценный архиватор с более широкими возможностями, но самой утилиты
json2dir на практике более чем достаточно для представления большинства необходимых файлов :)Больше подробностей на страничке проекта. А о том, как и вы можете менеджить дотфайлы и пакеты в связке с Nix, можно почитать тут. Мой конфиг можно найти тут.
Слушай, а зачем ты это сделал вообще? При чём тут home-manager?
Что ж, это вышло довольно случайно.
Я использовал Nix через nixsa на общем компьютере без рут-доступа, и мне хотелось использовать home-manager для менеджмента дотфайлов. Но с таким сетапом мне не удалось заставить home-manager работать, так что пришлось выкручиваться.
Я поразмышлял, и мне пришла в голову идея, что раз уж Nix может выплёвывать JSON, то, быть может, можно придумать утилиту, которая будет этот JSON принимать. Я посмотрел на существующие решения для этой проблемы, и они показались мне переусложнёнными и многословными, поэтому я придумал формат и сделал утилиту json2dir.
Роль сыграло и то, что механизм работы home-manager (модули, опции, графы) мне показался несколько сложным для понимания по сравнению с простой генерацией JSON. Кроме того, я заметил, что у некоторых пользователей Nix обновление конфига занимает минуты — в моём случае это скорее секунды (или миллисекунды, если конфиг совсем маленький). Nix используется и для менеджмента пакетов, но это уже отдельная команда
nix profile upgrade.Да, у такого подхода есть свои недостатки, но есть и преимущества: json2dir не создаёт символические ссылки на файлы внутри неизменяемого
/nix/store и не удаляет файлы, поэтому возможен некоторый дрифт конфига. Зато такие файлы легко отредактировать руками. Также концептуально утилита не привязана к Nix: конфиг можно написать хоть на питоне.Остальное — в репозитории проекта. Спасибо :)
---