forked from extern/flakelight
589ee5ba7a
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.
140 lines
4.1 KiB
Nix
140 lines
4.1 KiB
Nix
# flakelight -- Framework for simplifying flake setup
|
|
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
inputs:
|
|
let
|
|
inherit (inputs) nixpkgs;
|
|
inherit (builtins) isAttrs isPath readDir;
|
|
inherit (nixpkgs.lib) attrNames composeManyExtensions evalModules filter
|
|
findFirst fix genAttrs getValues hasSuffix isFunction isList mapAttrs
|
|
mapAttrsToList mkDefault mkOptionType pathExists pipe removePrefix
|
|
removeSuffix singleton warn;
|
|
inherit (nixpkgs.lib.types) coercedTo functionTo listOf;
|
|
inherit (nixpkgs.lib.options) mergeEqualOption mergeOneOption;
|
|
|
|
builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k))
|
|
(readDir ./builtinModules);
|
|
|
|
mkFlake = {
|
|
__functor = self: src: root: (evalModules {
|
|
specialArgs.modulesPath = ./builtinModules;
|
|
modules = builtinModules ++ self.extraModules ++ [
|
|
{ inputs.nixpkgs = mkDefault nixpkgs; }
|
|
{ inputs.flakelight = mkDefault inputs.self; }
|
|
{ _module.args = { inherit src flakelight; }; }
|
|
root
|
|
];
|
|
}).config.outputs;
|
|
|
|
# Attributes to allow module flakes to extend mkFlake
|
|
extraModules = [ ];
|
|
extend = (fix (extend': mkFlake': modules: fix (self: mkFlake' // {
|
|
extraModules = mkFlake'.extraModules ++ modules;
|
|
extend = extend' self;
|
|
}))) mkFlake;
|
|
};
|
|
|
|
flakelight = {
|
|
inherit autoImport autoImportArgs mkFlake selectAttr supportedSystem
|
|
types;
|
|
};
|
|
|
|
types = {
|
|
overlay = mkOptionType {
|
|
name = "overlay";
|
|
description = "nixpkgs overlay";
|
|
descriptionClass = "noun";
|
|
check = isFunction;
|
|
merge = _: defs: composeManyExtensions (getValues defs);
|
|
};
|
|
|
|
packageDef = mkOptionType {
|
|
name = "packageDef";
|
|
description = "package definition";
|
|
descriptionClass = "noun";
|
|
check = isFunction;
|
|
merge = mergeOneOption;
|
|
};
|
|
|
|
path = mkOptionType {
|
|
name = "path";
|
|
description = "path";
|
|
descriptionClass = "noun";
|
|
check = isPath;
|
|
merge = mergeEqualOption;
|
|
};
|
|
|
|
function = mkOptionType {
|
|
name = "function";
|
|
description = "function";
|
|
descriptionClass = "noun";
|
|
check = isFunction;
|
|
merge = mergeOneOption;
|
|
};
|
|
|
|
module = mkOptionType {
|
|
name = "module";
|
|
description = "module";
|
|
descriptionClass = "noun";
|
|
check = x: isPath x || isFunction x || isAttrs x;
|
|
merge = _: defs: { imports = getValues defs; };
|
|
};
|
|
|
|
fileset = mkOptionType {
|
|
name = "fileset";
|
|
description = "fileset";
|
|
descriptionClass = "noun";
|
|
check = x: isPath x || x._type or null == "fileset";
|
|
};
|
|
|
|
optListOf = elemType: coercedTo elemType singleton (listOf elemType);
|
|
|
|
optFunctionTo = elemType: coercedTo elemType (x: _: x)
|
|
(functionTo elemType);
|
|
|
|
optCallWith = args: elemType: coercedTo (functionTo elemType) (x: x args)
|
|
elemType;
|
|
};
|
|
|
|
supportedSystem = { lib, stdenv, ... }:
|
|
lib.meta.availableOn stdenv.hostPlatform;
|
|
|
|
importDir = path: genAttrs
|
|
(pipe (readDir path) [
|
|
attrNames
|
|
(filter (s: s != "default.nix"))
|
|
(filter (s: (hasSuffix ".nix" s)
|
|
|| pathExists (path + "/${s}/default.nix")))
|
|
(map (removeSuffix ".nix"))
|
|
(map (removePrefix "_"))
|
|
])
|
|
(p: import (path +
|
|
(if pathExists (path + "/_${p}.nix") then "/_${p}.nix"
|
|
else if pathExists (path + "/${p}.nix") then "/${p}.nix"
|
|
else "/${p}")));
|
|
|
|
autoImport = dir: name:
|
|
if isList name
|
|
then findFirst (x: x != null) null (map (autoImport dir) name)
|
|
else
|
|
if pathExists (dir + "/${name}.nix")
|
|
then import (dir + "/${name}.nix")
|
|
else if pathExists (dir + "/${name}/default.nix")
|
|
then import (dir + "/${name}")
|
|
else if pathExists (dir + "/${name}")
|
|
then importDir (dir + "/${name}")
|
|
else null;
|
|
|
|
autoImportArgs = dir: args: name: warn
|
|
("The autoImportArgs function is deprecated. " +
|
|
"Wrap the target type in flakelight.types.optCallWith instead.")
|
|
(
|
|
let v = autoImport dir name; in
|
|
if isFunction v then v args else v
|
|
);
|
|
|
|
selectAttr = attr: mapAttrs (_: v: v.${attr} or { });
|
|
in
|
|
flakelight
|