summary refs log tree commit diff
diff options
context:
space:
mode:
authorGabriel Gonzalez <Gabriel439@gmail.com>2019-12-11 16:30:05 -0800
committerGabriel Gonzalez <Gabriel439@gmail.com>2019-12-11 16:30:05 -0800
commit183a99734f666b6bd508f4c81e887dbc746fec69 (patch)
tree5ac296649a3555d5f27a1155cf546d110e11ff6c
parent98e57f8999cc88e3d4b2250adef51747ade5105e (diff)
downloadnixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar.gz
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar.bz2
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar.lz
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar.xz
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.tar.zst
nixpkgs-183a99734f666b6bd508f4c81e887dbc746fec69.zip
Add `pkgs.lib.renderOptions`
This adds a new utility to intelligently convert Nix records to
command line options to reduce boilerplate for simple use cases and to
also reduce the likelihood of malformed command lines
-rw-r--r--lib/cli.nix33
-rw-r--r--lib/default.nix2
-rw-r--r--lib/tests/misc.nix16
3 files changed, 51 insertions, 0 deletions
diff --git a/lib/cli.nix b/lib/cli.nix
new file mode 100644
index 00000000000..d794778b21a
--- /dev/null
+++ b/lib/cli.nix
@@ -0,0 +1,33 @@
+{ lib }:
+
+{ /* Automatically convert an attribute set to command-line options.
+
+     This helps protect against malformed command lines and also to reduce
+     boilerplate related to command-line construction for simple use cases.
+
+     Example:
+       renderOptions { foo = "A"; bar = 1; baz = null; qux = true; v = true; }
+       => " --bar '1' --foo 'A' --qux -v"
+  */
+  renderOptions =
+    options:
+      let
+        render = key: value:
+          let
+            hyphenate =
+              k: if builtins.stringLength k == 1 then "-${k}" else "--${k}";
+
+            renderOption = v: if v == null then "" else " ${hyphenate key} ${lib.escapeShellArg v}";
+
+            renderSwitch = if value then " ${hyphenate key}" else "";
+
+          in
+                 if builtins.isBool value
+            then renderSwitch
+            else if builtins.isList value
+            then lib.concatMapStrings renderOption value
+            else renderOption value;
+
+      in
+        lib.concatStrings (lib.mapAttrsToList render options);
+}
diff --git a/lib/default.nix b/lib/default.nix
index 8af53152586..5798c6bba00 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -39,6 +39,7 @@ let
 
     # misc
     asserts = callLibs ./asserts.nix;
+    cli = callLibs ./cli.nix;
     debug = callLibs ./debug.nix;
     generators = callLibs ./generators.nix;
     misc = callLibs ./deprecated.nix;
@@ -120,6 +121,7 @@ let
       isOptionType mkOptionType;
     inherit (asserts)
       assertMsg assertOneOf;
+    inherit (cli) renderOptions;
     inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
       traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
       traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index b064faa1e1b..a5f191410e5 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -441,4 +441,20 @@ runTests {
     expected  = "«foo»";
   };
 
+  testRenderOptions = {
+    expr =
+       renderOptions
+         { foo = "A";
+
+           bar = 1;
+
+           baz = null;
+
+           qux = true;
+
+           v = true;
+         };
+
+    expected = " --bar '1' --foo 'A' --qux -v";
+  };
 }