Делаю маленькую утилиту: читает лог Rails, вытаскивает запросы медленнее порога по строкам вида Completed 200 OK in 523ms и выводит топ. Пока одна команда и три опции, набросал на OptionParser:
require "optparse"
options = { threshold: 500, top: 10 }
OptionParser.new do |opts|
opts.banner = "Использование: slowlog [опции] ФАЙЛ"
opts.on("-t", "--threshold MS", Integer, "порог в мс") { |v| options[:threshold] = v }
opts.on("-n", "--top N", Integer, "сколько строк вывести") { |v| options[:top] = v }
opts.on("--json", "вывод в JSON") { options[:json] = true }
end.parse!
abort "Укажите файл лога" if ARGV.empty?
Работает, но везде пишут, что нормальные CLI делают на Thor. Стоит переделывать сейчас, пока кода мало?
Для одной команды OptionParser хватает с головой, и он в стандартной библиотеке, ноль зависимостей. Thor нужен, когда появляются подкоманды: slowlog top, slowlog stats, slowlog export. На OptionParser тогда начинается ручной разбор ARGV.shift и своя справка к каждой команде, а Thor делает это сам:
require "thor"
class Slowlog < Thor
def self.exit_on_failure? = true
desc "top FILE", "самые медленные запросы"
option :threshold, type: :numeric, default: 500
option :limit, type: :numeric, default: 10
def top(file)
puts "#{file}: порог #{options[:threshold]} мс, строк #{options[:limit]}"
end
end
Slowlog.start(ARGV)
Сейчас переделывать незачем, переедете, когда появится вторая команда.
ещё у OptionParser есть parse!(into: options), тогда значения сами ложатся в хэш без блоков