久しぶりに Thor をちゃんと使って、それで結構調べたので未来の自分のためにメモしておきます。バージョンは 0.19.1
です。
すべての基本形
lib/foo.rb
require 'thor'
class Foo < Thor
desc 'say', 'say hello'
method_option :dry_run, type: :boolean, default: false
def say
puts "Say hello!" unless options[:dry_run]
end
end
bin/foo
#!/usr/bin/env ruby
require 'foo'
Foo.start
コマンドのエイリアスを登録したい
-
map
つかう - なお、Thorの機能で下記のような場合
foo s
でfoo say
のエイリアスに自動でなる
class Foo < Thor
desc 'say', 'say hello'
def say
puts "Say hello!" unless options[:dry_run]
end
map 'talk' => 'say'
end
サブコマンドを登録したい
- ところでサブコマンドが出てきたら、モジュールを作ってくくっておくと分かりやすくなると思った
module BarCLI
class Sub < Thor
desc 'say', 'Say sub'
def say; ...; end
end
class Cli < Thor
subcommand 'sub', Sub
end
end
# barcli sub say => ...
デフォルトで呼ばれるコマンドを指定したい
-
default_task
使う
module BarCli
class Build < Thor
desc 'all', 'Build all app'
def all
#....
end
default_task :all
end
end
あるコマンドから別のコマンド呼ぶ
- 色々省略できるがややこしいので、以下の公式を覚える:
# 第一引数: Thor クラスのサブクラスで、サブコマンドを定義したやつ
# 第二引数: 配列で、コマンドに実際渡す引数。オプション系除く
# 第三引数: オプションをHashで。親のオプションを丸っと引き継ぐなら省略可能。それ以外微妙に加工するのなら適宜 `Hash#merge` とか使う
invoke SomeSub, [:do_hoge], options.merge(:bar => foobar)
全サブコマンドでの共通オプションの指定+共通処理の書き方
- ややHackyだけど以下の要領で
invoke_command
を上書けば行ける - コマンドでないパブリックメソッドの再定義なので、
no_commands
で囲まないと警告が出る
module BarCLI
class Cli < Thor
# verboseを共通に
class_option :verbose, type: :boolean, aliases: "-V", default: false
subcommand('hoge', Hoge)
subcommand('fuga', Fuga)
#....
no_commands do
def invoke_command(command, *args)
# モジュールメソッドになっているロガーのレベルをoptionで設定
BarCLI.logger.level = options[:verbose] ? Logger::DEBUG : Logger::INFO
super # 必ず呼ぶんだよ
end
end
end
end
# あとはサブコマンドを定義する