Skip to content

Commit c516150

Browse files
committed
Merge pull request #626 from marcandre/deprecate_default_check
Deprecate default check
2 parents dc21c60 + 7d199c0 commit c516150

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

lib/thor/base.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,20 @@ def check_unknown_options?(config) #:nodoc:
153153

154154
# If you want to raise an error when the default value of an option does not match
155155
# the type call check_default_type!
156-
# This is disabled by default for compatibility.
156+
# This will be the default; for compatibility a deprecation warning is issued if necessary.
157157
def check_default_type!
158158
@check_default_type = true
159159
end
160160

161-
def check_default_type #:nodoc:
162-
@check_default_type ||= from_superclass(:check_default_type, false)
161+
# If you want to use defaults that don't match the type of an option,
162+
# either specify `check_default_type: false` or call `allow_incompatible_default_type!`
163+
def allow_incompatible_default_type!
164+
@check_default_type = false
163165
end
164166

165-
def check_default_type? #:nodoc:
166-
!!check_default_type
167+
def check_default_type #:nodoc:
168+
@check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type)
169+
@check_default_type
167170
end
168171

169172
# If true, option parsing is suspended as soon as an unknown option or a
@@ -563,7 +566,7 @@ def is_thor_reserved_word?(word, type) #:nodoc:
563566
# options<Hash>:: Described in both class_option and method_option.
564567
# scope<Hash>:: Options hash that is being built up
565568
def build_option(name, options, scope) #:nodoc:
566-
scope[name] = Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
569+
scope[name] = Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
567570
end
568571

569572
# Receives a hash of options, parse them and add to the scope. This is a

lib/thor/parser/option.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def #{type}?
112112

113113
def validate!
114114
raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
115-
validate_default_type! if @check_default_type
115+
validate_default_type!
116116
end
117117

118118
def validate_default_type!
@@ -130,7 +130,18 @@ def validate_default_type!
130130
end
131131

132132
expected_type = (@repeatable && @type != :hash) ? :array : @type
133-
raise ArgumentError, "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == expected_type
133+
134+
if default_type != expected_type
135+
err = "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})"
136+
137+
if @check_default_type
138+
raise ArgumentError, err
139+
elsif @check_default_type == nil
140+
Thor.deprecation_warning "#{err}.\n" +
141+
'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' +
142+
' or call `allow_incompatible_default_type!` in your code'
143+
end
144+
end
134145
end
135146

136147
def dasherized?

spec/thor_spec.rb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,12 +722,30 @@ def unknown(*args)
722722
expect(klass.start(%w(unknown foo --bar baz))).to eq(%w(foo))
723723
end
724724

725-
it "does not check the default type when check_default_type! is not called" do
725+
it "issues a deprecation warning on incompatible types by default" do
726726
expect do
727727
Class.new(Thor) do
728728
option "bar", :type => :numeric, :default => "foo"
729729
end
730-
end.not_to raise_error
730+
end.to output(/^Deprecation warning/).to_stderr
731+
end
732+
733+
it "allows incompatible types if allow_incompatible_default_type! is called" do
734+
expect do
735+
Class.new(Thor) do
736+
allow_incompatible_default_type!
737+
738+
option "bar", :type => :numeric, :default => "foo"
739+
end
740+
end.not_to output.to_stderr
741+
end
742+
743+
it "allows incompatible types if `check_default_type: false` is given" do
744+
expect do
745+
Class.new(Thor) do
746+
option "bar", :type => :numeric, :default => "foo", :check_default_type => false
747+
end
748+
end.not_to output.to_stderr
731749
end
732750

733751
it "checks the default type when check_default_type! is called" do

0 commit comments

Comments
 (0)