Reputation: 425
I created a Thor class inside a Ruby executable, and it correctly shows the help when using ./foo help bar
.
To make it more intuitive (for the sanity of my users), I'd also like to support ./foo bar --help
and ./foo bar -h
. When I do that, I get:
ERROR: "foo bar" was called with arguments ["--help"]
Usage: "foo bar"
I could manually do method_option :help, ...
and handle it inside the bar
method, but I hope there would be an easier way to do that (redirecting that command to ./foo help bar
).
Does anyone know a simple and easy way to do this?
Upvotes: 2
Views: 991
Reputation: 11
To complement the answer from max pleaner, the following handles subcommands, because subcommands help is broken if the trick is applied to them.
Also, I choose to overload Thor start command.
def self.start(*args)
if (Thor::HELP_MAPPINGS & ARGV).any? and subcommands.grep(/^#{ARGV[0]}/).empty?
Thor::HELP_MAPPINGS.each do |cmd|
if match = ARGV.delete(cmd)
ARGV.unshift match
end
end
end
super
end
Upvotes: 1
Reputation: 31
Building on what @max-pleaner listed. This will support subcommands also:
help_commands = Thor::HELP_MAPPINGS + ["help"]
(help_commands & ARGV).each do |cmd|
match = ARGV.delete(cmd)
ARGV.size > 1 ? ARGV.insert(-2, match) : ARGV.unshift(match)
end
Upvotes: 2
Reputation: 26768
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.
Upvotes: 3
Reputation: 1147
You can achive this with class_option
. If you set a class option this option is availiable for every method in your cli and you can just check if it is set and then call the help method.
Something like this:
class CLI < Thor
class_option :help, type: :boolean
desc "foo PARAM", "foo"
def foo(param)
handle_help_option(:foo)
# your logic
end
def handle_help_option(method_name)
help(method_name) if options[:help]
end
end
Upvotes: 2