about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix3
-rw-r--r--lib/generators.nix72
-rw-r--r--lib/maintainers.nix8
-rw-r--r--lib/modules.nix9
-rw-r--r--lib/sources.nix26
-rw-r--r--lib/tests.nix74
6 files changed, 175 insertions, 17 deletions
diff --git a/lib/default.nix b/lib/default.nix
index cb9a9b0bd4d0..c0d7899b882a 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 000000000000..27d4142e8d9a
--- /dev/null
+++ b/lib/generators.nix
@@ -0,0 +1,72 @@
+/* Functions that generate widespread file
+ * formats from nix data structures.
+ *
+ * They all follow a similar interface:
+ * generator { config-attrs } data
+ *
+ * Tests can be found in ./tests.nix
+ * Documentation in the manual, #sec-generators
+ */
+with import ./trivial.nix;
+let
+  libStr = import ./strings.nix;
+  libAttr = import ./attrsets.nix;
+
+  flipMapAttrs = flip libAttr.mapAttrs;
+in
+
+rec {
+
+  /* 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;
+
+
+  /* Generates JSON from an arbitrary (non-function) value.
+    * For more information see the documentation of the builtin.
+    */
+  toJSON = {}: builtins.toJSON;
+
+
+  /* YAML has been a strict superset of JSON since 1.2, so we
+    * use toJSON. Before it only had a few differences referring
+    * to implicit typing rules, so it should work with older
+    * parsers as well.
+    */
+  toYAML = {}@args: toJSON args;
+}
diff --git a/lib/maintainers.nix b/lib/maintainers.nix
index b15f4542fb55..b908a261b1fa 100644
--- a/lib/maintainers.nix
+++ b/lib/maintainers.nix
@@ -48,6 +48,7 @@
   aske = "Kirill Boltaev <aske@fmap.me>";
   asppsa = "Alastair Pharo <asppsa@gmail.com>";
   astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
+  asymmetric = "Lorenzo Manacorda <lorenzo@mailbox.org>";
   aszlig = "aszlig <aszlig@redmoonstudios.org>";
   auntie = "Jonathan Glines <auntieNeo@gmail.com>";
   avnik = "Alexander V. Nikolaev <avn@avnik.info>";
@@ -88,6 +89,7 @@
   chris-martin = "Chris Martin <ch.martin@gmail.com>";
   chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
   christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
+  ckampka = "Christian Kampka <christian@kampka.net>";
   cko = "Christine Koppelt <christine.koppelt@gmail.com>";
   cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
   cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
@@ -129,6 +131,7 @@
   doublec = "Chris Double <chris.double@double.co.nz>";
   drets = "Dmytro Rets <dmitryrets@gmail.com>";
   drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
+  dtzWill = "Will Dietz <nix@wdtz.org>";
   ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
   ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
   eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
@@ -198,8 +201,10 @@
   jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
   javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
   jb55 = "William Casarin <bill@casarin.me>";
+  jbedo = "Justin Bedő <cu@cua0.org>";
   jcumming = "Jack Cummings <jack@mudshark.org>";
   jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
+  jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
   jfb = "James Felix Black <james@yamtime.com>";
   jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
   jgillich = "Jakob Gillich <jakob@gillich.me>";
@@ -273,6 +278,7 @@
   mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
   meditans = "Carlo Nucera <meditans@gmail.com>";
   meisternu = "Matt Miemiec <meister@krutt.org>";
+  mguentner = "Maximilian Güntner <code@klandest.in>";
   mic92 = "Jörg Thalheim <joerg@higgsboson.tk>";
   michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
   michalrus = "Michal Rus <m@michalrus.com>";
@@ -285,6 +291,7 @@
   mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
   modulistic = "Pablo Costa <modulistic@gmail.com>";
   mog = "Matthew O'Gorman <mog-lists@rldn.net>";
+  montag451 = "montag451 <montag451@laposte.net>";
   moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
   moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
   mornfall = "Petr Ročkai <me@mornfall.net>";
@@ -330,6 +337,7 @@
   palo = "Ingolf Wanger <palipalo9@googlemail.com>";
   pashev = "Igor Pashev <pashev.igor@gmail.com>";
   pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
+  periklis = "theopompos@gmail.com";
   pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
   peterhoeg = "Peter Hoeg <peter@hoeg.com>";
   peti = "Peter Simons <simons@cryp.to>";
diff --git a/lib/modules.nix b/lib/modules.nix
index e66d6a6926cb..256d49ba27d8 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -375,10 +375,13 @@ rec {
     if def._type or "" == "merge" then
       concatMap dischargeProperties def.contents
     else if def._type or "" == "if" then
-      if def.condition then
-        dischargeProperties def.content
+      if isBool def.condition then
+        if def.condition then
+          dischargeProperties def.content
+        else
+          [ ]
       else
-        [ ]
+        throw "‘mkIf’ called with a non-Boolean condition"
     else
       [ def ];
 
diff --git a/lib/sources.nix b/lib/sources.nix
index 156afaae5c98..f41abe1e1eae 100644
--- a/lib/sources.nix
+++ b/lib/sources.nix
@@ -12,19 +12,19 @@ rec {
 
   # Bring in a path as a source, filtering out all Subversion and CVS
   # directories, as well as backup files (*~).
-  cleanSource =
-    let filter = name: type: let baseName = baseNameOf (toString name); in ! (
-      # Filter out Subversion and CVS directories.
-      (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
-      # Filter out backup files.
-      lib.hasSuffix "~" baseName ||
-      # Filter out generates files.
-      lib.hasSuffix ".o" baseName ||
-      lib.hasSuffix ".so" baseName ||
-      # Filter out nix-build result symlinks
-      (type == "symlink" && lib.hasPrefix "result" baseName)
-    );
-    in src: builtins.filterSource filter src;
+  cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
+    # Filter out Subversion and CVS directories.
+    (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
+    # Filter out backup files.
+    lib.hasSuffix "~" baseName ||
+    # Filter out generates files.
+    lib.hasSuffix ".o" baseName ||
+    lib.hasSuffix ".so" baseName ||
+    # Filter out nix-build result symlinks
+    (type == "symlink" && lib.hasPrefix "result" baseName)
+  );
+
+  cleanSource = builtins.filterSource cleanSourceFilter;
 
 
   # Get all files ending with the specified suffices from the given
diff --git a/lib/tests.nix b/lib/tests.nix
index c3b8839fda95..d59814987ed6 100644
--- a/lib/tests.nix
+++ b/lib/tests.nix
@@ -130,4 +130,78 @@ 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
+    '';
+  };
+
+  /* right now only invocation check */
+  testToJSONSimple =
+    let val = {
+      foobar = [ "baz" 1 2 3 ];
+    };
+    in {
+      expr = generators.toJSON {} val;
+      # trival implementation
+      expected = builtins.toJSON val;
+  };
+
+  /* right now only invocation check */
+  testToYAMLSimple =
+    let val = {
+      list = [ { one = 1; } { two = 2; } ];
+      all = 42;
+    };
+    in {
+      expr = generators.toYAML {} val;
+      # trival implementation
+      expected = builtins.toJSON val;
+  };
+
 }