• azertyfun@sh.itjust.works
    link
    fedilink
    arrow-up
    18
    arrow-down
    1
    ·
    6 days ago

    Counterpoint: Yes, parse don’t validate, but CLIs should not be dealing with dependency management.

    I love Python’s argparse because:

    • It’s “Parse, don’t validate” (even supports FileType as a target)
    • It enforces or strongly encourages good CLI design
      • Required arguments should in most situations be positional arguments, not flags. It’s curl <URL> not curl --url <URL>.
      • Flags should not depend on each other. That usually indicates spaghetti CLI design. Don’t do server --serve --port 8080 and server --reload with rules for mix-and-matching those, do server serve --port 8080 and server reload with two separate subparsers.
      • Mutually exclusive flags sometimes make sense but usually don’t. Don’t do --xml --json, do -f [xml|json].
      • This or( pattern of yours IMO should always be replaced by a subparser (which can use inheritance!). As a user the options’ data model should be immediately intuitive to me as I look at the --help and having mutually exclusive flags forces the user to do the extra work of dependency management. Don’t do server --env prod --auth abc --ssl, do server serve prod --auth abc --ssl where prod is its own subparser inheriting from AbstractServeParser or whatever.

    Thinking of CLI flags as a direct mapping to runtime variables is the fundamental mistake here I think. A CLI should be a mapping to the set(s) of behavior(s) of your application. A good CLI may have mandatory positional arguments but has 0 mandatory flags, 0 mutually exclusive flags, and if it implements multiple separate behaviors should be a tree of subparsers. Any mandatory or mutually exclusive flags should be an immediate warning that you’re not being very UNIX-y in your CLI design.