Skip to content

Commit dd5b734

Browse files
committed
Allow user to ignore class options for command
1 parent 61d4866 commit dd5b734

File tree

7 files changed

+70
-10
lines changed

7 files changed

+70
-10
lines changed

lib/thor.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ def method_options(options = nil)
121121

122122
alias_method :options, :method_options
123123

124+
125+
# Declares the class options which can be ignored for given command
126+
#
127+
# ==== Parameters
128+
# list<Array>:: List of class options to be ignored
129+
#
130+
def ignore_class_options(list = nil)
131+
@class_options_to_ignore ||= list
132+
end
133+
124134
# Adds an option to the set of method options. If :for is given as option,
125135
# it allows you to change the options from a previous defined command.
126136
#
@@ -172,7 +182,8 @@ def command_help(shell, command_name)
172182
shell.say "Usage:"
173183
shell.say " #{banner(command)}"
174184
shell.say
175-
class_options_help(shell, nil => command.options.values)
185+
class_options_help(shell, command.ignored_options, nil => command.options.values)
186+
176187
if command.long_description
177188
shell.say "Description:"
178189
shell.print_wrapped(command.long_description, :indent => 2)
@@ -412,7 +423,7 @@ def create_command(meth) #:nodoc:
412423

413424
if @usage && @desc
414425
base_class = @hide ? Thor::HiddenCommand : Thor::Command
415-
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
426+
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, ignore_class_options)
416427
@usage, @desc, @long_desc, @method_options, @hide = nil
417428
true
418429
elsif all_commands[meth] || meth == "method_missing"

lib/thor/base.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ module Base
4242
# config<Hash>:: Configuration for this Thor class.
4343
#
4444
def initialize(args = [], local_options = {}, config = {})
45-
parse_options = self.class.class_options
45+
parse_options = self.class.class_options.dup
46+
47+
ignored_options = config[:current_command] ? config[:current_command].ignored_options : []
48+
49+
parse_options.reject! { |k, _v| ignored_options.include?(k) }
4650

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

522526
# Deal with default group
523527
global_options = groups.delete(nil) || []
528+
524529
print_options(shell, global_options)
525530

526531
# Print all others

lib/thor/command.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
class Thor
2-
class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
2+
class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ignored_options, :ancestor_name)
33
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
44

5-
def initialize(name, description, long_description, usage, options = nil)
6-
super(name.to_s, description, long_description, usage, options || {})
5+
def initialize(name, description, long_description, usage, options = nil, ignored_options = nil)
6+
super(name.to_s, description, long_description, usage, options || {}, ignored_options || [])
77
end
88

99
def initialize_copy(other) #:nodoc:

lib/thor/group.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def class_options_help(shell, groups = {}) #:nodoc:
162162
get_options_from_invocations(groups, class_options) do |klass|
163163
klass.send(:get_options_from_invocations, groups, class_options)
164164
end
165-
super(shell, groups)
165+
super(shell, [], groups)
166166
end
167167

168168
# Get invocations array and merge options from invocations. Those

spec/base_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,32 @@ def hello
154154
content = capture(:stdout) { Enum.help(Thor::Base.shell.new) }
155155
expect(content).to match(/Possible values\: apple, banana/)
156156
end
157+
158+
it "does not display class options in help if it has been ignored for a command" do
159+
help = capture(:stdout) { IgnoreClassOptions.start(%w(help shake)) }
160+
161+
expect(help).not_to match (/-c, --cheese=CHEESE/)
162+
end
163+
164+
it "displays class options in help if it has been not ignored for a command" do
165+
help = capture(:stdout) { IgnoreClassOptions.start(%w(help snack)) }
166+
167+
expect(help).to match (/-c, --cheese=CHEESE/)
168+
end
169+
end
170+
171+
describe "#ignore_class_options" do
172+
it "ignores class options when used ignore_class_options" do
173+
options = IgnoreClassOptions.start(%w(shake --fruit apple --milk 1))
174+
175+
expect(options).to eq ({"fruit"=>"apple", "milk"=>1})
176+
end
177+
178+
it "does not ignore class options when ignore_class_options is not used" do
179+
options_when_not_ignored = IgnoreClassOptions.start(%w(snack --fruit apple --cheese provlone))
180+
181+
expect(options_when_not_ignored).to eq ({ "cheese" => "provlone", "fruit" => "apple" })
182+
end
157183
end
158184

159185
describe "#namespace" do
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class IgnoreClassOptions < Thor
2+
class_option :fruit, :aliases => "-f", :type => :string, :enum => %w(apple banana), required: true
3+
class_option :cheese, :aliases => "-c", :type => :string, :enum => %w(pepperjack provlone), required: true
4+
5+
desc "snack", "test"
6+
method_option :vegetable, :aliases => "-v", :type => :string
7+
def snack
8+
options
9+
end
10+
11+
desc "shake", "test"
12+
method_option :milk, :aliases => "-k", :type => :numeric
13+
ignore_class_options [:cheese]
14+
def shake
15+
options
16+
end
17+
end

spec/helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
3939
load File.join(File.dirname(__FILE__), "fixtures", "subcommand.thor")
4040
load File.join(File.dirname(__FILE__), "fixtures", "command.thor")
41+
load File.join(File.dirname(__FILE__), "fixtures", "ignore_class_options.thor")
4142

4243
RSpec.configure do |config|
4344
config.before do

0 commit comments

Comments
 (0)