10 January 2012

Awesome CLI gem: Commandable

Ever wanted to drive your ruby code with a CLI?  Well, the commandable gem makes it easy.

At first, I struggled with OptionParser in the stdlib, but I had to duplicate my option handling across CLI code and method invocation.  Then OptionParser didn't handle required parameters at all, requiring me to do required parameters in a non-DRY way.   Also, OptionParse doesn't do sub-commands, git-style, which I needed for the new git plugin I'm working on.

When I saw the pickled_optparse gem (from Mike Bethany), it appeared to solve the missing 'required parameter' feature.  And the subcommand gem seemed to allow for subcommands with their own options, git-style.  However, the duplication across option definition and method invocation was still present.  And even subcommand required you to hook up the command to the class/method that needed to be called.

Finally I found that the author of pickled_optparse had totally rethought CLI in ruby with his commandable gem.  And I really like what he did.

Now there is no real additional logic AT ALL in order to hook your ruby class up to the command line.  Now my option handling code will be in the place it belongs, in the code that is doing the command that I invoked from the command line.

The main awesomeness here is that commandable pushes the CLI code into the appropriate place in your ruby class -- it makes it hard to scatter CLI code all over the place.

My only beef with the gem are the following points:

  • it comes with colors enabled by default (unusual for a CLI)
  • it clears the screen by default when displaying help (when colors are enabled, very unusual and annoying for a CLI)
  • it appears to be hard to do global options like: "cmd --global subcommand [args]"
  • there is no support for parsing command CLI-style options into ruby hashes, but this is a minor nit, because that's what OptionParser is for, and it's easy to use inside the method

I fixed a problem where the screen was cleared even if you disabled colors, and I've pushed it up to my fork.

Here is my hello world that shows commandable in action:

And here's the output for a few representative cases:

No comments:

Post a Comment