Inline a Nix expression into a single source file

With a Nix expression divided among imported source files, can Nix “inline” them into a single Nix expression (as if they’d been written in a single file)?

{
  imports = [
    ./foo.nix
    ./bar.nix
  ];
}
# foo.nix
{
  services.openssh.enable = true;
}
# bar.nix
{
  services.openssh.settings.PermitRootLogin = "no";
}

I know it’s typical to locally evaluate the expression to produce store derivations (i.e. instantiate) which can then be copied via closures to another machine and realized, but derivation files can be massive. And syncing a repo of source files can be burdensome too. Sometimes I’d like a way to just inline the expression itself, which could then be evaluated on a remote machine.

Anyone tried something similar? A way to ask Nix to just resolve imports, but don’t actually evaluate. Don’t touch the Nix Store. Don’t build anything. Just inline.

# merged
{
  services.openssh.enable = true;
  services.openssh.settings.PermitRootLogin = "no";
}

Unfortunately there’s no such thing. To get exactly what you describe, you need to not only parse but actually evaluate and the expression to transform it in non-trivial ways, which would involve a lot of domain knowledge from the module system. One specific complication would be to know which option values were set by the user rather than by modules themselves. This sort of tooling is not likely to appear any time soon (although it would be great to have).

To merely recursively expand import expressions, one could use rnix-parser, and maybe someone has already done that.

I suppose even with a parser like rnix-parser, dynamic import expressions would require some interpretting. And converting an abstract tree back to a source-like form would be tricky. I see your points. I’d need Nix to have more built out tooling in other languages or for nix to gain some abilities here.

1 Like