lib/types: make DAG entries mergeable

Removes the `uniq` constraint on `after` and `before` so that we can
merge multiple definitions for the same DAG entry:

    {
      dag = mkMerge [
        {
          foo = lib.hm.dag.entryBefore [ "bar" ] {
            # definition 1
          };
        }
        {
          foo = lib.hm.dag.entryBefore [ "qux" ] {
            # definition 2
          };
        }
        {
          foo = {
            # definition 3
          };
        }
      ];
    }

In this example `foo` will come before `bar` and `qux`.
This commit is contained in:
Naïm Favier 2022-05-09 19:50:15 +02:00 committed by Robert Helgesson
parent 177f1887d4
commit 6311f4adc3
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
3 changed files with 27 additions and 11 deletions

View file

@ -3,8 +3,8 @@
let let
inherit (lib) inherit (lib)
concatStringsSep defaultFunctor fixedWidthNumber imap1 isAttrs isList length concatStringsSep defaultFunctor fixedWidthNumber imap1 isAttrs isList length
listToAttrs mapAttrs mkIf mkOption mkOptionType nameValuePair stringLength listToAttrs mapAttrs mkIf mkOrder mkOption mkOptionType nameValuePair
types warn; stringLength types warn;
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before); isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
@ -13,21 +13,30 @@ let
submoduleType = types.submodule ({ name, ... }: { submoduleType = types.submodule ({ name, ... }: {
options = { options = {
data = mkOption { type = elemType; }; data = mkOption { type = elemType; };
after = mkOption { type = with types; uniq (listOf str); }; after = mkOption { type = with types; listOf str; };
before = mkOption { type = with types; uniq (listOf str); }; before = mkOption { type = with types; listOf str; };
}; };
config = mkIf (elemType.name == "submodule") { config = mkIf (elemType.name == "submodule") {
data._module.args.dagName = name; data._module.args.dagName = name;
}; };
}); });
maybeConvert = v: if isDagEntry v then v else dag.entryAnywhere v; maybeConvert = def:
if isDagEntry def.value then
def.value
else
dag.entryAnywhere (if def ? priority then
mkOrder def.priority def.value
else
def.value);
in mkOptionType { in mkOptionType {
name = "dagEntryOf"; name = "dagEntryOf";
description = "DAG entry of ${elemType.description}"; description = "DAG entry of ${elemType.description}";
# leave the checking to the submodule type # leave the checking to the submodule type
merge = loc: defs: merge = loc: defs:
submoduleType.merge loc submoduleType.merge loc (map (def: {
(map (def: def // { value = maybeConvert def.value; }) defs); inherit (def) file;
value = maybeConvert def;
}) defs);
}; };
in rec { in rec {
@ -42,7 +51,7 @@ in rec {
let attrEquivalent = types.attrsOf (dagEntryOf elemType); let attrEquivalent = types.attrsOf (dagEntryOf elemType);
in mkOptionType rec { in mkOptionType rec {
name = "dagOf"; name = "dagOf";
description = "DAG of ${elemType.description}s"; description = "DAG of ${elemType.description}";
inherit (attrEquivalent) check merge emptyValue; inherit (attrEquivalent) check merge emptyValue;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]); getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
getSubModules = elemType.getSubModules; getSubModules = elemType.getSubModules;

View file

@ -1,3 +1,4 @@
before:before before:before
merged:left,middle,middle,right
between:between between:between
after:after after:after

View file

@ -1,7 +1,8 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
inherit (lib) concatStringsSep hm mkIf mkMerge mkOption types; inherit (lib)
concatStringsSep hm mkIf mkMerge mkBefore mkAfter mkOption types;
dag = lib.hm.dag; dag = lib.hm.dag;
@ -11,17 +12,22 @@ let
in concatStringsSep "\n" data + "\n"; in concatStringsSep "\n" data + "\n";
in { in {
options.tested.dag = mkOption { type = hm.types.dagOf types.str; }; options.tested.dag = mkOption { type = hm.types.dagOf types.commas; };
config = { config = {
tested.dag = mkMerge [ tested.dag = mkMerge [
{ never = mkIf false "never"; } (mkIf false { never = "never"; })
{ never2 = mkIf false "never2"; }
{ after = mkMerge [ "after" (mkIf false "neither") ]; } { after = mkMerge [ "after" (mkIf false "neither") ]; }
{ before = dag.entryBefore [ "after" ] (mkIf true "before"); } { before = dag.entryBefore [ "after" ] (mkIf true "before"); }
{ {
between = between =
mkIf true (dag.entryBetween [ "after" ] [ "before" ] "between"); mkIf true (dag.entryBetween [ "after" ] [ "before" ] "between");
} }
{ merged = dag.entryBefore [ "between" ] "middle"; }
{ merged = mkBefore "left"; }
{ merged = dag.entryBetween [ "after" ] [ "before" ] (mkAfter "right"); }
{ merged = dag.entryBefore [ "between" ] "middle"; }
]; ];
home.file."result.txt".text = result; home.file."result.txt".text = result;