Polydocopt: docopt for commands with subcommands

Nowadays CLI tools have very complicated command lines, often with multiple subcommands that make it hard to describe them using traditional tools and libraries.

Me, I love docopt but it just doesn’t scale.

Thus: polydocopt a docopt approach to commands with subcommands.

Example:

require "polydocopt"

struct Hello < Polydocopt::Command
  @name = "hello"
  @@doc = <<-HELP
Says hello to the world

Usage:
  say hello [-u] [-p PLANET]

Options:
  -h --help     Show this screen
  -u --upper    Uppercase the output
  -p PLANET     Greet a planet [default: world]
HELP

  def run : Int32
    greeting = "hello #{options["-p"]}"
    greeting = greeting.upcase if options["--upper"]
    puts greeting
    0
  end
end

Hello.register()

And your CLI now works like this, with subcommands having totally different options, if needed:

> ./say
Usage:
  say help [COMMAND]
  say hello                   Says hello to the world
  say bye                     Says bye to the world

> ./say help hello
Says hello to the world

Usage:
  say hello [-u] [-p PLANET]

Options:
  -h --help     Show this screen
  -u --upper    Uppercase the output
  -p PLANET     Greet a planet [default: world]

> ./say help bye
Says bye to the world

Usage:
  say bye [-b] [-p PLANET]

Options:
  -h --help         Show this screen
  -b --backwards    Say it backwards
  -p PLANET         Greet a planet [default: world]

This library came out of the requirements of another personal project, so I am not sure if it’s of much use for others, but hopefully it is!

7 Likes

Awesome, that’s very cool!

I use docopt for all of my Ruby scripts, but for Crystal I have just been using the standard library. So definitely going to give this a go next time I build something new.

If what you want is just docopt, all the docopt work is actually done in GitHub - chenkovsky/docopt.cr: docopt for crystal-lang (just in case, so you don’t get this dependency if you don’t need it :-D )

1 Like