aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/pkgs/pkgs-lib
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/pkgs-lib')
-rw-r--r--nixpkgs/pkgs/pkgs-lib/default.nix11
-rw-r--r--nixpkgs/pkgs/pkgs-lib/formats.nix109
-rw-r--r--nixpkgs/pkgs/pkgs-lib/tests/default.nix7
-rw-r--r--nixpkgs/pkgs/pkgs-lib/tests/formats.nix157
4 files changed, 284 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/pkgs-lib/default.nix b/nixpkgs/pkgs/pkgs-lib/default.nix
new file mode 100644
index 00000000000..113dcebf8c6
--- /dev/null
+++ b/nixpkgs/pkgs/pkgs-lib/default.nix
@@ -0,0 +1,11 @@
+# pkgs-lib is for functions and values that can't be in lib because
+# 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/nixpkgs/pkgs/pkgs-lib/formats.nix b/nixpkgs/pkgs/pkgs-lib/formats.nix
new file mode 100644
index 00000000000..14589f8ecdc
--- /dev/null
+++ b/nixpkgs/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"
+ '';
+
+ };
+}
diff --git a/nixpkgs/pkgs/pkgs-lib/tests/default.nix b/nixpkgs/pkgs/pkgs-lib/tests/default.nix
new file mode 100644
index 00000000000..f3549ea9b0f
--- /dev/null
+++ b/nixpkgs/pkgs/pkgs-lib/tests/default.nix
@@ -0,0 +1,7 @@
+# Call nix-build on this file to run all tests in this directory
+{ pkgs ? import ../../.. {} }:
+let
+ formats = import ./formats.nix { inherit pkgs; };
+in pkgs.linkFarm "nixpkgs-pkgs-lib-tests" [
+ { name = "formats"; path = import ./formats.nix { inherit pkgs; }; }
+]
diff --git a/nixpkgs/pkgs/pkgs-lib/tests/formats.nix b/nixpkgs/pkgs/pkgs-lib/tests/formats.nix
new file mode 100644
index 00000000000..bf6be8595e1
--- /dev/null
+++ b/nixpkgs/pkgs/pkgs-lib/tests/formats.nix
@@ -0,0 +1,157 @@
+{ pkgs }:
+let
+ inherit (pkgs) lib formats;
+in
+with lib;
+let
+
+ evalFormat = format: args: def:
+ let
+ formatSet = format args;
+ config = formatSet.type.merge [] (imap1 (n: def: {
+ value = def;
+ file = "def${toString n}";
+ }) [ def ]);
+ in formatSet.generate "test-format-file" config;
+
+ runBuildTest = name: { drv, expected }: pkgs.runCommandNoCC name {} ''
+ if diff ${drv} ${builtins.toFile "expected" expected}; then
+ touch $out
+ else
+ echo "Got: $(cat ${drv})"
+ echo "Should be: ${expected}"
+ exit 1
+ fi
+ '';
+
+ runBuildTests = tests: pkgs.linkFarm "nixpkgs-pkgs-lib-format-tests" (mapAttrsToList (name: value: { inherit name; path = runBuildTest name value; }) (filterAttrs (name: value: value != null) tests));
+
+in runBuildTests {
+
+ testJsonAtoms = {
+ drv = evalFormat formats.json {} {
+ null = null;
+ false = false;
+ true = true;
+ int = 10;
+ float = 3.141;
+ str = "foo";
+ attrs.foo = null;
+ list = [ null null ];
+ };
+ expected = ''
+ {
+ "attrs": {
+ "foo": null
+ },
+ "false": false,
+ "float": 3.141,
+ "int": 10,
+ "list": [
+ null,
+ null
+ ],
+ "null": null,
+ "str": "foo",
+ "true": true
+ }
+ '';
+ };
+
+ testYamlAtoms = {
+ drv = evalFormat formats.yaml {} {
+ null = null;
+ false = false;
+ true = true;
+ float = 3.141;
+ str = "foo";
+ attrs.foo = null;
+ list = [ null null ];
+ };
+ expected = ''
+ {
+ "attrs": {
+ "foo": null
+ },
+ "false": false,
+ "float": 3.141,
+ "list": [
+ null,
+ null
+ ],
+ "null": null,
+ "str": "foo",
+ "true": true
+ }
+ '';
+ };
+
+ testIniAtoms = {
+ drv = evalFormat formats.ini {} {
+ foo = {
+ bool = true;
+ int = 10;
+ float = 3.141;
+ str = "string";
+ };
+ };
+ expected = ''
+ [foo]
+ bool=true
+ float=3.141000
+ int=10
+ str=string
+ '';
+ };
+
+ testIniDuplicateKeys = {
+ drv = evalFormat formats.ini { listsAsDuplicateKeys = true; } {
+ foo = {
+ bar = [ null true "test" 1.2 10 ];
+ baz = false;
+ qux = "qux";
+ };
+ };
+ expected = ''
+ [foo]
+ bar=null
+ bar=true
+ bar=test
+ bar=1.200000
+ bar=10
+ baz=false
+ qux=qux
+ '';
+ };
+
+ testTomlAtoms = {
+ drv = evalFormat formats.toml {} {
+ false = false;
+ true = true;
+ int = 10;
+ float = 3.141;
+ str = "foo";
+ attrs.foo = "foo";
+ list = [ 1 2 ];
+ level1.level2.level3.level4 = "deep";
+ };
+ expected = ''
+ false = false
+ float = 3.141
+ int = 10
+ list = [1, 2]
+ str = "foo"
+ true = true
+
+ [attrs]
+ foo = "foo"
+
+ [level1]
+
+ [level1.level2]
+
+ [level1.level2.level3]
+ level4 = "deep"
+ '';
+ };
+}