diff options
Diffstat (limited to 'lib/cli.nix')
-rw-r--r-- | lib/cli.nix | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/lib/cli.nix b/lib/cli.nix index f47625d2f53..c96d4dbb043 100644 --- a/lib/cli.nix +++ b/lib/cli.nix @@ -6,50 +6,77 @@ rec { 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; + `toGNUCommandLine` returns a list of nix strings. + `toGNUCommandLineShell` returns an escaped shell string. - retry-delay = null; - - url = [ "https://example.com/foo" "https://example.com/bar" ]; - - silent = false; + Example: + cli.toGNUCommandLine {} { + 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" + ] - verbose = true; - }; - => "'-X' 'PUT' '--data' '{\"id\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'" + cli.toGNUCommandLineShell {} { + 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 = + toGNUCommandLineShell = options: attrs: lib.escapeShellArgs (toGNUCommandLine options attrs); - toGNUCommandLine = - { renderKey ? - key: if builtins.stringLength key == 1 then "-${key}" else "--${key}" + toGNUCommandLine = { + # how to string-format the option name; + # by default one character is a short option (`-`), + # more than one characters a long option (`--`). + mkOptionName ? + k: if builtins.stringLength k == 1 + then "-${k}" + else "--${k}", - , renderOption ? - key: value: - if value == null - then [] - else [ (renderKey key) (builtins.toString value) ] + # how to format a boolean value to a command list; + # by default it’s a flag option + # (only the option name if true, left out completely if false). + mkBool ? k: v: lib.optional v (mkOptionName k), - , renderBool ? key: value: lib.optional value (renderKey key) + # how to format a list value to a command list; + # by default the option name is repeated for each value + # and `mkOption` is applied to the values themselves. + mkList ? k: v: lib.concatMap (mkOption k) v, - , renderList ? key: value: lib.concatMap (renderOption key) value + # how to format any remaining value to a command list; + # on the toplevel, booleans and lists are handled by `mkBool` and `mkList`, + # though they can still appear as values of a list. + # By default, everything is printed verbatim and complex types + # are forbidden (lists, attrsets, functions). `null` values are omitted. + mkOption ? + k: v: if v == null + then [] + else [ (mkOptionName k) (lib.generators.mkValueStringDefault {} v) ] }: 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; + render = k: v: + if builtins.isBool v then mkBool k v + else if builtins.isList v then mkList k v + else mkOption k v; in builtins.concatLists (lib.mapAttrsToList render options); |