`devShell` accepted either a package def, a submodule value, or a
function to a submodule value. `devShells` only accepted package defs.
This brings all the options of `devShells` to any devShell configured
with `devShells`.
`nullOr`'s merge function requires definitions to all be null or all be
non-null. It was being used where the intent was that null be used as a
value representing unset, and as such the merge should return null if
all definitions are null and ignore nulls otherwise. This adds a type
with that merge semantics.
Before, devShell could be set to a submodule config, a package def, or a
function taking module args and returning a submodule config. This
changes the last form to take the package set instead.
This enables cleaner configuration by not needing each option to
individually be a function of pkgs. Passing pkgs also gives more
flexibility as all the module args are available under the `moduleArgs`
attr.
Code that relied on module args not directly in the package set will now
have to access them from the `moduleArgs` attr.
Many attributes can take moduleArgs when auto-loaded in order to
facilitate access to them from other files. Those same attributes could
not take moduleArgs when included directly, which was inconsistent.
With this change, all attributes that could take moduleArgs when
auto-loaded can now always do so. Auto-loading no longer needs special
cases.
Previously, devShell was inconsistent when setting it to a function.
When setting directly, a function was assumed to be a package definition
and was used to set devShells.default directly. When auto-loading, a
function was assumed to take module args, and result in config (not a
derivation).
This now enables both behaviors in either case by detecting if a
function is a package definition or if it expects module args and
handling it accordingly.
Using `perSystem` to implement per-system attributes ties all the
per-system attributes together; all the `perSystem` functions must run
to determine output attrs. By generating them separately, the generation
can be done lazily.
Using a submodule for devShell removes the need to make every option
nullable and the need to check all of them. By using nullOr submodule,
we can tell if the value has been set and have default values for
options.
This also enables enabling a devShell with no options set.
This sets the default devShell using mkDefault, letting user set default
shells override it. Previously, to set a different default shell, one
would have to not set any of the devShell.* options and then define
devShells.default, or use mkForce.