summaryrefslogtreecommitdiffstats
path: root/pkgs/pkgs-lib
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2020-03-26 02:55:16 +0100
committerSilvan Mosberger <contact@infinisil.com>2020-07-29 18:08:23 +0200
commitb6c540a87cf4cdf5c37cc7975f1afb0c07f8106c (patch)
treeff34068391d955fba54a98486d4a392a851441df /pkgs/pkgs-lib
parent888c923880ed08352a5cadc4e2476c6d1032e1e2 (diff)
pkgs-lib: Implement settings formats for JSON, INI, YAML and TOML
Diffstat (limited to 'pkgs/pkgs-lib')
-rw-r--r--pkgs/pkgs-lib/default.nix6
-rw-r--r--pkgs/pkgs-lib/formats.nix109
2 files changed, 114 insertions, 1 deletions
diff --git a/pkgs/pkgs-lib/default.nix b/pkgs/pkgs-lib/default.nix
index 1f74747d3113..113dcebf8c68 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 000000000000..14589f8ecdc3
--- /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:
+
+ <format> = <parameters>: {
+ # ^^ 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"
+ '';
+
+ };
+}