1
1
forked from extern/flakelight

Refactor checks to use types

This commit is contained in:
Archit Gupta 2024-02-24 21:22:00 -08:00
parent e72626b0a9
commit 610cc3b0c4
2 changed files with 54 additions and 13 deletions

View File

@ -4,28 +4,49 @@
{ config, src, lib, flakelight, genSystems, ... }: { config, src, lib, flakelight, genSystems, ... }:
let let
inherit (lib) isDerivation isFunction mkOption mkIf mapAttrs; inherit (lib) isFunction last mapAttrs mergeDefinitions mkIf mkOption
inherit (lib.types) lazyAttrsOf raw; mkOptionType;
inherit (flakelight.types) nullable optFunctionTo; inherit (lib.types) lazyAttrsOf optionDescriptionPhrase;
inherit (flakelight.types) coercedTo' drv nullable optFunctionTo stringLike;
mkCheck = pkgs: name: cmd: mkCheck = name: pkgs: cmd:
let cmd' = if isFunction cmd then cmd pkgs else cmd; in
if isDerivation cmd' then cmd' else
pkgs.runCommand "check-${name}" { } '' pkgs.runCommand "check-${name}" { } ''
cp --no-preserve=mode -r ${src} src cp --no-preserve=mode -r ${src} src
cd src cd src
${cmd'} ${cmd}
touch $out touch $out
''; '';
checkType = mkOptionType {
name = "checkType";
description =
let
targetDesc = optionDescriptionPhrase
(class: class == "noun" || class == "composite")
(coercedTo' stringLike (abort "") drv);
in
"${targetDesc} or function that evaluates to it";
descriptionClass = "composite";
check = x: isFunction x || drv.check x || stringLike.check x;
merge = loc: defs: pkgs:
let
targetType = coercedTo' stringLike (mkCheck (last loc) pkgs) drv;
in
(mergeDefinitions loc targetType (map
(fn: {
inherit (fn) file;
value = if isFunction fn.value then fn.value pkgs else fn.value;
})
defs)).mergedValue;
};
in in
{ {
options.checks = mkOption { options.checks = mkOption {
type = nullable (optFunctionTo (lazyAttrsOf raw)); type = nullable (optFunctionTo (lazyAttrsOf checkType));
default = null; default = null;
}; };
config.outputs = mkIf (config.checks != null) { config.outputs = mkIf (config.checks != null) {
checks = genSystems (pkgs: checks = genSystems (pkgs: mapAttrs (_: v: v pkgs) (config.checks pkgs));
mapAttrs (mkCheck pkgs) (config.checks pkgs));
}; };
} }

View File

@ -7,9 +7,9 @@ let
inherit (inputs) nixpkgs; inherit (inputs) nixpkgs;
inherit (builtins) isAttrs isPath readDir; inherit (builtins) isAttrs isPath readDir;
inherit (nixpkgs.lib) all attrNames composeManyExtensions evalModules filter inherit (nixpkgs.lib) all attrNames composeManyExtensions evalModules filter
findFirst fix genAttrs getValues hasSuffix isFunction isList isStringLike findFirst fix genAttrs getValues hasSuffix isDerivation isFunction isList
mapAttrs mapAttrsToList mkDefault mkOptionType pathExists pipe removePrefix isStringLike mapAttrs mapAttrsToList mkDefault mkOptionType pathExists pipe
removeSuffix singleton warn; removePrefix removeSuffix singleton warn;
inherit (nixpkgs.lib.types) coercedTo defaultFunctor functionTo listOf inherit (nixpkgs.lib.types) coercedTo defaultFunctor functionTo listOf
optionDescriptionPhrase; optionDescriptionPhrase;
inherit (nixpkgs.lib.options) mergeEqualOption mergeOneOption; inherit (nixpkgs.lib.options) mergeEqualOption mergeOneOption;
@ -74,6 +74,14 @@ let
merge = mergeOneOption; merge = mergeOneOption;
}; };
drv = mkOptionType {
name = "drv";
description = "derivation";
descriptionClass = "noun";
check = isDerivation;
merge = mergeOneOption;
};
stringLike = mkOptionType { stringLike = mkOptionType {
name = "stringLike"; name = "stringLike";
description = "string-convertible value"; description = "string-convertible value";
@ -99,6 +107,18 @@ let
optListOf = elemType: coercedTo elemType singleton (listOf elemType); optListOf = elemType: coercedTo elemType singleton (listOf elemType);
coercedTo' = coercedType: coerceFunc: finalType:
(coercedTo coercedType coerceFunc finalType) // {
merge = loc: defs:
let
coerceVal = val:
if finalType.check val then val
else coerceFunc val;
in
finalType.merge loc
(map (def: def // { value = coerceVal def.value; }) defs);
};
optFunctionTo = optFunctionTo =
let let
nonFunction = mkOptionType { nonFunction = mkOptionType {