概要
Thor は Ruby で CLI ツールを作成することができるライブラリです
今回は簡単な使い方を紹介します
環境
- macOS 10.15.6
- Ruby 2.7.1p83
- thor 1.0.1
インストール
bundle init
vim Gemfile
gem "thor"
bundle config path vendor
bundle install
Hello thor
とりあえず動作させてみましょう
Thor クラスを継承したクラス内でメソッドを定義するだけでそれを CLI から呼び出すことができます
また help コマンド時の説明も desc などの DSL を使うことで定義できます
require "thor"
class MyCLI < Thor
desc "hello NAME", "say hello to NAME"
def hello(name)
puts "Hello #{name}"
end
end
MyCLI.start(ARGV)
これで help を表示すると以下のように表示されます
bundle exec ruby app.rb help
Commands:
app.rb hello NAME # say hello to NAME
app.rb help [COMMAND] # Describe available commands or one specific command
hello メソッドを実行してみるとちゃんと実行されているのが確認できると思います
bundle exec ruby app.rb hello hawksnowlog
=> Hello hawksnowlog
可変長引数を受け取る
先程の例だと引数を 1 つ以上指定するとエラーになります
可変長にすることで引数をいくつでも受け取ることができるようになります
require "thor"
class MyCLI < Thor
desc "team NAME member1 member2", "show team NAME and members"
def team(name, *members)
puts "Team #{name}"
puts "Members #{members.join(',')}"
end
end
MyCLI.start(ARGV)
こんな感じで実行することができます
ruby app.rb team number 1 2 3 4
Team number
Members 1,2,3,4`
オプションを指定する
--hoge
のような感じでオプションを指定することができます
require "thor"
class MyCLI < Thor
desc "print NAME", "print NAME and optional age"
option :age
def print(name)
puts "Name #{name}"
puts "Age #{options[:age]}"
end
end
MyCLI.start(ARGV)
bundle exec ruby app.rb print hawksnowlog --age 10
クラスオプション
クラス内で共通のオプションを持たせたい場合は class_option
を使います
定義したすべてのメソッドでオプションを使うことができます
require "thor"
class MyCLI < Thor
class_option :verbose, :type => :boolean
desc "hello NAME", "say hello to NAME"
def hello(name)
puts "Hello #{name}"
puts "Bye!" if options[:verbose]
end
end
MyCLI.start(ARGV)
bundle exec ruby app.rb hello hawk --verbose
Long Description
help commad とすることで詳細を表示することができます
long_desc
を使います
require "thor"
class MyCLI < Thor
desc "hello NAME", "say hello to NAME"
long_desc <<-LONGDESC
\u001b[31maaaaaaaaaaaaaaaaaa\u001b[0m
bbbbbbbbbbbbbbbb
> $ bundle exec ruby app.rb hello "hawksnowlog"
LONGDESC
def hello(name)
puts "Hello #{name}"
end
end
MyCLI.start(ARGV)
ANSI カラーコードも使えました
bundle exec ruby app.rb help hello
サブコマンド
git remote add
や git remote remove
のようにサブコマンドを定義することもできます
例えば name
というコマンドに対するサブコマンドを定義したい場合は以下のようにします
subcommand
を使って更にサブコマンド用のクラスを定義する感じになります
require "thor"
class Show < Thor
desc "print", "Print my name"
def print
puts "hawksnowlog"
end
end
class MyCLI < Thor
desc "name SUBCOMMAND", "Operations for your name"
subcommand "name", Show
end
MyCLI.start(ARGV)
Thorfile
thor はタスクランナーとして使うこともできます
Thorfile というファイルに同じように実行したいコマンドを定義しておくと rake のようにタスクとして実行することができます
vim Thorfile
require "thor"
class Task < Thor
class << self
def exit_on_failure?
true
end
end
desc "hello NAME", "say hello to NAME"
def hello(name)
puts "Hello #{name}"
end
end
exit_on_failure?
はおまじないだと思ってください
これがないと Deprecation warning: Thor exit with status 0 on errors. To keep this behavior, you must define exit_on_failure? in Thor::Sandbox::Task
という警告が表示されてしまいます
タスクの一覧を確認する場合は thor -T
を使います
bundle exec thor -T
task
----
thor task:hello NAME # say hello to NAME
あとはタスクを指定して実行するだけです
こちらの使い方のほうが thor っぽいというか rake っぽくも使えるので良いかなと思います
bundle exec thor task:hello hawksnowlog
最後に
Ruby の thor を使って CLI ツールを作成する方法を紹介しました
引数の制御やオプション、サブコマンドなど必要な機能は一通り揃っているかなと思います
よくタスクランナーの使い方が紹介されているイメージですが元は CLI ビルドツールになります
0 件のコメント:
コメントを投稿