[Nix-dev] nix os modules: how to filter out unset values

Nicolas Pierron nicolas.b.pierron at gmail.com
Sun Jul 6 16:45:34 CEST 2014


And I guess you are also interested in a way to filter out these "null"
 out of the attribute set that you are getting, as the following code does:

with (import <nixpkgs> {}).lib;

let
  filterAttrsRec = pred: v:
    if isAttrs v then
      filterAttrs pred (mapAttrs (path: filterAttrsRec pred) v)
    else
      v;
in

  filterAttrsRec (n: v: v != null) {
    a.b = null;
    c = 32;
    d.e = "64";
    d.f = null;
    g = null;
    h.i.j = 1;
  }



On Fri, Jul 4, 2014 at 9:35 AM,  <phreedom at yandex.ru> wrote:
> On Monday, June 30, 2014 22:56:27 Max Ivanov wrote:
>> That would work if not type of default should match type of option. So
>> to make it work, I'd need to invent magic values for every type I use,
>> and then filter them all out, which doesn't seem to be very elegant
>> solution.
>
> Unless the magic value is null :) Try this:
> opt1 = mkOption { type = types.nullOr types.str; default=null; };
>
>> The problem is that access to any attribute in
>> config.services.xyz triggers evaluation of the value and if default is
>> missing the error is thrown.
>>
>> So in normal case it enforces values to be set, unless mkOption is
>> used with default attribute. My minimal goal here is at least to keep
>> enforcing as it is, and mark "optional" values so that they don't
>> appear (or can be removed) from config.services.xyz
>>
>> On Mon, Jun 30, 2014 at 8:48 AM, Mateusz Kowalczyk
>>
>> <fuuzetsu at fuuzetsu.co.uk> wrote:
>> > On 06/30/2014 09:42 AM, Max Ivanov wrote:
>> >> Hi Nixers,
>> >>
>> >> I am building a nix os module and stumbled upon a problem which I
>> >> might need your advice on how to approach it.
>> >>
>> >> What I can't figure out, is how to filter out unset values even if
>> >> they don't have a default value set in mkOption. The idea is that
>> >> application itself handles missing values using defaults and I don't
>> >> want to duplicate them in a config.
>> >>
>> >> On the other hand, there are some values which are mandatory, so that
>> >> if they are missing from configuration.nix config build should fail.
>> >> Worth mentioning is that number of mandatory attrs is << number of
>> >> handled by default attrs, so I'd prefer to whitelist mandatories if it
>> >> is possible. Also the solution whatever it is should process cfg
>> >> recursively as cfg is actually nested set of types.submodules.
>> >>
>> >> Here is a minimal example, which demonstrates the problem I am trying
>> >> to solve. It doesn't make sense overall, so don't judge me for missing
>> >> mkIf or silly system services ;) it just shows what I am trying to
>> >> achieve.
>> >>
>> >> { config, lib, pkgs, ... }:
>> >> with lib;
>> >> let
>> >>
>> >>   # question is how to write this function
>> >>   filter_cfg = cfg: cfg;
>> >>
>> >>   cfg = filter_cfg config.services.xyz;
>> >>   confFile = pkgs.writeText "xyz.json" (builtins.toJSON cfg);
>> >>
>> >> in
>> >> {
>> >>
>> >>   options.services.xyz = {
>> >>
>> >>     opt1 = mkOption { type = types.str; default="default_opt1"; };
>> >>
>> >>     # should be excluded from cfg if missing in configuration
>> >>     opt_devs_defaults = mkOption { type = types.str; };
>> >>
>> >>     # error should be raised if missing in conf
>> >>     opt_mandatory = mkOption { type = types.str; };
>> >>
>> >>   };
>> >>
>> >>   config = {
>> >>
>> >>     systemd.services.xyz = {
>> >>
>> >>           serviceConfig = {
>> >>
>> >>               ExecStart = "${pkgs.bash} -c 'touch ${confFile}'";
>> >>
>> >>           };
>> >>
>> >>       };
>> >>
>> >>   };
>> >>
>> >> }
>> >> _______________________________________________
>> >> nix-dev mailing list
>> >> nix-dev at lists.science.uu.nl
>> >> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>> >
>> > For optional values, you could set default to null and then checking for
>> > null later. If it's null, don't include it in the command and if it
>> > isn't then do include it. Effectively ‘not set’ becomes default.
>> >
>> > I'm unsure how you can enforce a presence of an option. Things like
>> > ‘assert’ &c could be used to catch such things but I don't know whether
>> > this is recommended course of action.
>> >
>> > --
>> > Mateusz K.
>> > _______________________________________________
>> > nix-dev mailing list
>> > nix-dev at lists.science.uu.nl
>> > http://lists.science.uu.nl/mailman/listinfo/nix-dev
>>
>> _______________________________________________
>> nix-dev mailing list
>> nix-dev at lists.science.uu.nl
>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>
> _______________________________________________
> nix-dev mailing list
> nix-dev at lists.science.uu.nl
> http://lists.science.uu.nl/mailman/listinfo/nix-dev



-- 
Nicolas Pierron
http://www.linkedin.com/in/nicolasbpierron - http://nbp.name/


More information about the nix-dev mailing list