Merge pull request #75539 from Gabriel439/gabriel/renderOptions

Add `pkgs.lib.encodeGNUCommandLine`
This commit is contained in:
Robert Hensing 2020-01-14 12:04:05 +01:00 committed by GitHub
commit 8da81465c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 0 deletions

56
lib/cli.nix Normal file
View File

@ -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);
}

View File

@ -39,6 +39,7 @@ let
# misc # misc
asserts = callLibs ./asserts.nix; asserts = callLibs ./asserts.nix;
cli = callLibs ./cli.nix;
debug = callLibs ./debug.nix; debug = callLibs ./debug.nix;
generators = callLibs ./generators.nix; generators = callLibs ./generators.nix;
misc = callLibs ./deprecated.nix; misc = callLibs ./deprecated.nix;
@ -120,6 +121,7 @@ let
isOptionType mkOptionType; isOptionType mkOptionType;
inherit (asserts) inherit (asserts)
assertMsg assertOneOf; assertMsg assertOneOf;
inherit (cli) encodeGNUCommandLine toGNUCommandLine;
inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal

View File

@ -441,4 +441,25 @@ runTests {
expected = "«foo»"; 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'";
};
} }