flakelight/builtinModules/core.nix
Archit Gupta bb0080c21c Fix inconsistency when setting outputs.__functor
This edge case was inconsistent between setting outputs directly and
auto-loading. Setting directly did not support args, so just merged
sets, thus resulting in a __functor flake output. When autoloading, a
set with a __functor attr was treated as a function and passed module
args.

To correct this inconsistency, outputs now always supports taking args,
and has the autoloading behavior.

Code that relied on previous behavior is easy to fix, as the value needs
to be converted to a function, which can then return the set with
__functor.
2024-01-14 19:22:46 -08:00

79 lines
2.1 KiB
Nix

# flakelight -- Framework for simplifying flake setup
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT
{ config, inputs, lib, flakelight, moduleArgs, ... }:
let
inherit (builtins) all head isAttrs length;
inherit (lib) foldAttrs genAttrs getFiles getValues mapAttrs mergeAttrs
mkOption mkOptionType showFiles showOption;
inherit (lib.types) functionTo lazyAttrsOf listOf nonEmptyStr raw uniq;
inherit (flakelight.types) optCallWith optListOf overlay;
outputs = mkOptionType {
name = "outputs";
description = "output values";
descriptionClass = "noun";
merge = loc: defs:
if (length defs) == 1 then (head defs).value
else if all isAttrs (getValues defs) then
(lazyAttrsOf outputs).merge loc defs
else
throw ("The option `${showOption loc}' has conflicting definitions" +
" in ${showFiles (getFiles defs)}");
};
pkgsFor = genAttrs config.systems (system: import inputs.nixpkgs {
inherit system;
inherit (config.nixpkgs) config;
overlays = config.withOverlays ++ [ config.packageOverlay ];
});
genSystems = f: genAttrs config.systems (system: f pkgsFor.${system});
in
{
options = {
inputs = mkOption {
type = lazyAttrsOf raw;
};
systems = mkOption {
type = uniq (listOf nonEmptyStr);
default = [ "x86_64-linux" "aarch64-linux" ];
};
outputs = mkOption {
type = optCallWith moduleArgs (lazyAttrsOf outputs);
default = { };
};
perSystem = mkOption {
type = functionTo (lazyAttrsOf outputs);
default = _: { };
};
nixpkgs.config = mkOption {
type = lazyAttrsOf raw;
default = { };
};
withOverlays = mkOption {
type = optListOf overlay;
default = [ ];
};
};
config = {
_module.args = {
inherit (config) inputs outputs;
inherit pkgsFor genSystems;
};
outputs = foldAttrs mergeAttrs { } (map
(system: mapAttrs
(_: v: { ${system} = v; })
(config.perSystem pkgsFor.${system}))
config.systems);
};
}