query
On this page

toCommandLine

lib.cli.toCommandLine

Docs pulled from | This Revision | 9 minutes ago


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. If null, 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: true emits only the option flag, false emits nothing.

  • true: both true and false are rendered as explicit arguments via formatArg.

Optional fields:

  • formatArg: Converts the option value to a string. Defaults to lib.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.toCommandLineShell
  • lib.cli.toCommandLineGNU
  • lib.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);