Skip to content

Commit

Permalink
Allow user to ignore class options for command
Browse files Browse the repository at this point in the history
  • Loading branch information
snehitgajjar committed Oct 10, 2017
1 parent 61d4866 commit dd5b734
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 10 deletions.
15 changes: 13 additions & 2 deletions lib/thor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ def method_options(options = nil)

alias_method :options, :method_options


# Declares the class options which can be ignored for given command
#
# ==== Parameters
# list<Array>:: List of class options to be ignored
#
def ignore_class_options(list = nil)
@class_options_to_ignore ||= list
end

# Adds an option to the set of method options. If :for is given as option,
# it allows you to change the options from a previous defined command.
#
Expand Down Expand Up @@ -172,7 +182,8 @@ def command_help(shell, command_name)
shell.say "Usage:"
shell.say " #{banner(command)}"
shell.say
class_options_help(shell, nil => command.options.values)
class_options_help(shell, command.ignored_options, nil => command.options.values)

if command.long_description
shell.say "Description:"
shell.print_wrapped(command.long_description, :indent => 2)
Expand Down Expand Up @@ -412,7 +423,7 @@ def create_command(meth) #:nodoc:

if @usage && @desc
base_class = @hide ? Thor::HiddenCommand : Thor::Command
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, ignore_class_options)
@usage, @desc, @long_desc, @method_options, @hide = nil
true
elsif all_commands[meth] || meth == "method_missing"
Expand Down
13 changes: 9 additions & 4 deletions lib/thor/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ module Base
# config<Hash>:: Configuration for this Thor class.
#
def initialize(args = [], local_options = {}, config = {})
parse_options = self.class.class_options
parse_options = self.class.class_options.dup

ignored_options = config[:current_command] ? config[:current_command].ignored_options : []

parse_options.reject! { |k, _v| ignored_options.include?(k) }

# The start method splits inbound arguments at the first argument
# that looks like an option (starts with - or --). It then calls
Expand Down Expand Up @@ -512,15 +516,16 @@ def handle_argument_error(command, error, args, arity) #:nodoc:
# Prints the class options per group. If an option does not belong to
# any group, it's printed as Class option.
#
def class_options_help(shell, groups = {}) #:nodoc:
def class_options_help(shell, ignored_options = [], groups = {}) #:nodoc:
# Group options by group
class_options.each do |_, value|
class_options.each do |key, value|
groups[value.group] ||= []
groups[value.group] << value
groups[value.group] << value unless ignored_options.include? key
end

# Deal with default group
global_options = groups.delete(nil) || []

print_options(shell, global_options)

# Print all others
Expand Down
6 changes: 3 additions & 3 deletions lib/thor/command.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
class Thor
class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ignored_options, :ancestor_name)
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/

def initialize(name, description, long_description, usage, options = nil)
super(name.to_s, description, long_description, usage, options || {})
def initialize(name, description, long_description, usage, options = nil, ignored_options = nil)
super(name.to_s, description, long_description, usage, options || {}, ignored_options || [])
end

def initialize_copy(other) #:nodoc:
Expand Down
2 changes: 1 addition & 1 deletion lib/thor/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def class_options_help(shell, groups = {}) #:nodoc:
get_options_from_invocations(groups, class_options) do |klass|
klass.send(:get_options_from_invocations, groups, class_options)
end
super(shell, groups)
super(shell, [], groups)
end

# Get invocations array and merge options from invocations. Those
Expand Down
26 changes: 26 additions & 0 deletions spec/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,32 @@ def hello
content = capture(:stdout) { Enum.help(Thor::Base.shell.new) }
expect(content).to match(/Possible values\: apple, banana/)
end

it "does not display class options in help if it has been ignored for a command" do
help = capture(:stdout) { IgnoreClassOptions.start(%w(help shake)) }

expect(help).not_to match (/-c, --cheese=CHEESE/)
end

it "displays class options in help if it has been not ignored for a command" do
help = capture(:stdout) { IgnoreClassOptions.start(%w(help snack)) }

expect(help).to match (/-c, --cheese=CHEESE/)
end
end

describe "#ignore_class_options" do
it "ignores class options when used ignore_class_options" do
options = IgnoreClassOptions.start(%w(shake --fruit apple --milk 1))

expect(options).to eq ({"fruit"=>"apple", "milk"=>1})
end

it "does not ignore class options when ignore_class_options is not used" do
options_when_not_ignored = IgnoreClassOptions.start(%w(snack --fruit apple --cheese provlone))

expect(options_when_not_ignored).to eq ({ "cheese" => "provlone", "fruit" => "apple" })
end
end

describe "#namespace" do
Expand Down
17 changes: 17 additions & 0 deletions spec/fixtures/ignore_class_options.thor
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class IgnoreClassOptions < Thor
class_option :fruit, :aliases => "-f", :type => :string, :enum => %w(apple banana), required: true
class_option :cheese, :aliases => "-c", :type => :string, :enum => %w(pepperjack provlone), required: true

desc "snack", "test"
method_option :vegetable, :aliases => "-v", :type => :string
def snack
options
end

desc "shake", "test"
method_option :milk, :aliases => "-k", :type => :numeric
ignore_class_options [:cheese]
def shake
options
end
end
1 change: 1 addition & 0 deletions spec/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
load File.join(File.dirname(__FILE__), "fixtures", "subcommand.thor")
load File.join(File.dirname(__FILE__), "fixtures", "command.thor")
load File.join(File.dirname(__FILE__), "fixtures", "ignore_class_options.thor")

RSpec.configure do |config|
config.before do
Expand Down

0 comments on commit dd5b734

Please sign in to comment.