サブコマンドのあるCLIをThorで作る

gitとかvagrantみたいな一群の処理をサブコマンドとしてまとめたコマンドをスクリプトとして、rubyで書くとき、optparse(OptionParser)でもできるけどちょっと大変。

Thorを使うと、Thorのサブクラスを作ったらメソッドがそのままサブコマンドの処理になる。便利。

qiita.com

qiita.com

#! /usr/bin/env ruby
# mycommand.rb
require 'rubygems' # gemなのでこれが必要。
require 'thor'

Version = "0.0.1"

class MyCommand < Thor
  default_command :help

  map %w[--version -v] => :print_version
  desc "--version, -v", "print the version"
  def print_version
    puts "MyCommand CLI v.#{Version}"
  end

  desc 'hello', 'Hello'
  def hello(to='')
    puts "Hello #{to}"
  end

  desc 'hello-world', 'Hello World'
  def hello_world
    self.hello 'World'
  end

end

MyCommand.start(ARGV)
  • helpは自動定義される。default_commandに指定しておくと、サブコマンドを入れなかったらヘルプが表示される。
  • optparseでhelpと同じく自動定義されるバージョン表示は、上の例のように-v--versionを何かしらのサブコマンドの別名とすることで作れる。
  • 二語以上のサブコマンドは、たとえばmycommand.rb hello_worldではなくてmycommand.rb hello-worldとハイフンで繋ぎたいときものだが、素直にアンダースコア繋ぎのメソッドを定義すれば呼び出し時にThorの方で-を_に置き換えてくれる。(ドキュメントのどこにも書かれてないが、ソースを読んだらそういうことをやっている。)