I’ll just say what I know about Docopt. I haven’t used
clap before, so this should be taken as only one side of the comparison.
docopt crate has API documentation, but the documentation for writing the usage string is part of the official Docopt project. So you’ll need to look at that to determine what features docopt has: http://docopt.org/ It has most things you’d expect. Abbreviated short flags:
-zxf. Specify flags more than once to get a list of values:
--output VGA-1 --output HDMI-0. Greedy matching to support commands like
cp src1 src2 src3 dst (actually, I think that is a
docopt.rs special ;-)). Flags can come before or after positional arguments (toggleable). Auto-responses to
--help. Default values. etc etc
- Automatic deserialization of values using
rustc-serialize. (This is one of my favorite features. No fiddling with integer conversions and such. You either get the right type of values, or
docopt shows an error to the user.)
- There is a
docopt! compiler plugin that will generate your struct for your from the usage string, which I think is wicked awesome.
That’s pretty much it. The set of allowed CLI invocations is controlled by your usage string. I don’t know where
clap fits in with the above, so don’t take that as a list of things docopt has that clap doesn’t. It’s just a list of things that docopt has.
Some negatives of Docopt:
- As I said, I have no good answer for sub-commands yet. Both Cargo and xsv do use sub-commands with docopt, but it’s done by having a top-level Docopt usage string with multiple docopt usage strings for each sub-command. I actually think this is a fine thing to do, but the Docopt crate won’t really help you do it. You have to wire it all up yourself. It’s not bad, but it’s not automatic.
- Some failure modes can be especially bad. Docopt is pretty good about saying whether you passed a non-existent flag or committed some other syntax error, but if you passed a valid invocation that simply didn’t match one of the usage patterns, then docopt doesn’t say why. It just says, “Invalid flags.” If your command has lots of complex usage patterns, then it may not be obvious to the user why their command isn’t working.
Ignoring sub-commands, I do think Docopt is easy to use, and I think programs written with it can be easy to maintain. If you follow along in my case study that uses Docopt, it’s pretty easy to add a new argument. Of course, it’s a pretty trivial example, and I imagine it’s just as easy as
clap. I think docopt’s story will get much better when we get stable compiler plugins (or equivalent functionality).
My general view of “which to use” I think is mostly focused on how you feel about either one. I don’t think either are missing anything too major. By far, the most common objection I hear about Docopt is something along the lines of “writing the usage string is annoying.” But then again, one of the most common praises is, “writing the usage string is awesome.”
Anyway, as I wrote (and use)
docopt.rs, take the above with appropriate biases. And if I’ve missed something, please let me know!
Also, one last thing: I’ve seen lots of development activity on
clap which I think is great. For the most part, I think of the
docopt crate as mostly done. There are some problems I’ve outlined above that I’d like to fix, but otherwise, I don’t see much more being added. Most of the meat is in the Docopt spec itself.