I have some nix I’m trying to refactor. It’s a defautl.nix
that is a lambda with a ton of arguments that all have defaults. All of them them are used with nix-build --arg ...
to get different behaviour. The reason I’m refactoring is because default.nix
relies on lib.inNixShell
to either serve a build or a shell, and this is causing problems. I thought it would be really easy to separate it into a default.nix
and a shell.nix
but this has turned out not to be the case due to how nix works. The best structure I can currently come up with is
-
nix/default.nix
: this is where the olddefault.nix
now lives, with a couple changes- all the default argument values have been removed
- the
if
statement has been separated into a set{ build = ...; shell = ...; }
-
default.nix
: is a lambda with all the arguments and their defaults, that passes them intonix/default.nix
and returns thebuild
attribute. -
shell.nix
: same asdefault.nix
but returns theshell
attributes.
This is really bad because we now have to manually make sure that the defaults stay in sync between default.nix
and shell.nix
. not to mention all of the many arguments are duplicated across three files and in two of them they’re duplicated within the file, as they simply just get forwarded into nix/default.nix
.
What I can’t do
- declare the defaults in
nix/default.nix
and use{ ... }@args: (import ./nix args).build
- the
--arg
flag won’t pass in anything
- the
- store all the defaults in a single set so at least they don’t have to be duplicated across
default.nix
andshell.nix
- the defaults depend on each other. I don’t think I can replicate this with a normal set.
I’ve been thinking about it and I’m at a loss. I’m also open to a different approach that doesn’t rely on --arg
but still allows us to configure builds easily.