Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make two thor tasks share options?

Tags:

ruby

thor

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?

like image 278
N.N. Avatar asked Jan 15 '13 20:01

N.N.


1 Answers

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.

like image 142
DBrown Avatar answered Oct 04 '22 19:10

DBrown