www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - D port of docopt

reply "Bob Tolbert" <bob tolbert.org> writes:
In order to learn D, I've worked up a port of the docopt
commandline parser (original in Python http://docopt.org).

https://github.com/rwtolbert/docopt.d

Since this is my first code in D, I apologize in advance for the
mix if Python and C++ idioms. Since this is ported from Python,
with the intention of staying compatible with future Python
versions, some of that is expected, but I look for this as an
chance to learn more about D.

It is also a pretty useful way to write commandline interfaces.
The included example that mimics the git CLI is pretty impressive.

This is also my first submission as a dub project, so hopefully I
got that right as well.

Still needs more tests ported from Python, but it does pass the
entire functional test suite for the current Python version.

Regards,
Bob
Jun 15 2014
next sibling parent reply "Soulsbane" <paul acheronsoft.com> writes:
Thanks for this. Have played with it a whole lot yet but it looks 
like it will work better for me than getopt does.

Thanks again.
Jun 15 2014
parent "Bob Tolbert" <bob tolbert.org> writes:
On Monday, 16 June 2014 at 00:40:25 UTC, Soulsbane wrote:
 Thanks for this. Have played with it a whole lot yet but it 
 looks like it will work better for me than getopt does.
Hope it works for you. Let me know if you have questions. While there are most likely cases of some command line interface it can't do, I continue to be impressed with all that it does do. I need to port the rest of the examples over from Python, but in reality they are just a big string and a bit of code to call the parser. Bob
Jun 15 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 15/06/14 19:35, Bob Tolbert wrote:
 In order to learn D, I've worked up a port of the docopt
 commandline parser (original in Python http://docopt.org).

 https://github.com/rwtolbert/docopt.d

 Since this is my first code in D, I apologize in advance for the
 mix if Python and C++ idioms. Since this is ported from Python,
 with the intention of staying compatible with future Python
 versions, some of that is expected, but I look for this as an
 chance to learn more about D.

 It is also a pretty useful way to write commandline interfaces.
 The included example that mimics the git CLI is pretty impressive.

 This is also my first submission as a dub project, so hopefully I
 got that right as well.

 Still needs more tests ported from Python, but it does pass the
 entire functional test suite for the current Python version.
Pretty cool idea. Are you aware of that in D you can, at compile time, parse the doc string and generate a command line parser for that particular documentation. Looking at the git example [1], it seems a bit complicated and verbose to use after parsing. To determine which arguments was passed to the application. [1] https://github.com/rwtolbert/docopt.d/blob/master/examples/git/gitD.d -- /Jacob Carlborg
Jun 15 2014
next sibling parent "Colin" <grogan.colin gmail.com> writes:
On Monday, 16 June 2014 at 06:51:41 UTC, Jacob Carlborg wrote:
 On 15/06/14 19:35, Bob Tolbert wrote:
 In order to learn D, I've worked up a port of the docopt
 commandline parser (original in Python http://docopt.org).

 https://github.com/rwtolbert/docopt.d

 Since this is my first code in D, I apologize in advance for 
 the
 mix if Python and C++ idioms. Since this is ported from Python,
 with the intention of staying compatible with future Python
 versions, some of that is expected, but I look for this as an
 chance to learn more about D.

 It is also a pretty useful way to write commandline interfaces.
 The included example that mimics the git CLI is pretty 
 impressive.

 This is also my first submission as a dub project, so 
 hopefully I
 got that right as well.

 Still needs more tests ported from Python, but it does pass the
 entire functional test suite for the current Python version.
Pretty cool idea. Are you aware of that in D you can, at compile time, parse the doc string and generate a command line parser for that particular documentation. Looking at the git example [1], it seems a bit complicated and verbose to use after parsing. To determine which arguments was passed to the application. [1] https://github.com/rwtolbert/docopt.d/blob/master/examples/git/gitD.d
Im actually in the middle of writing this very thing :) My docopt parser builds a class (using string mixins) depending on what fields are required from the help text, and then returns a type of that class at run time. It's not ready for prime time yet though, so havent uploaded it. The idea was to have the interface look like: auto doc = docopt!(HelpText String)(args);
Jun 16 2014
prev sibling next sibling parent reply "Bob Tolbert" <Bob tolbert.org> writes:
On Monday, 16 June 2014 at 06:51:41 UTC, Jacob Carlborg wrote:
 Pretty cool idea. Are you aware of that in D you can, at 
 compile time, parse the doc string and generate a command line 
 parser for that particular documentation.
I wondered about that, after looking at the compile-time regex stuff, which is pretty darn cool.
 Looking at the git example [1], it seems a bit complicated and 
 verbose to use after parsing. To determine which arguments was 
 passed to the application.

 [1] 
 https://github.com/rwtolbert/docopt.d/blob/master/examples/git/gitD.d
While that is true, I'd argue that if you are writing an app with a command line that complicated, then you have your work cut out for you no matter what the system is you use. Bob
Jun 16 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 16/06/14 15:31, Bob Tolbert wrote:

 While that is true, I'd argue that if you are writing an app with
 a command line that complicated, then you have your work cut out
 for you no matter what the system is you use.
It would be nice to see a simpler example of how to use the library after parsing. Most examples now just do "writeln(arguments);". -- /Jacob Carlborg
Jun 16 2014
parent "Bob Tolbert" <bob tolbert.org> writes:
On Tuesday, 17 June 2014 at 06:29:14 UTC, Jacob Carlborg wrote:
 On 16/06/14 15:31, Bob Tolbert wrote:

 While that is true, I'd argue that if you are writing an app 
 with
 a command line that complicated, then you have your work cut 
 out
 for you no matter what the system is you use.
It would be nice to see a simpler example of how to use the library after parsing. Most examples now just do "writeln(arguments);".
So I agree it would be nice to have a more real example. I am open to suggestions or working with someone that needs a CLI update. I thought about a small version of grep or ack written in D, but not sure if that is a waste of time when there might be a more interesting need for something new or different. Bob
Jun 17 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 16 June 2014 at 06:51:41 UTC, Jacob Carlborg wrote:
 Pretty cool idea. Are you aware of that in D you can, at 
 compile time, parse the doc string and generate a command line 
 parser for that particular documentation.
I don't think it gives any advantage here :) docopt looks cool, though my I'd prefer something that works other way around - automatically generates argument parsing code and help messages from aggregate that represents configuration and/or CLI API (with help of few UDA).
Jun 16 2014
next sibling parent reply Robert Schadek via Digitalmars-d-announce writes:
On 06/16/2014 11:11 PM, Dicebot via Digitalmars-d-announce wrote:
 On Monday, 16 June 2014 at 06:51:41 UTC, Jacob Carlborg wrote:
 Pretty cool idea. Are you aware of that in D you can, at compile
 time, parse the doc string and generate a command line parser for
 that particular documentation.
I don't think it gives any advantage here :) docopt looks cool, though my I'd prefer something that works other way around - automatically generates argument parsing code and help messages from aggregate that represents configuration and/or CLI API (with help of few UDA).
+1 I could use reviews for this PR https://github.com/D-Programming-Language/phobos/pull/2072
Jun 16 2014
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 16 June 2014 at 21:21:47 UTC, Robert Schadek via 
Digitalmars-d-announce wrote:
 On 06/16/2014 11:11 PM, Dicebot via Digitalmars-d-announce 
 wrote:
 On Monday, 16 June 2014 at 06:51:41 UTC, Jacob Carlborg wrote:
 Pretty cool idea. Are you aware of that in D you can, at 
 compile
 time, parse the doc string and generate a command line parser 
 for
 that particular documentation.
I don't think it gives any advantage here :) docopt looks cool, though my I'd prefer something that works other way around - automatically generates argument parsing code and help messages from aggregate that represents configuration and/or CLI API (with help of few UDA).
+1 I could use reviews for this PR https://github.com/D-Programming-Language/phobos/pull/2072
Sure, will have a look. Though I don't see how what I propose can fit into Phobos as std.getopt, it is something for an alternative module. The way I see it, getopt will be more suitable for small simple CLI implementations and that imaginary module - for programs with huge amount of options and complicated nested commands. Something like this: help(" Header used to describe this configuration option block ") struct CLI { descr("Some optional parameter") Optional!int param1; descr("Mandatory parameter") int param2; struct Command { string nested_param; void opCall(ref A outer) { // called after parsing relevant args into this instance } } Command command; } void main(string[] args) { Config config; parseCLI!config(args); // ./app --param2 42 command --nested_param yay }
Jun 16 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 16/06/14 23:11, Dicebot wrote:

 I don't think it gives any advantage here :)

 docopt looks cool, though my I'd prefer something that works other way
 around - automatically generates argument parsing code and help messages
 from aggregate that represents configuration and/or CLI API (with help
 of few UDA).
Same here. I use the argument parser in Tango [1], which I think works well. I have extended the one in Tango to support generating the help message, and some other stuff as well [2]. [1] http://siegelord.github.io/Tango-D2/tango.text.Arguments.html [2] https://github.com/jacob-carlborg/mambo/tree/master/mambo/arguments -- /Jacob Carlborg
Jun 16 2014
prev sibling next sibling parent "Colin" <grogan.colin gmail.com> writes:
On Sunday, 15 June 2014 at 17:35:59 UTC, Bob Tolbert wrote:
 In order to learn D, I've worked up a port of the docopt
 commandline parser (original in Python http://docopt.org).

 https://github.com/rwtolbert/docopt.d

 Since this is my first code in D, I apologize in advance for the
 mix if Python and C++ idioms. Since this is ported from Python,
 with the intention of staying compatible with future Python
 versions, some of that is expected, but I look for this as an
 chance to learn more about D.

 It is also a pretty useful way to write commandline interfaces.
 The included example that mimics the git CLI is pretty 
 impressive.

 This is also my first submission as a dub project, so hopefully 
 I
 got that right as well.

 Still needs more tests ported from Python, but it does pass the
 entire functional test suite for the current Python version.

 Regards,
 Bob
Good going bob, I've actually been attempting to write this for the past while too :) Looks good, and should be very useful to the community!
Jun 16 2014
prev sibling next sibling parent reply =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= <sludwig rejectedsoftware.com> writes:
Am 15.06.2014 19:35, schrieb Bob Tolbert:
 In order to learn D, I've worked up a port of the docopt
 commandline parser (original in Python http://docopt.org).

 https://github.com/rwtolbert/docopt.d

 Since this is my first code in D, I apologize in advance for the
 mix if Python and C++ idioms. Since this is ported from Python,
 with the intention of staying compatible with future Python
 versions, some of that is expected, but I look for this as an
 chance to learn more about D.

 It is also a pretty useful way to write commandline interfaces.
 The included example that mimics the git CLI is pretty impressive.

 This is also my first submission as a dub project, so hopefully I
 got that right as well.

 Still needs more tests ported from Python, but it does pass the
 entire functional test suite for the current Python version.

 Regards,
 Bob
That's a really nice approach. Makes me wonder if there is a generic bash completion script for this kind of help screen format(?). One thing that would be nice is support for multiple help screens (e.g. one per command). For DUB [1] (or GIT) for example there is one main help screen that lists all commands along with common options and then one help screen per command that lists the individual arguments, options and a summary of what the command does. But maybe for such more complex CLIs it starts to be more efficient to use a programmatic approach. For a statically typed language like D it would also be interesting to investigate the possibility to encode and validate the type of each option or positional argument instead of using a generic string type. [1]: http://code.dlang.org/
Jun 16 2014
parent reply "Bob Tolbert" <bob tolbert.org> writes:
On Monday, 16 June 2014 at 17:59:13 UTC, Sönke Ludwig wrote:
 Am 15.06.2014 19:35, schrieb Bob Tolbert:
 One thing that would be nice is support for multiple help 
 screens (e.g. one per command). For DUB [1] (or GIT) for 
 example there is one main help screen that lists all commands 
 along with common options and then one help screen per command 
 that lists the individual arguments, options and a summary of 
 what the command does. But maybe for such more complex CLIs it 
 starts to be more efficient to use a programmatic approach.
if you have a look at the gitD examples, they do just this. If you do gitD --help you get the general help for gitD, but if you do gitD push -h or gitD help push you get the help for the sub-command "push" so doing this with 'dub' would be pretty simple. And you don't have to use external sub-commands either. You can parse the basic args with the general doc string and then based on the sub-command chosen, re-parse with the options specific to that sub module. I haven't looked at the dub source code, but I'd be happy to help sketch out how this might work there specifically. Bob
Jun 16 2014
parent =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= <sludwig rejectedsoftware.com> writes:
Am 16.06.2014 20:19, schrieb Bob Tolbert:
 On Monday, 16 June 2014 at 17:59:13 UTC, Sönke Ludwig wrote:
 Am 15.06.2014 19:35, schrieb Bob Tolbert:
 One thing that would be nice is support for multiple help screens
 (e.g. one per command). For DUB [1] (or GIT) for example there is one
 main help screen that lists all commands along with common options and
 then one help screen per command that lists the individual arguments,
 options and a summary of what the command does. But maybe for such
 more complex CLIs it starts to be more efficient to use a programmatic
 approach.
if you have a look at the gitD examples, they do just this. If you do gitD --help you get the general help for gitD, but if you do gitD push -h or gitD help push you get the help for the sub-command "push" so doing this with 'dub' would be pretty simple. And you don't have to use external sub-commands either. You can parse the basic args with the general doc string and then based on the sub-command chosen, re-parse with the options specific to that sub module. I haven't looked at the dub source code, but I'd be happy to help sketch out how this might work there specifically. Bob
Ah OK, nice. I was somehow under the impression that all options would have to match exactly with what is in the help text. But nesting works fine like this of course. As for DUB, it probably doesn't make sense to rewrite the CLI now for no particular reason. Its command line interface maybe isn't as concise as a docopt based one, but still does pretty well and also has a few possible advantages, such as direct type validation and automatic assembly of help pages with nested options (the help text includes both, global and command specific options, as well as possible intermediate level options that are shared among several commands). Currently, everything is in a single module (the "framework" and all commands), but that is supposed to be broken up into multiple modules in the future: https://github.com/D-Programming-Language/dub/blob/master/source/dub/commandline.d
Jun 16 2014
prev sibling parent Leandro Lucarella <luca llucax.com.ar> writes:
Bob Tolbert, el 15 de June a las 17:35 me escribiste:
 In order to learn D, I've worked up a port of the docopt
 commandline parser (original in Python http://docopt.org).
 
 https://github.com/rwtolbert/docopt.d
THANK YOU. I love docopt!
 Since this is my first code in D, I apologize in advance for the
 mix if Python and C++ idioms. Since this is ported from Python,
 with the intention of staying compatible with future Python
 versions, some of that is expected, but I look for this as an
 chance to learn more about D.
 
 It is also a pretty useful way to write commandline interfaces.
 The included example that mimics the git CLI is pretty impressive.
 
 This is also my first submission as a dub project, so hopefully I
 got that right as well.
 
 Still needs more tests ported from Python, but it does pass the
 entire functional test suite for the current Python version.
 
 Regards,
 Bob
-- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- This is what you get, when you mess with us.
Jun 16 2014