diff --git a/pkgs/pkgs-lib/default.nix b/pkgs/pkgs-lib/default.nix index 1f74747d311..113dcebf8c6 100644 --- a/pkgs/pkgs-lib/default.nix +++ b/pkgs/pkgs-lib/default.nix @@ -2,6 +2,10 @@ # they depend on some packages. This notably is *not* for supporting package # building, instead pkgs/build-support is the place for that. { lib, pkgs }: { - + # setting format types and generators. These do not fit in lib/types.nix, + # because they depend on pkgs for rendering some formats + formats = import ./formats.nix { + inherit lib pkgs; + }; } diff --git a/pkgs/pkgs-lib/formats.nix b/pkgs/pkgs-lib/formats.nix new file mode 100644 index 00000000000..14589f8ecdc --- /dev/null +++ b/pkgs/pkgs-lib/formats.nix @@ -0,0 +1,109 @@ +{ lib, pkgs }: +rec { + + /* + + Every following entry represents a format for program configuration files + used for `settings`-style options (see https://github.com/NixOS/rfcs/pull/42). + Each entry should look as follows: + + = : { + # ^^ Parameters for controlling the format + + # The module system type most suitable for representing such a format + # The description needs to be overwritten for recursive types + type = ...; + + # generate :: Name -> Value -> Path + # A function for generating a file with a value of such a type + generate = ...; + + }); + */ + + + json = {}: { + + type = with lib.types; let + valueType = nullOr (oneOf [ + bool + int + float + str + (attrsOf valueType) + (listOf valueType) + ]) // { + description = "JSON value"; + }; + in valueType; + + generate = name: value: pkgs.runCommandNoCC name { + nativeBuildInputs = [ pkgs.jq ]; + value = builtins.toJSON value; + passAsFile = [ "value" ]; + } '' + jq . "$valuePath"> $out + ''; + + }; + + # YAML has been a strict superset of JSON since 1.2 + yaml = {}: + let jsonSet = json {}; + in jsonSet // { + type = jsonSet.type // { + description = "YAML value"; + }; + }; + + ini = { listsAsDuplicateKeys ? false, ... }@args: { + + type = with lib.types; let + + singleIniAtom = nullOr (oneOf [ + bool + int + float + str + ]) // { + description = "INI atom (null, bool, int, float or string)"; + }; + + iniAtom = + if listsAsDuplicateKeys then + coercedTo singleIniAtom lib.singleton (listOf singleIniAtom) // { + description = singleIniAtom.description + " or a list of them for duplicate keys"; + } + else + singleIniAtom; + + in attrsOf (attrsOf iniAtom); + + generate = name: value: pkgs.writeText name (lib.generators.toINI args value); + + }; + + toml = {}: json {} // { + type = with lib.types; let + valueType = oneOf [ + bool + int + float + str + (attrsOf valueType) + (listOf valueType) + ] // { + description = "TOML value"; + }; + in valueType; + + generate = name: value: pkgs.runCommandNoCC name { + nativeBuildInputs = [ pkgs.remarshal ]; + value = builtins.toJSON value; + passAsFile = [ "value" ]; + } '' + json2toml "$valuePath" "$out" + ''; + + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4fca1254bcd..07e5fca1685 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -524,7 +524,7 @@ in writers = callPackage ../build-support/writers {}; # lib functions depending on pkgs - inherit (import ../pkgs-lib { inherit lib pkgs; }); + inherit (import ../pkgs-lib { inherit lib pkgs; }) formats; ### TOOLS