summaryrefslogtreecommitdiff
path: root/lib/chef/property.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/property.rb')
-rw-r--r--lib/chef/property.rb66
1 files changed, 17 insertions, 49 deletions
diff --git a/lib/chef/property.rb b/lib/chef/property.rb
index 89e4ffe0e6..8c2776928e 100644
--- a/lib/chef/property.rb
+++ b/lib/chef/property.rb
@@ -253,13 +253,13 @@ class Chef
return get(resource)
end
- if value.nil? && !explicitly_accepts_nil?(resource)
+ if value.nil? && !options.has_key?(:is)
# In Chef 12, value(nil) does a *get* instead of a set, so we
# warn if the value would have been changed. In Chef 13, it will be
# equivalent to value = nil.
result = get(resource)
if !result.nil?
- Chef.log_deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.")
+ Chef.log_deprecation("#{name} nil currently does not overwrite the value of #{name}. This will change in Chef 13, and the value will be set to nil instead. If `nil` is a valid value for your property, please change it to use a type (property kind_of: [ String, NilClass ] becomes property [ String, nil ]) or use `is` instead of `equal_to` or `kind_of` to avoid the warning. If `nil` is not a valid value for your property, please stop setting it to nil.")
end
result
else
@@ -332,8 +332,6 @@ class Chef
value = coerce(resource, value)
- # We don't validate defaults
-
# If the value is mutable (non-frozen), we set it on the instance
# so that people can mutate it. (All constant default values are
# frozen.)
@@ -367,7 +365,18 @@ class Chef
def set(resource, value)
unless value.is_a?(DelayedEvaluator)
value = coerce(resource, value)
- validate(resource, value)
+ if value.nil?
+ # If the value is `nil`, and is not a valid value for this property,
+ # it means we need to reset the property.
+ begin
+ validate(resource, value)
+ rescue Chef::Exceptions::ValidationFailed
+ reset(resource)
+ return
+ end
+ else
+ validate(resource, value)
+ end
end
set_value(resource, value)
end
@@ -411,6 +420,8 @@ class Chef
#
# Does no special handling for lazy values.
#
+ # `nil` is never coerced.
+ #
# @param resource [Chef::Resource] The resource we're coercing against
# (to provide context for the coerce).
# @param value The value to coerce.
@@ -421,7 +432,7 @@ class Chef
# this property.
#
def coerce(resource, value)
- if options.has_key?(:coerce)
+ if options.has_key?(:coerce) && !value.nil?
value = exec_in_resource(resource, options[:coerce], value)
end
value
@@ -509,49 +520,6 @@ class Chef
#
attr_reader :options
- #
- # Find out whether this type accepts nil explicitly.
- #
- # A type accepts nil explicitly if "is" allows nil, it validates as nil, *and* is not simply
- # an empty type.
- #
- # A type is presumed to accept nil if it does coercion (which must handle nil).
- #
- # These examples accept nil explicitly:
- # ```ruby
- # property :a, [ String, nil ]
- # property :a, [ String, NilClass ]
- # property :a, [ String, proc { |v| v.nil? } ]
- # ```
- #
- # This does not (because the "is" doesn't exist or doesn't have nil):
- #
- # ```ruby
- # property :x, String
- # ```
- #
- # These do not, even though nil would validate fine (because they do not
- # have "is"):
- #
- # ```ruby
- # property :a
- # property :a, equal_to: [ 1, 2, 3, nil ]
- # property :a, kind_of: [ String, NilClass ]
- # property :a, respond_to: [ ]
- # property :a, callbacks: { "a" => proc { |v| v.nil? } }
- # ```
- #
- # @param resource [Chef::Resource] The resource we're coercing against
- # (to provide context for the coerce).
- #
- # @return [Boolean] Whether this value explicitly accepts nil.
- #
- # @api private
- def explicitly_accepts_nil?(resource)
- options.has_key?(:coerce) ||
- (options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false))
- end
-
def get_value(resource)
if instance_variable_name
resource.instance_variable_get(instance_variable_name)