geniousli edited this page Jul 22, 2017 · 9 revisions

Thor has a special class called Thor::Group. All of the tasks defined in a Thor::Group are invoked together as a sequence, in the order that they were defined. The example from Invocations could be rewritten using Thor::Group as: myawesomegem/lib/mycounter_file.rb

require 'thor/group'

module MyAwesomeGem
  class MyCounter < Thor::Group
    desc "Prints 1 2 3"

    def one
      puts 1
    end

    def two
      puts 2
    end

    def three
      puts 3
    end
  end
end

When invoked:

thor my_awesome_gem:my_counter
# prints "1 2 3"

Note that in order to add the Thor::Group subclass to the commands list of your executable, you have to register it first.
Building on the executables explanation found in Making An Executable, let's say that you have a file:
myawesomegem/bin/command

#!/usr/bin/env ruby
require File.expand_path('lib/command', Dir.pwd)
MyAwesomeGem::MyCommand.start

And then, the file containing the actual command:
myawesomegem/lib/command.rb

require "thor"
module MyAwesomeGem
  class MyCommand < Thor
    desc "foo", "Prints foo"
    def foo
      puts "foo"
    end
  end
end

Test executable file:

cd myawesomegem
chmod a+x bin/command # make permission
bin/command foo

To make MyCounter available as a subcommand, you need to call the register method:
myawesomegem/lib/command.rb

require "thor"
require File.expand_path("lib/mycounter_file", Dir.pwd)
module MyAwesomeGem
  class MyCommand < Thor
    desc "foo", "Prints foo"
    def foo
      puts "foo"
    end
    
    # register(class_name, subcommand_alias, usage_list_string, description_string)
    register(MyAwesomeGem::MyCounter, "counter", "counter", "Prints some numbers in sequence")
  end
end

Now the class MyCounter < Thor::Group will appear as a sub-task within mycommand with the alias counter, usage:

bin/command
# Commands:
#  command counter         # Prints numbers in sequence
#  command foo             # Prints foo

bin/command counter
#=> 1 2 3

Note: when using Thor::Group, the description you provide (using the method desc) is for the entire class, as opposed to providing a description for each task.

Also, Thor::Group can parse arguments and options as Thor tasks:

class Counter < Thor::Group
  # number will be available as attr_accessor
  argument :number, :type => :numeric, :desc => "The number to start counting"
  desc "Prints the 'number' given upto 'number+2'"

  def one
    puts number + 0
  end

  def two
    puts number + 1
  end

  def three
    puts number + 2
  end
end

The counter above expects one parameter and has the following outputs:

thor counter 5
# Prints "5 6 7"

thor counter 11
# Prints "11 12 13"

You can also give options to Thor::Group, but instead of using method_option and method_options, you should use class_option and class_options. Both argument and class_options methods are available to Thor class as well.

Thor::Group is a great tool to create generators, since you can define several steps which are invoked in the order they are defined (Thor::Group is the tool used for generators in Rails 4.x).

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.