summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2016-11-06 01:51:13 +0100
committerProfpatsch <mail@profpatsch.de>2016-11-17 19:46:41 +0100
commit61311665cb0f11c4688fc0013d732d85bbd66fca (patch)
tree3f742a70994fc274dc498d0c28b465d62805a8bb /lib
parentba73dbbda61b14ec8e2ca0ab526d3b35ba1db74c (diff)
downloadnixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar.gz
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar.bz2
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar.lz
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar.xz
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.tar.zst
nixpkgs-61311665cb0f11c4688fc0013d732d85bbd66fca.zip
lib: add ini configuration generator
Many configurations are INI-style files. Attribute sets can be mapped
rather painlessly to the INI format.
This adds a function toINI inside a new generators library section.
Also, unit tests for the default values are provided.
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix3
-rw-r--r--lib/generators.nix53
-rw-r--r--lib/tests.nix51
3 files changed, 106 insertions, 1 deletions
diff --git a/lib/default.nix b/lib/default.nix
index cb9a9b0bd4d..c0d7899b882 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -27,6 +27,7 @@ let
 
   # misc
   debug = import ./debug.nix;
+  generators = import ./generators.nix;
   misc = import ./deprecated.nix;
 
   # domain-specific
@@ -39,7 +40,7 @@ in
             customisation maintainers meta sources
             modules options types
             licenses platforms systems
-            debug misc
+            debug generators misc
             sandbox fetchers;
   }
   # !!! don't include everything at top-level; perhaps only the most
diff --git a/lib/generators.nix b/lib/generators.nix
new file mode 100644
index 00000000000..90dd3371454
--- /dev/null
+++ b/lib/generators.nix
@@ -0,0 +1,53 @@
+/* Functions that generate widespread config file
+ * formats from nix data structures.
+ * Tests can be found in ./tests.nix
+ */
+with import ./trivial.nix;
+let
+  libStr = import ./strings.nix;
+  libAttr = import ./attrsets.nix;
+
+  flipMapAttrs = flip libAttr.mapAttrs;
+in
+
+{
+
+  /* Generates an INI-style config file from an
+   * attrset of sections to an attrset of key-value pairs.
+   *
+   * generators.toINI {} {
+   *   foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
+   *   baz = { "also, integers" = 42; };
+   * }
+   *
+   *> [baz]
+   *> also, integers=42
+   *>
+   *> [foo]
+   *> ciao=bar
+   *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
+   *
+   * The mk* configuration attributes can generically change
+   * the way sections and key-value strings are generated.
+   *
+   * For more examples see the test cases in ./tests.nix.
+   */
+  toINI = {
+    # apply transformations (e.g. escapes) to section names
+    mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
+    # format a setting line from key and value
+    mkKeyValue    ? (k: v: "${libStr.escape ["="] k}=${toString v}")
+  }: attrsOfAttrs:
+    let
+        # map function to string for each key val
+        mapAttrsToStringsSep = sep: mapFn: attrs:
+          libStr.concatStringsSep sep
+            (libAttr.mapAttrsToList mapFn attrs);
+        mkLine = k: v: mkKeyValue k v + "\n";
+        mkSection = sectName: sectValues: ''
+          [${mkSectionName sectName}]
+        '' + libStr.concatStrings (libAttr.mapAttrsToList mkLine sectValues);
+    in
+      # map input to ini sections
+      mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
+}
diff --git a/lib/tests.nix b/lib/tests.nix
index c3b8839fda9..b5513dcb5ff 100644
--- a/lib/tests.nix
+++ b/lib/tests.nix
@@ -130,4 +130,55 @@ runTests {
     expected = false;
   };
 
+
+  /* Generator tests */
+  # these tests assume attributes are converted to lists
+  # in alphabetical order
+
+  testToINIEmpty = {
+    expr = generators.toINI {} {};
+    expected = "";
+  };
+
+  testToINIEmptySection = {
+    expr = generators.toINI {} { foo = {}; bar = {}; };
+    expected = ''
+      [bar]
+
+      [foo]
+    '';
+  };
+
+  testToINIDefaultEscapes = {
+    expr = generators.toINI {} {
+      "no [ and ] allowed unescaped" = {
+        "and also no = in keys" = 42;
+      };
+    };
+    expected = ''
+      [no \[ and \] allowed unescaped]
+      and also no \= in keys=42
+    '';
+  };
+
+  testToINIDefaultFull = {
+    expr = generators.toINI {} {
+      "section 1" = {
+        attribute1 = 5;
+        x = "Me-se JarJar Binx";
+      };
+      "foo[]" = {
+        "he\\h=he" = "this is okay";
+      };
+    };
+    expected = ''
+      [foo\[\]]
+      he\h\=he=this is okay
+
+      [section 1]
+      attribute1=5
+      x=Me-se JarJar Binx
+    '';
+  };
+
 }