With Thor one can use method_option to set the options for a particular task. To set the options for all tasks in a class one can use class_option
. But what about t
I had the same problem and I used what N.N. answered. But I found some problems:
If you want to share more than one option as in the example, it doesn't work very well. Imagine you want to share :value
between task2 and task3. You could create another shared_options
or you could create an array with the shared options and access it with the shared_option name.
This works but it's verbose and hard to read. I've implemented something small to be able to share options.
Cli < Thor
class << self
def add_shared_option(name, options = {})
@shared_options = {} if @shared_options.nil?
@shared_options[name] = options
end
def shared_options(*option_names)
option_names.each do |option_name|
opt = @shared_options[option_name]
raise "Tried to access shared option '#{option_name}' but it was not previously defined" if opt.nil?
option option_name, opt
end
end
end
#...commands
end
This creates a hash with the option name as key, and the 'definition' (required, default, etc) as value (which is a hash). This is easily accessible afterwards.
With this, you can do the following:
require 'thor'
class Cli < Thor
add_shared_option :type, :type => :string, :required => true, :default => 'foo'
add_shared_option :value, :type => :numeric
desc 'task1', 'Task 1'
shared_options :type
def task1
end
desc 'task2', 'Task 2'
shared_options :type, :value
def task2
end
desc 'task3', 'Task 3'
shared_options :value
def task3
end
end
Cli.start(ARGV)
For me it looks more readable, and if the number of commands is bigger than 3 or 4 it's a great improvement.