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
This commit is contained in:
Gabriel Gonzalez 2019-12-11 16:30:05 -08:00
parent 98e57f8999
commit 183a99734f
3 changed files with 51 additions and 0 deletions

33
lib/cli.nix Normal file
View file

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

View file

@ -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

View file

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