На форуме не очень много информации про систему сборки Nix. Nix прошел долгий путь, и внутри системы давно идёт глубинная трансформация от центрального репозитория с обычными деривациями к графу из флейков.
Флейк заворачивает в себя уже известные нам деривации. Задача флейков – добавить гибкости и масштабируемости в экосистему, за счёт большей жёсткости и структурированности ее базовых элементов.
В классическом Nix роль такого элемента отводилась деривациям, своего рода сценариям, абстрагирующим воспроизводимую сборку программы или библиотеки. Со своей задачей они справляются неплохо, что можно судить о росте числа программ в репозитории nixpkgs. Но как показывает практика, после успешного решения одной большой проблемы появляется другая.
Так произошло и в этот раз – из-за бурного роста числа дериваций стала очевидна проблема их компоновки и менеджмента – в одном гит-репозитарии хранятся ссылки на сотни тысяч проектов, тысячи открытых тикетов и пуллреквестов. Гитхаб даже стал ограничивать скачивание этой репы – пришлось настроить переодическую синхронизацию, чтобы избегать отказов в обслуживании.
Ввели понятие флейка, который упрощает склеивание дериваций во что-то большее. Для этого в определении флейка сделан упор на функцию, так как функции, с точки зрения математики очень хорошо композируются. Да, флейк это чистая функция, которая принимает другие флейки или не флейки а просто ссылки на обычные Nix-файлы или архивы.
В попытке уйти от центрального репозитория все флейк-аргументы передаются по гиперссылкам. Все, что нужно для сборки, указано в значениях по умолчанию аргументов флейка – отпадает требование хранить все флейки кучей.
Вроде бы все хорошо, но в чистой функции нет доступа к глобальным переменным, а аргументами могут быть только гиперссылки. Как в такой флейк передать флаг?!
Здесь, по моему мнению, Nix-пуристы точно перегнули палку.
Да, при сборке флейка можно указать цель (.#цель) – подмножество дериваций из флейка, но производную строку или число уже нет. Без точной цели флейк собирается целиком. Пусть программа может собираться статически и как обычно. Для статической сборки нужно качать и собирать компилятор и полный набор нигде не закешированных библиотек, на что уходит кучка трафика и времени, а требуется это только при релизе, что крайне редкое явление.
По умолчанию цель нельзя выбрать.
В общем получается, чтобы передавать произвольные параметры во флейк при запуске сборки, нужно как минимум сохранить их в файл или загрузить на веб сервер!
Пуристы гнутся под напором инженеров и уже не один год тянется дискуссия под тикетом про то, как разрешить передачу аргументов во флейк по-человечески.
В результате размышлений над улучшением флейкэргономики реализовал костыль в виде микросервиса, который выдает множество Nix атрибутов закодированных незамысловатым образом в пути гиперссылки.
wget -q -O - 'https://lficom.me/name/Alice Wonder/age/18/alive/true/job/null/'
ответ:
{ ... }:
{
name = "Alice Wonder";
age = 18;
alive = true;
job = null;
}
В дополнение к веб-сервису идёт консольная утилита для генерации ссылок из аргументов командной строки и команда:
nix build --override-input c \
https://lficom.me/name/Bob/.tar
сокращается до
nix build $(e -name Bob)
Одновременно с кодирование утилита выполняет валидацию значений и их вычисление в изолированном контексте Nix:
$ e -x "{ x = 2+; }"
Invalid attribute(s):
-x
[{ x = 2+; }] is bad Nix expression due:<string>:1:9:
|
1 | { x = 2+; }
| ^
unexpected ';'
expecting '-'
URL из первого примера сворачивается до:
e -name Alice Wonder -age 18 -alive true -job null
Строки могут содержать пробелы и использование кавычек необязательно, так как значение считается строкой если это не число, литеральное значение, список, множество аттрибутов или лямбда.
Программа доступна в формате флейк на гитхаб и использует себя в своем флейке для купирования проблем связанных со статической сборкой.



