summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorRobert Hensing <roberth@users.noreply.github.com>2020-01-14 12:04:05 +0100
committerGitHub <noreply@github.com>2020-01-14 12:04:05 +0100
commit8da81465c19fca393a3b17004c743e4d82a98e4f (patch)
tree3e2824a04be40528809a581346cb0f10682033e1 /lib
parente306ee4a56eeb60eb38e97a33e65a769b0e99ad1 (diff)
parenta46679facd38ef7031ea3a79def60b98e384f155 (diff)
downloadnixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar.gz
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar.bz2
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar.lz
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar.xz
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.tar.zst
nixpkgs-8da81465c19fca393a3b17004c743e4d82a98e4f.zip
Merge pull request #75539 from Gabriel439/gabriel/renderOptions
Add `pkgs.lib.encodeGNUCommandLine`
Diffstat (limited to 'lib')
-rw-r--r--lib/cli.nix56
-rw-r--r--lib/default.nix2
-rw-r--r--lib/tests/misc.nix21
3 files changed, 79 insertions, 0 deletions
diff --git a/lib/cli.nix b/lib/cli.nix
new file mode 100644
index 00000000000..f47625d2f53
--- /dev/null
+++ b/lib/cli.nix
@@ -0,0 +1,56 @@
+{ lib }:
+
+rec {
+  /* 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:
+       encodeGNUCommandLine
+         { }
+         { data = builtins.toJSON { id = 0; };
+
+           X = "PUT";
+
+           retry = 3;
+
+           retry-delay = null;
+
+           url = [ "https://example.com/foo" "https://example.com/bar" ];
+
+           silent = false;
+
+           verbose = true;
+         };
+       => "'-X' 'PUT' '--data' '{\"id\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'"
+  */
+  encodeGNUCommandLine =
+    options: attrs: lib.escapeShellArgs (toGNUCommandLine options attrs);
+
+  toGNUCommandLine =
+    { renderKey ?
+        key: if builtins.stringLength key == 1 then "-${key}" else "--${key}"
+
+    , renderOption ?
+        key: value:
+          if value == null
+          then []
+          else [ (renderKey key) (builtins.toString value) ]
+
+    , renderBool ? key: value: lib.optional value (renderKey key)
+
+    , renderList ? key: value: lib.concatMap (renderOption key) value
+    }:
+    options:
+      let
+        render = key: value:
+                 if builtins.isBool value
+            then renderBool key value
+            else if builtins.isList value
+            then renderList key value
+            else renderOption key value;
+
+      in
+        builtins.concatLists (lib.mapAttrsToList render options);
+}
diff --git a/lib/default.nix b/lib/default.nix
index 77dda17f3b4..5abafe1b2ac 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) encodeGNUCommandLine toGNUCommandLine;
     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..e47b48b5017 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -441,4 +441,25 @@ runTests {
     expected  = "«foo»";
   };
 
+  testRenderOptions = {
+    expr =
+       encodeGNUCommandLine
+         { }
+         { data = builtins.toJSON { id = 0; };
+
+           X = "PUT";
+
+           retry = 3;
+
+           retry-delay = null;
+
+           url = [ "https://example.com/foo" "https://example.com/bar" ];
+
+           silent = false;
+
+           verbose = true;
+         };
+
+    expected = "'-X' 'PUT' '--data' '{\"id\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'";
+  };
 }