Когда и как следует использовать default.nix, shell.nix и release.nix?

Один из первых типов выражения Nix, встречающийся при обучении использованию диспетчера пакетов Nix, - default.nix; на замечательном канале IRC NixOS я узнал о существовании shell.nix и release.nix.

У меня сложилось впечатление, что грубо - default.nix следует использовать с nix-build для простого построения пакета, shell.nix используется с nix-shell для создания интерактивной среды с пакетом, а release.nix - используется с nixops при развертывании пакета.

Так как это, вероятно, неполное и частично неверное, и поскольку это, как представляется, не является четко документированным, я хотел бы получить четкое и точное объяснение этих типов "стандартных файлов"; в частности, для каждого из этих типов файлов (а также любых других стандартных файлов, которые мне не хватает), я хотел бы знать:

  • Каковы типичные варианты использования такого файла? Для чего они не должны использоваться?
  • Как обычно этот тип файла структурирован? Каковы минимальные требования для этого?
  • Не могли бы вы показать пример парадигмы такого файла в контексте его использования, т.е. с инструкциями использования и включая строки кода, необходимые для использования в оболочке или другом выражении Nix?

В качестве дополнительного вопроса о бонусе, я хочу знать, какие из этих стандартных файлов, если таковые имеются, следует использовать при установке пакета в модуль NixOS? Как это будет сделано?

Ответ 1

Как сказано @danbst, только default.nix и shell.nix имеют специальные значения для инструментальной системы nix, из которых нет реального стандарта, и каждый может свободно использовать то, что подходит для большинства их потребностей.

Тем не менее, это не значит, что вы не можете установить свой собственный набор правил лично для одного проекта деривации. Мне нравится упорядочивать nix файлы следующим образом:

  • default.nix: используйте callpackage для импорта derivation.nix.
  • derivation.nix: файл дефиниции стиля nixpkgs.
  • shell.nix: файл nix-shell.
  • module.nix: файл модуля NixOS, import default.nix.
  • test.nix: тестовый файл NixOS.
  • release.nix: декларация о назначении Hydra.

Мы поговорили об этой теме в Tokyo NixOS meetup, пример такой организации кода можно найти здесь.

Ответ 2

Прежде всего, default.nix и shell.nix имеют специальные значения в инструменте Nix, но release.nix является удобной.

Далее default.nix используется как файл по умолчанию при запуске nix-build, а shell.nix используется как файл по умолчанию при запуске nix-shell. Так же, как вы сказали.

Далее, default.nix используется не только для nix-build. Например, <nixpkgs/lib/default.nix> используется как агрегатор для функций и не содержит дериваций. Поэтому не каждый default.nix должен быть "построен" (но если default.nix - это набор атрибутов дериваций, он будет доступен для сборки, а nix-build построит все из них).

Далее nix-shell будет использовать default.nix, если не найдено shell.nix.

Затем default.nix используется как файл по умолчанию при импорте каталога. Поэтому, если вы напишете x = import ./some/directory;, тогда будет импортирован ./some/directory/default.nix. Это на самом деле должно объяснить, почему "nix-build ." использует default.nix.

И, наконец, существуют два распространенных формата для дериваций в default.nix: деривации и callPackage вывода. Вы не можете nix-build последнего. Почти любой пакет в nixpkgs написан в этом стиле, см. hello. Но вы можете nix-build -E 'with import <nixpkgs> { }; callPackage ./path/to/default.nix { }' как обходной путь. nix-shell также поддерживает этот аргумент -E.