nanopb: include C sources (#91055)
[NixPkgs.git] / lib / cli.nix
blobc96d4dbb0432dd3cab8ac388b9de1c955d46d42a
1 { lib }:
3 rec {
4   /* Automatically convert an attribute set to command-line options.
6      This helps protect against malformed command lines and also to reduce
7      boilerplate related to command-line construction for simple use cases.
9      `toGNUCommandLine` returns a list of nix strings.
10      `toGNUCommandLineShell` returns an escaped shell string.
12      Example:
13        cli.toGNUCommandLine {} {
14          data = builtins.toJSON { id = 0; };
15          X = "PUT";
16          retry = 3;
17          retry-delay = null;
18          url = [ "https://example.com/foo" "https://example.com/bar" ];
19          silent = false;
20          verbose = true;
21        }
22        => [
23          "-X" "PUT"
24          "--data" "{\"id\":0}"
25          "--retry" "3"
26          "--url" "https://example.com/foo"
27          "--url" "https://example.com/bar"
28          "--verbose"
29        ]
31        cli.toGNUCommandLineShell {} {
32          data = builtins.toJSON { id = 0; };
33          X = "PUT";
34          retry = 3;
35          retry-delay = null;
36          url = [ "https://example.com/foo" "https://example.com/bar" ];
37          silent = false;
38          verbose = true;
39        }
40        => "'-X' 'PUT' '--data' '{\"id\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'";
41   */
42   toGNUCommandLineShell =
43     options: attrs: lib.escapeShellArgs (toGNUCommandLine options attrs);
45   toGNUCommandLine = {
46     # how to string-format the option name;
47     # by default one character is a short option (`-`),
48     # more than one characters a long option (`--`).
49     mkOptionName ?
50       k: if builtins.stringLength k == 1
51           then "-${k}"
52           else "--${k}",
54     # how to format a boolean value to a command list;
55     # by default it’s a flag option
56     # (only the option name if true, left out completely if false).
57     mkBool ? k: v: lib.optional v (mkOptionName k),
59     # how to format a list value to a command list;
60     # by default the option name is repeated for each value
61     # and `mkOption` is applied to the values themselves.
62     mkList ? k: v: lib.concatMap (mkOption k) v,
64     # how to format any remaining value to a command list;
65     # on the toplevel, booleans and lists are handled by `mkBool` and `mkList`,
66     # though they can still appear as values of a list.
67     # By default, everything is printed verbatim and complex types
68     # are forbidden (lists, attrsets, functions). `null` values are omitted.
69     mkOption ?
70       k: v: if v == null
71             then []
72             else [ (mkOptionName k) (lib.generators.mkValueStringDefault {} v) ]
73     }:
74     options:
75       let
76         render = k: v:
77           if      builtins.isBool v then mkBool k v
78           else if builtins.isList v then mkList k v
79           else mkOption k v;
81       in
82         builtins.concatLists (lib.mapAttrsToList render options);