Rust library for building no-boilerplate CLI apps

(github.com)

49 points | by PaulHoule 21 hours ago ago

13 comments

  • liambigelow 17 hours ago

    Looks nice! I like the approach.

    My holy grail will still be landing on a good multi-layer configuration setup for Rust CLIs. Ideally CLI flags merged over top of environment variables merged over top of configuration files.

    Twelf [0] was close in unifying things, but I had some friction. Lately I've been using Schematic [1] to handle the environment + config layers, and then just a manual implementation of Clap arguments layered on top.

    [0] https://github.com/bnjjj/twelf.

    [1] https://github.com/moonrepo/schematic

    • brianm 2 hours ago

      I've seen a couple of cli apps recently take the path of "config file is long form arguments, minus the --, separated by newlines, overridden by actual arguments", so if you were doing `dsh` (which doesn't support this) it might look like

          verbose
          show-machine-names
          remoteshell ssh
          forklimit 4
      
      TBH, I quite like it. Less to memorize, easy to know what to override, etc.
    • kdeldycke 10 hours ago

      > My holy grail will still be landing on a good multi-layer configuration setup for Rust CLIs. Ideally CLI flags merged over top of environment variables merged over top of configuration files.

      I did that for Python if you are interested: https://github.com/kdeldycke/click-extra

      You create your CLI with Click as usual, then Click Extra introspects your "--parameters" to build up support for a corresponding configuration file in either TOML, YAML, JSON, INI or XML.

    • weinzierl 8 hours ago

      "Ideally CLI flags merged over top of environment variables merged over top of configuration files."

      I used to wish for that too but I have changed my mind. I think in real world applications with many options it is preferable to not allow every option to be set in every way.

      Environment variables shine for properties that vary per instances which share config files and for system properties (think $GOMAXPROCS).

      Secrets should never go in the command line nor the environment.

      There is no one size fits all. Arguments, environment and config files have different pros and cons and should be used accordingly.

      • liambigelow 9 minutes ago

        Yeah I agree, and do the same. Likewise some config gets complex and can only be reasonably set through config. I prefer when I have a system with one base configuration struct where certain fields can be tagged as available on the command line, another subset in the environment, etc.

    • zakhary 16 hours ago

      Not a library, but I have a template repo [0] I made precisely for this purpose (since I found libraries aren’t as flexible as I needed). See it in use at [1].

      Edit: If there’s demand I’d be willing to better document it.

      [0]: https://github.com/kaplanz/rust

      [1]: https://github.com/kaplanz/rugby/tree/main/apps/cli

    • dakom 16 hours ago

      I've been using Figment [0] Needs a little bit of hand-holding when you have structs with different field names, but otherwise does everything I need for that particular part of the problem.

      [0] https://github.com/SergioBenitez/Figment

  • cdaringe 4 hours ago

    I like the concept. CLIs I author tend to have large sets of —options, thus param derivation prob doesnt work elegantly for my use cases, unless it could expand a structs fields

  • IshKebab 11 hours ago

    Definitely nice, and Typer is one of the few Python libraries that is actually well designed. But Typer is competing against shitty argparse. This is competing with clap-derive which IMO is already very good and "boilerplate free". E.g. how does the comparison look with help messages?

    Nice work anyway!

  • searealist 14 hours ago

    This needs to show a comparison with vanilla clap. In particular, clap allows deriving a parser from a struct and then pattern matching on it. I suspect this is no more terse than that method.