-
|
Once again, some questions that accumulated over the last couple of weeks, trying to improve my understanding of the inner workings of this great library! It would be awesome if the documentation could elaborate more about these concepts: 1. DAGIs this the intended use of dagOf? options.foo = lib.mkOption {
type = wlib.types.dagOf lib.types.str;
};
config.foo = {
b = wlib.dag.entryAfter ["a"] "hello foo 2";
a = "hello foo 1";
};and then collect them somehow: foos = lib.concatMapStringsSep " " (x: x.data) (wlib.dag.sortAndUnwrap { dag = config.foo; });I split my zsh wrapper into multiple modules:
Each of these modules ultimately collect some snippet of zsh config in form of a string. ''
# Completion
${lib.optionalString config.completion.enable config.completion.init}
# plugins
${config.pluginConfig}
# integrations
${config.integrationConfig}I was thinking of using a dagOf str for this. Am I responsible to always collect the values myself using 2. DALThe only difference to DAL I can spot from the current documentation is that it "Accepts a LIST of elements" (instead of an attrs) and I guess we have to use the Is this all there is to it? I think DAL is a confusing name because in my head I read it as "Directed Acyclic List" which does not make much sense to me (I mean, its not wrong, but its like saying "wet water"). 3. SpecsWhat exactly is a "Spec"? How do I use it? Are the DAG elems Would be awesome to have some minimal examples illustrating their purpose :-) 4. NormalizationMy guess is it refers to wrapping DAG elements inside the data field of |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
There is more to it, as they are submodule types under the hood, so you can use type merging to extend them, or a deferredModule option for people to extend them if you have multiple options with specs that you want them to be able to modify the same way, as seen in the nvim module. But yes that is how you use it (and there is also an unwrapSort which works better in pipes). Although, honestly, the I will be also introducing another few variations of them which merges with the thing you pass rather than putting what you pass into the data field, which may be a little more useful, especially for the entriesBetween function which can do many, but like, especially the ones that are just for a single value are a little superfluous usually haha (but feel free to use them there is nothing really wrong with them, they just arent much shorter usually) But basically, you pass either The resulting value in The ones from the makeWrapper module also accept an
I agree the name DAL meaning directed acyclic list is not good. But everything else I could come up with was just WAY too many letters. The next best would probably be Dependently Ordered List. So I guess I could have chose DOL but then it is not clear they are basically the same thing. Maybe depList? The symmetry between DAG and DAL seemed better for helping people understand they were the same. I don't really see a need to change it at this point. Lets pretend it just means
You provide it a module. You must have 1 option that does not have a default at the top level, i.e. not nested. Everything else must have defaults, nested options are assumed to have defaults. If the value is a set with the same top level value names defined, it will NOT convert it. Otherwise it will convert it, by placing the value in whatever is the main field. (it may at some point to handle nested options better, but it is currently still as lazy as possible, i.e. it doesnt need to recurse into and validate the fields until you grab from them and when you do it only validates the one you grabbed, and I would like to make sure it stays that way, so I will be proceeding carefully with that. Submodule options however work just fine, as they are the option, and the nested values are inside them, but a nested value cannot be the main field)
In this case, a mix of sets with particular fields, and values destined for the main field of said set, all converted into the set form. Edit: These types were also discussed in a PR, so figured I would paste the comment here: It is an
{ config, lib, wlib, ... }: {
options.myspecset = lib.mkOption {
default = {};
type = lib.types.attrsOf (wlib.types.spec {
# yes this is a module, yes this supports type merging
# If the thing does not have the expected fields, it will place it in the main field.
options = {
data = lib.mkOption {
type = lib.types.str;
description = "no default makes this the main one";
};
extrafield = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "and then you can have other ones, but they need defaults";
# You could theoretically set this default via config for this spec submodule as well.
# It needs to be defined somewhere within the base set of modules passed to the type
default = null;
};
};
});
};
# provide just the value for the main field
config.myspecset.TESTVAL1 = "hello";
# or a set where you can set more than just the main field
config.myspecset.TESTVAL2.data = "hello2";
config.myspecset.TESTVAL2.extrafield = "hello2";
config.myspecset.TESTVAL3 = { data = "hello3"; extrafield = "hello3"; };
config.myspecset.TESTVAL4 = { data = "hello4"; };
# now:
# config.myspecset == {
# TESTVAL1 = { data = "hello"; extrafield = null; };
# TESTVAL2 = { data = "hello2"; extrafield = "hello2"; };
# TESTVAL3 = { data = "hello3"; extrafield = "hello3"; };
# TESTVAL4 = { data = "hello4"; extrafield = null; };
# }
}The module passed to The sorting functions from The thing that makes it a DAG are the As to the behavior of the sort, it gets to be quite simple, thanks to nixpkgs offering Basically, there was a lot of stuff where you would want some collection of either the value, or a set with the value and some other stuff. And then you would need to do a bunch of normalization yourself. This is the type for that, and it automatically normalizes it. Then you do whatever with that. If it has a name before and after field, you can call the sorting function on it. |
Beta Was this translation helpful? Give feedback.
There is more to it, as they are submodule types under the hood, so you can use type merging to extend them, or a deferredModule option for people to extend them if you have multiple options with specs that you want them to be able to modify the same way, as seen in the nvim module.
But yes that is how you use it (and there is also an unwrapSort which works better in pipes). Although, honestly, the
entryBeforeandentryAfterthing is kinda not needed, those helpers, especially the single value ones, are kinda longer than writing it out by hand to be honest.I will be also introducing another few variations of them which merges with the thing you pass rather than putting what you pa…