I used docopt in production for years, before switching off of it.
My main issues were that the author of docopt doesn't know anything about language grammars & parsing. That's fine — we all start somewhere. But he insists that defining a grammar (and having a rational parser) aren't useful or even possible! If, instead, there were a normative spec (and this requires only the slightest change to edge-cases that aren't tested by his test-suite, anyways), then it'd be possible to really roll out a much more robust docopt than what currently occurs.
With a grammar you'd be able to roll out AST=>AST transforms, and update the parsing strategy of the command lines, i.e., portability between CLI flavors between new/old style POSIX, Windows, etc. You'd have the ability to do i18n, you could catch errors both in the docopt spec of your parser, and in the parsing of the command line options, etc.
I've started with a fork of Docopt, but then I realized the exact same thing - the maintainers didn't use the best parsing practices, so I've just deleted the fork and started Docli. If you follow the tutorial you will see that you can print the AST produced by Docli's parser :D.
Totally! I love the idea of Docopt, but I don't like the implementation - that was the perfect excuse to start Docli (Although some of these points were not YET addressed).
It's also mostly redundant. I'd expect CLI users to be able to parse flags and --help messages in english.
And I'm not saying it as a native english speaker -- which I'm not. Without english knowledge you can't parse 99% of existing, never to be i18n standard UNIX commands, flags, and manpages.
That makes me happy. I'm all for national languages, ethnic nuances etc (I'm not English-native-speaker myself), great spell checkers, voice recognition, fonts, etc for all languages.
But for text work (writing, reading, etc).
Not on my fucking programming languages (like bizarro foreign variable names in source code), and ideally, not on my CLI either.
Let's have a common universal language in our domain.
Doctors get to use latin names and common terms for tons of medical staff whatever their country. Pilots get to speak english with every control tower all around the world.
I am not a Go user so I can't speak about Go specifically, but I feel like including the name of the language in the library name is in general an anti-pattern, since generally when you look for a library to do something in language A, you aren't going to get results using language B anyway.
I still feel that cobra and docopt are ungoish despite the author of cobra getting hired on. There's simply too much magic to both of them. I would much rather they improve flags, which is what I use. It really doesn't take that much with flags to add subcommands, etc, but it could be made better.
Can you elaborate on what makes cobra ungoish? I had built a CLI using it without prior knowledge of Go (but with a background in scripting languages and a some C#) and it seemed pretty straightforward.
The only issue that I can tell was that you can possibly create errors that the compiler can miss, but it's been pretty solid otherwise.
Cobra is very much a kitchen sink approach with a lot of gen. I'd rather have less dependency and write just using the stdlib without the kitchen sink, which is more goish.
I use github.com/urfave/cli, but I almost always end up wrapping it with my own declarative framework. Gradually said framework is becoming more general purpose and suitable for general use, at which point I'll probably open source it and hopefully it will make someone's life better.
For servers I prefer using: https://github.com/alecthomas/kingpin, allows you to really nicely expand based on main arguments with flags. Also, setting defaults is a joy.
Tho admittedly it works in reverse; it generates the doc/help info rather than parsing it into an AST. It addresses the “boilerplate” issue with code gen as well, but it has a CLI to generate code that’s pretty powerful.
For instance, how does docli handle subcommands? How about global vs command specific flags? For any case beyond the basic single command CLI, it seems like there would need to be all sorts of magic and non-obvious formatting requirements on the doc string.
Right now Docli can't handle those scenarios, but it will on the next big release - which it might take a while because it's not trivial to add those features and keep the API simple.
I can second this recommendation – Oclif[0] is an absolute pleasure to use. I'd even encourage developers who aren't at a "full-stack Node.js shop" to give it a shot.
I'm particularly impressed with the bash and zsh autocomplete support. I was delighted when I finished setting it up and everything worked perfectly on the first try.
There are lots of different approaches to defining the arguments and options.
* You can build up a structure programmatically to define the arguments, as in commander, and then the usage and shape of the parsed result are implied.
* You can provide the usage, as in docopt, and then the structure to define the args and shape of the parsed result are implied.
* Or you can take the approach I did in fncli, which is to provide the shape of parsed result, as a function signature, and let the structure to define the args and usage be implied.
This is possible because Javascript spec includes the function arguments as a string that can be parsed at run time.
Because you're using ES6 syntax, you don't have to learn a new syntax (unlike docli or docopt). And although there are limitations, I've found this approach to handle modest CLI needs with an absolute minimum of fuss.
Not really a fan of this approach. I don't like the duality between the help text and the struct it gets bound to - much prefer the approach of generating the help text from a struct.
https://github.com/jessevdk/go-flags is my favourite option; it's lightweight but amazingly featureful, and I much prefer the declarative approach to a programmatic one like the standard library flags package
- i18n is made hard
- syntax errors are not caught by tooling
- you don't get automatic args checking or env var override
Eventually, a well made programmative API is better.