summary refs log blame commit diff
path: root/lib/cli.nix
blob: a0e85c396057e0c98f73f81c7afcfbbfb3d23773 (plain) (tree)
1
2
3
4
5
6
7
8

        

                                                                    



                                                                           


                                                             
             



























                                                                                                                                           
    
                         


                                                                         
                 



                                           
 


                          

                                                            
 
                                                                 
 
                                                                     


            



                                                                   
                                        

        
                                                                 
 
{ lib }:

rec {
  /* 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.

     `toGNUCommandLine` returns a list of nix strings.
     `toGNUCommandLineShell` returns an escaped shell string.

     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"
       ]

       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'";
  */
  toGNUCommandLineShell =
    options: attrs: lib.escapeShellArgs (toGNUCommandLine options attrs);

  toGNUCommandLine =
    { renderKey ?
        key:
          if builtins.stringLength key == 1
          then "-${key}"
          else "--${key}"

    , renderOption ?
        key: value:
          if value == null
          then []
          else [ (renderKey key) (builtins.toString value) ]

    , renderBool ? key: value: lib.optional value (renderKey key)

    , renderList ? key: value: lib.concatMap (renderOption key) value
    }:
    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;

      in
        builtins.concatLists (lib.mapAttrsToList render options);
}