types: fix dagOf
behaviour with mkIf
This makes definitions like
home.activation.foo = mkIf false "bar"
work, where previously they would complain about
`home.activation.foobar.data` being used but not defined.
The crucial part is that we don't call `convertAllToDags` in
`dagOf.merge`, because we need to process `mkIf`/`mkMerge` properties
first. So we let `attrEquivalent.merge` do its job normally, but give
it a type `dagEntryOf` that does the conversion.
Ideally this shouldn't require so much boilerplate; I'd like to
implement something like
types.changeInto dagContentType elemType dagEntryAnywhere
in Nixpkgs.
(cherry picked from commit 8db712a6a2
)
This commit is contained in:
parent
236c6ec214
commit
834d863dd2
|
@ -8,17 +8,27 @@ let
|
||||||
|
|
||||||
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
||||||
|
|
||||||
dagContentType = elemType:
|
dagEntryOf = elemType:
|
||||||
types.submodule ({ name, ... }: {
|
let
|
||||||
options = {
|
submoduleType = types.submodule ({ name, ... }: {
|
||||||
data = mkOption { type = elemType; };
|
options = {
|
||||||
after = mkOption { type = with types; uniq (listOf str); };
|
data = mkOption { type = elemType; };
|
||||||
before = mkOption { type = with types; uniq (listOf str); };
|
after = mkOption { type = with types; uniq (listOf str); };
|
||||||
};
|
before = mkOption { type = with types; uniq (listOf str); };
|
||||||
config = mkIf (elemType.name == "submodule") {
|
};
|
||||||
data._module.args.dagName = name;
|
config = mkIf (elemType.name == "submodule") {
|
||||||
};
|
data._module.args.dagName = name;
|
||||||
});
|
};
|
||||||
|
});
|
||||||
|
maybeConvert = v: if isDagEntry v then v else dag.entryAnywhere v;
|
||||||
|
in mkOptionType {
|
||||||
|
name = "dagEntryOf";
|
||||||
|
description = "DAG entry of ${elemType.description}";
|
||||||
|
# leave the checking to the submodule type
|
||||||
|
merge = loc: defs:
|
||||||
|
submoduleType.merge loc
|
||||||
|
(map (def: def // { value = maybeConvert def.value; }) defs);
|
||||||
|
};
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
# A directed acyclic graph of some inner type.
|
# A directed acyclic graph of some inner type.
|
||||||
|
@ -29,21 +39,16 @@ in rec {
|
||||||
# "actual" attribute name a new submodule argument is provided with
|
# "actual" attribute name a new submodule argument is provided with
|
||||||
# the name `dagName`.
|
# the name `dagName`.
|
||||||
dagOf = elemType:
|
dagOf = elemType:
|
||||||
let
|
let attrEquivalent = types.attrsOf (dagEntryOf elemType);
|
||||||
convertAllToDags = let
|
|
||||||
maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
|
|
||||||
in map (def: def // { value = mapAttrs maybeConvert def.value; });
|
|
||||||
|
|
||||||
attrEquivalent = types.attrsOf (dagContentType elemType);
|
|
||||||
in mkOptionType rec {
|
in mkOptionType rec {
|
||||||
name = "dagOf";
|
name = "dagOf";
|
||||||
description = "DAG of ${elemType.description}s";
|
description = "DAG of ${elemType.description}s";
|
||||||
check = isAttrs;
|
inherit (attrEquivalent) check merge emptyValue;
|
||||||
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
|
|
||||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
||||||
getSubModules = elemType.getSubModules;
|
getSubModules = elemType.getSubModules;
|
||||||
substSubModules = m: dagOf (elemType.substSubModules m);
|
substSubModules = m: dagOf (elemType.substSubModules m);
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
|
nestedTypes.elemType = elemType;
|
||||||
};
|
};
|
||||||
|
|
||||||
# A directed acyclic graph of some inner type OR a list of that
|
# A directed acyclic graph of some inner type OR a list of that
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) concatStringsSep hm mkMerge mkOption types;
|
inherit (lib) concatStringsSep hm mkIf mkMerge mkOption types;
|
||||||
|
|
||||||
dag = lib.hm.dag;
|
dag = lib.hm.dag;
|
||||||
|
|
||||||
|
@ -14,10 +14,14 @@ in {
|
||||||
options.tested.dag = mkOption { type = hm.types.dagOf types.str; };
|
options.tested.dag = mkOption { type = hm.types.dagOf types.str; };
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
tested = mkMerge [
|
tested.dag = mkMerge [
|
||||||
{ dag.after = "after"; }
|
{ never = mkIf false "never"; }
|
||||||
{ dag.before = dag.entryBefore [ "after" ] "before"; }
|
{ after = mkMerge [ "after" (mkIf false "neither") ]; }
|
||||||
{ dag.between = dag.entryBetween [ "after" ] [ "before" ] "between"; }
|
{ before = dag.entryBefore [ "after" ] (mkIf true "before"); }
|
||||||
|
{
|
||||||
|
between =
|
||||||
|
mkIf true (dag.entryBetween [ "after" ] [ "before" ] "between");
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
home.file."result.txt".text = result;
|
home.file."result.txt".text = result;
|
||||||
|
|
Loading…
Reference in a new issue