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 the case where one wants some tasks of a class, but not all, to share options?
In the following task1
and task2
shares options but they do not share all options and they share no options with task3
.
require 'thor'
class Cli < Thor
desc 'task1', 'Task 1'
method_option :type, :type => :string, :required => true, :default => 'foo'
def task1
end
desc 'task2', 'Task 2'
method_option :type, :type => :string, :required => true, :default => 'foo'
method_option :value, :type => :numeric
def task2
end
desc 'task3', 'Task 3'
method_option :verbose, :type => :boolean, :aliases => '-v'
def task3
end
end
Cli.start(ARGV)
The problem with stating method_option :type, :type => :string, :required => true, :default => 'foo'
for both task1
and task2
is that it violates the DRY principle. Is there an idiomatic way of handling this?
So there is a nice dry way to do this now, but may not fall into the requirements of being as idiomatic, though I wanted to mention it for anyone looking for a more recent answer.
You can start by using the class_options to set the majority of shared options between your methods:
module MyModule
class Hello < Thor
class_option :name, :desc => "name", :required => true
class_option :greet, :desc => "greeting to use", :required => true
desc "Hello", "Saying hello"
def say
puts "#{options[:greet]}, #{options[:name]}!"
end
desc "Say", "Saying anything"
remove_class_option :greet
def hello
puts "Hello, #{options[:name]}!"
end
def foo
puts "Foo, #{options[:name]}!"
end
end
end
The best part about this, is that it pertains to all methods after the declaration. With these set to required, you can see that the first method requires both greet and name, but say and foo only require the name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With