概要
書籍 Build Awesome Command-Line Applications in Ruby2
章
Make Configration Easy
詳細
Command Suitesのように複数のコマンドを持つ場合、コマンドごとの引数やオプションの設定が必要です。
サンプル仕様
下記記事のサンプルをベースに設定を追加します。
Ruby | CLI | Be Easy to Use | Ruby | CLI | Thorを利用した使いやすいCommand suitインターフェース
http://d.hatena.ne.jp/tbpg/20140526/1401109675
サンプル設定ファイル
--- :commands: :firstname: 'upcase': false 'downcase': false :lastname: 'upcase': false 'downcase': false :fullname: 'upcase': false 'downcase': false :age: 'pretty_print': false
サンプルコード
require 'csv' require 'thor' require 'pp' require 'yaml' class PersonViewer < Thor CONFIG = 'personal.yml' package_name "person_viewer" VERSION = "0.0.1" PERSONALS = './personals.csv' UP_OPTIONS = {type: :boolean, aliases: '-u', desc: "文字を大文字にする"} DOWN_OPTIONS = {type: :boolean, aliases: '-d', desc: "文字を小文字にする"} class_option :help, type: :boolean, aliases: '-h', desc: 'ヘルプを表示します' class_option :version, type: :boolean, desc: 'バージョンを表示します' desc "firstname", "名前を表示します" option 'upcase', UP_OPTIONS option 'downcase', DOWN_OPTIONS def firstname opt = load_option_settings('firstname', options.to_h, 'upcase', 'downcase') print opt, "\n" read_csv.each do |row| row[:firstname] = row[:firstname].upcase if opt['upcase'] row[:firstname] = row[:firstname].downcase if opt['downcase'] puts row[:firstname] end end desc "find by firstname [FIRSTNAME]", "find by firstname [FIRSTNAME]" def find_by_firstname(text = '') target = read_csv.select { |row|row[:firstname] =~ /#{text}/ } pp target end desc "lastname", "名字を表示します" option 'upcase', UP_OPTIONS option 'downcase', DOWN_OPTIONS def lastname opt = load_option_settings('lastname', options.to_h, 'upcase', 'downcase') print opt, "\n" read_csv.each do |row| row[:lastname] = row[:lastname].upcase if opt['upcase'] row[:lastname] = row[:lastname].downcase if opt['downcase'] puts row[:lastname] end end desc "fullname", "フルネームを表示します" option 'upcase', UP_OPTIONS option 'downcase', DOWN_OPTIONS def fullname opt = load_option_settings('fullname', options.to_h, 'upcase', 'downcase') print opt, "\n" read_csv.each do |row| tmp_fullname = "#{row[:firstname]} #{row[:lastname]}" tmp_fullname = tmp_fullname.upcase if opt['upcase'] tmp_fullname = tmp_fullname.downcase if opt['downcase'] puts tmp_fullname end end desc "age", "年齢を表示します" option :pretty_print, {type: :boolean, aliases: '-p', desc: "人間向けの出力フォーマットにする"} def age opt = load_option_settings('age', options.to_h, 'pretty_print') print opt, "\n" if opt['pretty_print'] read_csv.each { |row|puts "#{row[:firstname]} #{row[:lastname]}は#{row[:age]}歳です" } else read_csv.each { |row|puts row[:age] } end end desc 'version', 'バージョンを表示します' def version puts VERSION end def self.banner(task, namespace = false, subcommand = true) super end private def read_csv CSV.table(PERSONALS) end def load_option_settings(command, opt, *marge_elements) options = YAML.load(File.read(CONFIG)) setting = options[:commands][command] marge_elements.each { |elm|setting[elm] ||= opt[elm] unless opt[elm].nil? } setting end end PersonViewer.start(ARGV)
サンプル出力
大文字変換設定有効
personal.yml
--- :commands: 'firstname': 'upcase': true 'downcase': false 'lastname': 'upcase': true 'downcase': false 'fullname': 'upcase': true 'downcase': false 'age': 'pretty_print': false
出力
$ ruby personal.rb fir DL is deprecated, please use Fiddle {"upcase"=>true, "downcase"=>false} KAZUO KEN ICHIRO $ ruby personal.rb fir -u DL is deprecated, please use Fiddle {"upcase"=>true, "downcase"=>false} KAZUO KEN ICHIRO $ ruby personal.rb fir -d DL is deprecated, please use Fiddle {"upcase"=>true, "downcase"=>true} kazuo ken ichiro $ ruby personal.rb last DL is deprecated, please use Fiddle {"upcase"=>true, "downcase"=>false} TANAKA SATO SUZUKI $ ruby personal.rb ful DL is deprecated, please use Fiddle {"upcase"=>true, "downcase"=>false} KAZUO TANAKA KEN SATO ICHIRO SUZUKI
年齢の pretty print を有効化
personal.yml
--- :commands: 'firstname': 'upcase': false 'downcase': false 'lastname': 'upcase': false 'downcase': false 'fullname': 'upcase': false 'downcase': false 'age': 'pretty_print': true
出力
$ ruby personal.rb a {"pretty_print"=>true} Kazuo Tanakaは34歳です Ken Satoは54歳です Ichiro Suzukiは45歳です $ ruby personal.rb a -p {"pretty_print"=>true} Kazuo Tanakaは34歳です Ken Satoは54歳です Ichiro Suzukiは45歳です