toCommandLine
lib.cli.toCommandLine
Converts an attribute set into a list of command-line arguments.
This is the most general command-line construction helper in lib.cli.
It is parameterized by an optionFormat function, which defines how each
option name and its value are rendered.
All other helpers in this file are thin wrappers around this function.
toCommandLine returns a flat list of strings, suitable for use as argv
arguments or for further processing (e.g. shell escaping).
Inputs
optionFormat-
A function that takes the option name and returns an option spec, where the option spec is an attribute set describing how the option should be rendered.
The returned attribute set must contain:
-
option(string): The option flag itself, e.g."-v"or"--verbose". -
sep(string or null): How to separate the option from its argument. Ifnull, the option and its argument are returned as two separate list elements. If a string (e.g."="), the option and argument are concatenated. -
explicitBool(bool): Controls how boolean values are handled: -
false:trueemits only the option flag,falseemits nothing. -
true: bothtrueandfalseare rendered as explicit arguments viaformatArg.
Optional fields:
formatArg: Converts the option value to a string. Defaults tolib.generators.mkValueStringDefault { }.
-
attrs-
An attribute set mapping option names to values.
Supported value types:
- null: omitted entirely
- bool: handled according to
explicitBool - list: each element is rendered as a separate occurrence of the option
- any other value: rendered as a single option argument
Empty attribute names are rejected.
Examples
lib.cli.toCommandLine basic usage example
let
optionFormat = optionName: {
option = "-${optionName}";
sep = "=";
explicitBool = true;
};
in
lib.cli.toCommandLine optionFormat {
v = true;
verbose = [
true
true
false
null
];
i = ".bak";
testsuite = [
"unit"
"integration"
];
e = [
"s/a/b/"
"s/b/c/"
];
n = false;
data = builtins.toJSON { id = 0; };
}
=> [
"-data={\"id\":0}"
"-e=s/a/b/"
"-e=s/b/c/"
"-i=.bak"
"-n=false"
"-testsuite=unit"
"-testsuite=integration"
"-v=true"
"-verbose=true"
"-verbose=true"
"-verbose=false"
]
lib.cli.toCommandLine usage with a more complex option format
let
optionFormat =
optionName:
let
isLong = builtins.stringLength optionName > 1;
in
{
option = if isLong then "--${optionName}" else "-${optionName}";
sep = if isLong then "=" else null;
explicitBool = true;
formatArg =
value:
if builtins.isAttrs value then
builtins.toJSON value
else
lib.generators.mkValueStringDefault { } value;
};
in
lib.cli.toCommandLine optionFormat {
v = true;
verbose = [
true
true
false
null
];
n = false;
output = "result.txt";
testsuite = [
"unit"
"integration"
];
data = {
id = 0;
name = "test";
};
}
=> [
"--data={\"id\":0,\"name\":\"test\"}"
"-n"
"false"
"--output=result.txt"
"--testsuite=unit"
"--testsuite=integration"
"-v"
"true"
"--verbose=true"
"--verbose=true"
"--verbose=false"
]
See also
lib.cli.toCommandLineShelllib.cli.toCommandLineGNUlib.cli.toCommandLineShellGNU
Noogle detected
Implementation
The following is the current implementation of this function.
toCommandLine =
optionFormat: attrs:
let
handlePair =
k: v:
if k == "" then
lib.throw "lib.cli.toCommandLine only accepts non-empty option names."
else if builtins.isList v then
builtins.concatMap (handleOption k) v
else
handleOption k v;
handleOption = k: renderOption (optionFormat k) k;
renderOption =
{
option,
sep,
explicitBool,
formatArg ? lib.generators.mkValueStringDefault { },
}:
k: v:
if v == null || (!explicitBool && v == false) then
[ ]
else if !explicitBool && v == true then
[ option ]
else
let
arg = formatArg v;
in
if sep != null then
[ "${option}${sep}${arg}" ]
else
[
option
arg
];
in
builtins.concatLists (lib.mapAttrsToList handlePair attrs);