Re:Challenge: Implement CLI interface like that?
by moe on Sunday June 17, 2012 @07:41AM
(#4122725)
Imho this is a bad pitch. It took me a moment to realize that you have already solved the problem that you're proposing (and the "challenge" is only meant to pitch the solution).
Given the elegance of that very solution I think this marketing stunt is entirely unneeded and actually harmful; it's confusing and you miss out on getting a descriptive headline such as "Generate OptParser from code comment!".
That said... Brilliant idea!
I'm definitely trying out docopt for my next project.
And I have a counter-challenge for you:
How about making docopt work with nested commands? I.e. multiple methods could have a docopt-style comment and they would smartly merge to enable usages such as "mygit remote show --help", where 'show' is a subcommand of 'remote', with its own set of parameters and a matching help-page.
If you can work that one out then docopt could become the defacto standard for generating even complex OptParsers.
Re:Challenge: Implement CLI interface like that?
by antidoh on Sunday June 17, 2012 @10:35AM
(#4123012)
I think it's a great pitch, because the pseudo-pitch appeals to exactly the people who would be interested in this. "Ha! I've got this licked, I'll just whip out argparse ... Wait ... Oh!"
Re:Challenge: Implement CLI interface like that?
by phoboslab on Sunday June 17, 2012 @08:15AM
(#4122793)
For me, your new presentation worked brilliantly. The short while it took me to get what was going on, was exactly what caused me to keep reading. Granted, it is a bit of a bait and switch, but a pleasant one.
Re:Challenge: Implement CLI interface like that?
by tathagatadg on Sunday June 17, 2012 @09:39AM
(#4122911)
I too think the pitch is brilliant - specially when you think about the target audience - folks who get turned on by the word "Challenge", er developers, and most of them must have felt the need for something like this at some point of their life("Some day I'll have to write clean & DRY way ...").
Only thing different might be instead of giving the solution on that page itself - a hyperlink to the solution which takes you to docopt.org landing page
Re:Challenge: Implement CLI interface like that?
by mikeash on Sunday June 17, 2012 @10:34AM
(#4123011)
I agree. I thought, interesting challenge, although not interesting enough for me to actually try it. I wonder if he has any example solutions that I could look through. Huh? Ooooh.
If I had just seen it presented straight out as, "Parse arguments based on docstrings," I doubt it would have been nearly as memorable.
Re:Challenge: Implement CLI interface like that?
by moe on Sunday June 17, 2012 @07:56AM
(#4122751)
Ah, that's great!
But I'd strongly vote for making it possible to annotate multiple functions and merging their respective doc-strings smartly.
I don't think you'd want to express the entire syntax-tree of a reasonably complex program (e.g. 'git') in a single doc-string. Not only would that turn into a mess, but you'd also lose modularity. I.e. subcommands often need to be dynamically generated (e.g. depending on loaded modules) and not all subcommands may be available at all times.
Re:Challenge: Implement CLI interface like that?
by halst on Sunday June 17, 2012 @08:03AM
(#4122769)
I'm also a fan of idea of using function-docstrings for separate subcommand help-screens. Problems: (1) exact API, (2) how to do that in non-python implementations. You (and everyone) is very welcome to suggest APIs for that in issues:
https://github.com/docopt/docopt/issues
Re:Challenge: Implement CLI interface like that?
by lubutu on Sunday June 17, 2012 @12:10PM
(#4123191)
The docopt documentation suggests that a lone "--", signifying the end of the command-line flags, is only supported if "[--]" is added explicitly to the syntax string. In my opinion this is a mistake, and may even break POSIX XBD §12 [1]. I would seriously recommend the authors support it by default.
Re:Challenge: Implement CLI interface like that?
by andreyvit on Sunday June 17, 2012 @09:37AM
(#4122906)
Ouch, and I implemented https://github.com/andreyvit/dreamopt.js only a few months ago. Similar idea, but yours is better. (Not sure how you deal with type coercion and the like, but I guess it's not too hard to figure out.)
Re:Challenge: Implement CLI interface like that?
by rcthompson on Sunday June 17, 2012 @04:28PM
(#4123729)
I've found Plac[1] to be a suitably terse and DRY method of building command-line interfaces. Basically, you write a Python function where each argument to the function becomes either an option, flag, or positional argument on the command line. It's one "line" to define the function's arguments (which might be split on multiple lines due to length, but it's just the function's argument list), plus one "line" to annotate each argument with a type, single-letter abbreviation, docstring, etc. (which might be longer than one line if the docstring is extra long). The "type" of an argument is any function that takes a string and returns anything, so you can for example have a function that parses and returns a comma-separated list of numbers as a Python list of floats. I think Plac supports subcommands, but I haven't used it that way.
If you want to see some examples of real-world usage of Plac, here are some examples from my own projects:
Re:Challenge: Implement CLI interface like that?
by smoyer on Sunday June 17, 2012 @07:45AM
(#4122730)
Docopt looks like a useful library, but I'd be interested to see how intelligent the "help" parsing is when faced with slight variations in the format.
Using Commons-CLI in Java actually goes the opposite direction and if can be reasonably terse (one line per parameter or option) but it's also got to be wrapped in a class and have the rest of the Java boilerplate (a main method to execute, etc).
Re:Challenge: Implement CLI interface like that?
by halst on Sunday June 17, 2012 @08:17AM
(#4122798)
When the DSL (http://docopt.org/) was designed, the main goal was just to formalise that pattern-language used for decades in man pages and `--help` screens. So variations that are conventional (such as `UPPER-CASE` for arguments or `<angular-brackets>` for arguments) are supported.
Re:Challenge: Implement CLI interface like that?
by boris on Monday June 18, 2012 @06:35AM
(#4125767)
The question, of course, is whether it will scale to more complex cases with more elaborate option documentation (i.e., multiple paragraphs, formatting, short version for usage, extended version for man/html, etc).
For C++ there is the CLI compiler that implements a similar idea (i.e., uses a DSL) but instead of using the usage itself as a specification, it is based on the class-with-members abstraction. While the result is not as terse, it is quite a bit more flexible. Plus it allows you to specify option type (i.e., int, double, string, etc).
From a single interface specification CLI will generate C++ parsers, usage printing code, man pages, and html pages. Here is an example of a real-world interface that is handled with CLI:
Users can't name their ships 'new' or 'shoot' and you can't safely add more 'ship something' commands in new versions as you risk colliding with some user's ship name.
You could try to warn of such conflicts, but that sounds like a lot of work... :)
Re:Challenge: Implement CLI interface like that?
by bajsejohannes on Sunday June 17, 2012 @05:11PM
(#4123849)
Very nice! And especially clever that the DSL is the usage help we all know and love. I'm never happy about the amount of code normally required to write these.
One nitpick is that there is still some repetition: "naval_fate", and well as the long options are repeated. Granted, there might be ways around that which I haven't discovered yet.
Re:Challenge: Implement CLI interface like that?
by halst on Monday June 18, 2012 @03:06PM
(#4127963)
About long options repeated: you can either specify "[options]" shortcut in a pattern in order not to put all options in that pattern, or you can have all options listed in the pattern--then you can avoid having them in option description.
About repeating program's name (say "naval_fate"), you can do:
Re:Challenge: Implement CLI interface like that?
by bitdiffusion on Sunday June 17, 2012 @09:36AM
(#4122904)
If you are looking for something like this for .NET, "synoptic" can generate cli-usage help in a similar format based on your methods/classes complete with defaults, examples etc: https://github.com/bitdiff/synoptic (disclaimer: it's my companies' project)
It should be relatively easy to update it to work with 0.4; if you can make it work with 0.4 it would be great if you make a pull request to the project above.
Given the elegance of that very solution I think this marketing stunt is entirely unneeded and actually harmful; it's confusing and you miss out on getting a descriptive headline such as "Generate OptParser from code comment!".
That said... Brilliant idea!
I'm definitely trying out docopt for my next project.
And I have a counter-challenge for you:
How about making docopt work with nested commands? I.e. multiple methods could have a docopt-style comment and they would smartly merge to enable usages such as "mygit remote show --help", where 'show' is a subcommand of 'remote', with its own set of parameters and a matching help-page.
If you can work that one out then docopt could become the defacto standard for generating even complex OptParsers.
I wanted to improve on presentation, since my last post: http://news.ycombinator.com/submitted?id=halst
Great idea, great presentation!
Only thing different might be instead of giving the solution on that page itself - a hyperlink to the solution which takes you to docopt.org landing page
If I had just seen it presented straight out as, "Parse arguments based on docstrings," I doubt it would have been nearly as memorable.
Making possible several help-screens for different commands is on it's way. The only stopper—deciding on API: https://github.com/docopt/docopt/issues/17
But I'd strongly vote for making it possible to annotate multiple functions and merging their respective doc-strings smartly.
I don't think you'd want to express the entire syntax-tree of a reasonably complex program (e.g. 'git') in a single doc-string. Not only would that turn into a mess, but you'd also lose modularity. I.e. subcommands often need to be dynamically generated (e.g. depending on loaded modules) and not all subcommands may be available at all times.
[1]: http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_...
Exactly one. Unless, of course, it's in some funny language that mixes syntax with presentation ;)
Never used much of the docopt module, maybe I should spend a couple hours with it. Last time I saw it, it didn't appealed to me for some reason...
http://apenwarr.ca/log/?m=201111
Had you seen that before?
Also, I love it; it's taking DRY to its necessary conclusion.
http://search.cpan.org/~fangly/Getopt-Declare-1.14/lib/Getop...
If you want to see some examples of real-world usage of Plac, here are some examples from my own projects:
https://github.com/DarwinAwardWinner/intemp/blob/master/inte...
https://github.com/DarwinAwardWinner/mergesam/blob/master/me...
https://github.com/DarwinAwardWinner/splitloci/blob/master/s...
https://github.com/DarwinAwardWinner/fastqident/blob/master/...
[1] http://plac.googlecode.com/hg/doc/plac.html
Using Commons-CLI in Java actually goes the opposite direction and if can be reasonably terse (one line per parameter or option) but it's also got to be wrapped in a class and have the rest of the Java boilerplate (a main method to execute, etc).
Perhaps I'll try it on my next NodeJS project.
Take an example:
2 commands, 3 arguments, 5 options: in only 3 lines of DSL.Take a look at more examples: https://github.com/docopt/docopt/tree/master/examples
For C++ there is the CLI compiler that implements a similar idea (i.e., uses a DSL) but instead of using the usage itself as a specification, it is based on the class-with-members abstraction. While the result is not as terse, it is quite a bit more flexible. Plus it allows you to specify option type (i.e., int, double, string, etc).
From a single interface specification CLI will generate C++ parsers, usage printing code, man pages, and html pages. Here is an example of a real-world interface that is handled with CLI:
http://codesynthesis.com/products/odb/doc/odb.xhtml
The project page is here:
http://codesynthesis.com/projects/cli/
Note that there is a conflict between the subcommands in the example:
Users can't name their ships 'new' or 'shoot' and you can't safely add more 'ship something' commands in new versions as you risk colliding with some user's ship name.You could try to warn of such conflicts, but that sounds like a lot of work... :)
One nitpick is that there is still some repetition: "naval_fate", and well as the long options are repeated. Granted, there might be ways around that which I haven't discovered yet.
About repeating program's name (say "naval_fate"), you can do:
I've been looking for an excuse to use it.
It should be relatively easy to update it to work with 0.4; if you can make it work with 0.4 it would be great if you make a pull request to the project above.
We have just started to port to Ruby and Lua. All ports live under `docopt` organization on GitHub: https://github.com/docopt
You are very welcome to help us out with Ruby, Lua, and your favorite language :-).