Expressões Nix
Uma expressão Nix é como qualquer expressão da linguagem de programação: qualquer coisa que seja avaliada como um valor ou função. Um valor nesse caso também pode ser uma lista ou um conjunto. Como um módulo Nix (arquivo com extensão .nix) pode conter qualquer expressão Nix, você esperaria que o arquivo de configuração NixOS ( /etc/nixos/configuration.nix) contivesse uma única expressão Nix como conteúdo do arquivo.
O arquivo de configuração do NixOS contém uma expressão do Nix no formato:
{config, pkgs, ...}: { /* various configuration options */ }
Se você olhar atentamente, poderá ver que é uma função , porque as funções seguem o formulário pattern: form. Você também pode ver que é uma função que aceita um conjunto e retorna um conjunto. Por exemplo, se você tiver uma função f = {x, y}: {a = x + y;}, poderá chamá-la como f {x=1; y=2;}e recuperar um conjunto {a=3;}.
Então, isso significa que, quando você chama nixos-rebuild switch, algo chama a função dentro do arquivo de configuração do NixOS com o conjunto que deve conter atributos confige pkgs.
importações
Seguindo o exemplo de ./hardware-configuration.nix, a maneira simples de extrair a lista de pacotes em um módulo separado packages.nixé apenas extrair a environment.systemPackagesopção e colocá-la ./packages.nixna importsopção. Você /etc/nixos/configuration.nixficaria assim:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Você /etc/nixos/packages.nixficaria assim:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Como isso funciona? Quando você executa nixos-rebuild switch, o processo que avalia expressões Nix e decide instalar pacotes e assim por diante chama configuration.nixcom um conjunto de atributos, alguns dos quais são confige pkgs.
Ele encontra atributo importsdentro do conjunto devolvido, de modo que avalia cada expressão Nix nos módulos que importscontém com os mesmos argumentos ( config, pkgs, etc.).
Você deve ter pkgscomo argumento (ou, tecnicamente falando, um atributo de um conjunto, que por si só é um argumento) de uma função packages.nix, porque, da perspectiva da linguagem Nix, o processo pode ou não chamar a função com o conjunto que contém pkgs. Caso contrário, a qual atributo você se referiria ao executar with pkgs?
Você também deve ter reticências, porque a função pode ser chamada com outros atributos, não apenas pkgs.
Por que não existe pkgsem configuration.nix? Você pode obtê-lo, mas se não o consultar em nenhum lugar do arquivo, poderá omiti-lo com segurança, pois as reticências os incluiriam de qualquer maneira.
Atualizando um atributo chamando uma função externa
Outra maneira é apenas criar uma função que retorne um conjunto com algum atributo e o valor desse atributo que você colocaria dentro environment.systemPackages. Este é o seu configuration.nix:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# SOME STUFF
environment.systemPackages = import ./packages.nix pkgs;
# SOME STUFF
}
O seu packages.nix:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgssignifica: carregar e retornar a expressão Nix ./packages.nixe, como é uma função, chame-a com um argumento pkgs. with pkgs; [ emacs gitFull ]é uma expressão com , ele traz o escopo da expressão antes do ponto e vírgula para a expressão após ponto e vírgula. Sem isso, seria [ pkgs.emacs pkgs.gitFull ].