How to Create Thor::Group Generators as Args of My_Command

How do I create thor::group generators as args of my_command

I had trouble getting this to work at first, too. Here's the pattern that I've started using:

$ cat cli.rb

#!/usr/bin/env ruby
require 'rubygems'
require 'thor'
require 'thor/group'

module CLI
class Greeter < Thor::Group
def say_hi
say "Hi"
end
def say_goodbye
say "Goodbye"
end
end
end

module CLI
class Crud < Thor
desc 'create', 'Creates a sub-thing'
def create
say "Creating a sub-thing"
end

desc 'delete', 'Deletes a sub-thing'
def delete
say "Deleting a sub-thing"
end

end
end

module CLI
class Root < Thor
register CLI::Greeter, 'greet', 'greet', 'Executes a multi-step subtask'
register CLI::Crud, 'crud', 'crud [COMMAND]', 'Delegates to a sub-command'
end
end

CLI::Root.start

$ ./cli.rb

Tasks:
cli.rb crud [COMMAND] # Delegates to a sub-command
cli.rb greet # Executes a multi-step subtask
cli.rb help [TASK] # Describe available tasks or one specific task

$ ./cli.rb greet

Hi
Goodbye

$ ./cli.rb crud

Tasks:
cli.rb crud create # Creates a sub-thing
cli.rb crud delete # Deletes a sub-thing
cli.rb crud help [COMMAND] # Describe subcommands or one specific subcommand

$ ./cli.rb crud create

Creating a sub-thing

$ ./cli.rb crud delete

Deleting a sub-thing

How do I register a Thor::Group as a subcommand with arguments

I have a solution. Instead of using Thor::Group I'm using Invocations

bin/foo looks like this:

#!/usr/bin/env ruby

require 'foo'

Foo::CLI.start

lib/cli.rb - registers 'generate' as a subtask of of the base command, foo:

module Foo
class CLI < Thor
register(Generate, 'generate', 'generate [something]', 'Type foo generate for more help.')
end
end

lib/generate.rb looks like this:

module Foo

class Generate < Thor

desc "project [name]", "Prints the project making step"
def project(name)
puts "making first project file #{name}"
invoke :config
invoke :project_sub
end

desc "config [name]", "Prints the config making step"
def config(name)
puts "making first config file #{name}"
invoke :project_sub
end

desc "project_sub [name]", "Prints the project_sub making step"
def project_sub(name)
puts "making subsystem file #{name}"
end

def self.banner(task, namespace = false, subcommand = true)
task.formatted_usage(self, true, subcommand).split(':').join(' ')
end

end

end

Now I can type: foo generate project fred

and it will output:

> making first project file fred
> making first config file fred
> making subsystem file fred

Notice the banner override. It means that typing: foo generate project with invalid or missing args will give the correct help message:

"project" was called incorrectly. Call as "foo generate project [name]".

as opposed to

"project" was called incorrectly. Call as "foo project [name]".

How to add --help, -h flag to Thor command?

Assuming Foo is your class that inherits from Thor, you can call the following somewhere before Foo.start:

help_commands = Thor::HELP_MAPPINGS + ["help"]
# => ["-h", "-?", "--help", "-D"]

if help_commands.any? { |cmd| ARGV.include? cmd }
help_commands.each do |cmd|
if match = ARGV.delete(cmd)
ARGV.unshift match
end
end
end

Rather than going into Thor and patching some method to have different ARGV-parsing behavior, this kind of cheats by moving any help commands to the front of the list.

Why doesn't Thor recognize my command line option?

You just mixed options with arguments. If you add arguments to your thor task definition, as you did in def resend_to_soft_bounced_emails(bounce_rate, amount_of_email), you need to call them as command line arguments too:

thor reverification_task:notifications:resend_to_soft_bounced_emails 20 2000

But you rather wanted to use options (passed on the command line with - prefixes), so you should remove the arguments from your task definition and refer to the options using the options hash:

def resend_to_soft_bounced_emails
Reverification::Process.set_amazon_stat_settings(options[:bounce_threshold],
options[:num_email])
Reverification::Mailer.resend_soft_bounced_notifications
end


Related Topics



Leave a reply



Submit