librelist archives

« back to archive

Arglist parsing

Arglist parsing

From:
Brian Marick
Date:
2013-01-18 @ 17:06
Is there a convention/library for arglist parsing in the plugin ecosystem?
I didn't find one, so I wrote my own. I'm tempted to claim that the right 
syntax for lein plugin architectures is this:

% lein deps :tree
% lein midje namespace1 namespace 2 :config config-file1 config-file2

That is, more like the DOS convention than the UNIX one:
* main arguments come first
* switches come later and are keywords instead of -/--
* switches can take multiple arguments themselves.

This turns out to be easy to parse. (If you think about it, the Unix style
is an implementation artifact: character comparisons in C are easier than 
string comparisons, partitioning an array is a big deal, so you're rather 
use a `for(;**argv=='-';argc++)` loop. Clojure doesn't have those 
limitations.)

It also allows the user to have consistent expectations for plugin 
arguments and the Clojure code that implements them. For example, 
autotesting through `lein midje` looks like this:

% lein midje :autotest
% lein midje :autotest dir1 dir2

That's not identical to the in-repl `autotest` call, which looks like this:

user=> (autotest)
user=> (autotest :dirs "dir1" "dir2" :interval 500)

… but something carries over.

I don't have a full-fledged argument parser - I only wrote what I needed -
but if anyone wants to build on it, it's here:

https://github.com/marick/Midje/blob/master/test/midje/parsing/t_arglists.clj#L33
https://github.com/marick/Midje/blob/master/src/midje/parsing/arglists.clj#L28

I'd offer to beef it up, but I've been spending way too much time on Midje
1.5 as it is.

--------
Occasional consulting on programming technique
Contract programming in Ruby and Clojure
Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

Re: [leiningen] Arglist parsing

From:
Hugo Duncan
Date:
2013-01-18 @ 17:54
Brian Marick <marick@exampler.com> writes:

> Is there a convention/library for arglist parsing in the plugin 
ecosystem? I didn't find one, so I wrote my own. I'm tempted to claim that
the right syntax for lein plugin architectures is this:

I've been using tools.cli [1] in lein-ritz.

    lein ritz 4006 --log-level trace


[1] https://github.com/clojure/tools.cli

Re: [leiningen] Arglist parsing

From:
Brian Marick
Date:
2013-01-18 @ 18:44
On Jan 18, 2013, at 11:54 AM, Hugo Duncan <hugo@hugoduncan.org> wrote:
> I've been using tools.cli [1] in lein-ritz.
> [1] https://github.com/clojure/tools.cli


Sigh. Even knowing that exists, I can't find it anywhere in clojure.org, 
clojure-docs.org, or clojure-doc.org. Am I just exceptionally stupid? 

--------
Occasional consulting on programming technique
Contract programming in Ruby and Clojure
Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

Re: [leiningen] Arglist parsing

From:
Sean Corfield
Date:
2013-01-18 @ 23:43
The (not very helpful) auto-generated documentation:
http://clojure.github.com/tools.cli/

On Fri, Jan 18, 2013 at 10:44 AM, Brian Marick <marick@exampler.com> wrote:
>
> On Jan 18, 2013, at 11:54 AM, Hugo Duncan <hugo@hugoduncan.org> wrote:
>> I've been using tools.cli [1] in lein-ritz.
>> [1] https://github.com/clojure/tools.cli
>
>
> Sigh. Even knowing that exists, I can't find it anywhere in clojure.org,
clojure-docs.org, or clojure-doc.org. Am I just exceptionally stupid?
>
> --------
> Occasional consulting on programming technique
> Contract programming in Ruby and Clojure
> Latest book: /Functional Programming for the Object-Oriented Programmer/
> https://leanpub.com/fp-oo
>



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Re: [leiningen] Arglist parsing

From:
Jake McCrary
Date:
2013-01-19 @ 05:20
The readme is much better documentation then the auto-generated docs.

https://github.com/clojure/tools.cli/

Gaz has also written a blog post about it:
http://blog.gaz-jones.com/2012/02/03/clojure_command_line_apps.html. I
wrote one for it prior to becoming a contrib library, but it is
significantly out of date now.


On Fri, Jan 18, 2013 at 5:43 PM, Sean Corfield <seancorfield@gmail.com>wrote:

> The (not very helpful) auto-generated documentation:
> http://clojure.github.com/tools.cli/
>
> On Fri, Jan 18, 2013 at 10:44 AM, Brian Marick <marick@exampler.com>
> wrote:
> >
> > On Jan 18, 2013, at 11:54 AM, Hugo Duncan <hugo@hugoduncan.org> wrote:
> >> I've been using tools.cli [1] in lein-ritz.
> >> [1] https://github.com/clojure/tools.cli
> >
> >
> > Sigh. Even knowing that exists, I can't find it anywhere in clojure.org,
> clojure-docs.org, or clojure-doc.org. Am I just exceptionally stupid?
> >
> > --------
> > Occasional consulting on programming technique
> > Contract programming in Ruby and Clojure
> > Latest book: /Functional Programming for the Object-Oriented Programmer/
> > https://leanpub.com/fp-oo
> >
>
>
>
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
> World Singles, LLC. -- http://worldsingles.com/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)
>

Re: [leiningen] Arglist parsing

From:
Phil Hagelberg
Date:
2013-01-18 @ 18:36
Brian Marick writes:

> Is there a convention/library for arglist parsing in the plugin
> ecosystem? I didn't find one, so I wrote my own. I'm tempted to claim
> that the right syntax for lein plugin architectures is this:

The only nontrivial[1] argument parsing in Leiningen itself occurs in the
`run` task, which can either take a list of args to pass on to -main or
the namespace of -main itself. In that case it uses "-m" to signal the
second case, but I believe this is the only place in Leiningen that
accepts dashes rather than keywords. So perhaps I'll change that to
accept either in the interests of consistency.

The intention of Leiningen tasks is not to mirror Unix commands or DOS
or whatever but simply to act like Clojure function invocations. The
same rules apply in terms of how to structure your arglists. Keep
optional & rest args at the end. Things at the front should remain
consistent across arities. Don't overload the same function to do
different things. Use higher-order tasks when appropriate. Avoid
ambiguity (cases where the same nth argument can be interpreted two
different ways) whenever possible.

-Phil

[1] I'm defining nontrivial here as cases where the position of the
argument isn't enough to determine how it is interpreted.