diff options
-rw-r--r-- | lib/chef/application.rb | 2 | ||||
-rw-r--r-- | lib/chef/chef_class.rb | 16 | ||||
-rw-r--r-- | lib/chef/cookbook_version.rb | 6 | ||||
-rw-r--r-- | lib/chef/deprecation/warnings.rb | 5 | ||||
-rw-r--r-- | lib/chef/dsl/recipe.rb | 5 | ||||
-rw-r--r-- | lib/chef/dsl/resources.rb | 4 | ||||
-rw-r--r-- | lib/chef/event_dispatch/base.rb | 15 | ||||
-rw-r--r-- | lib/chef/event_dispatch/dispatcher.rb | 4 | ||||
-rw-r--r-- | lib/chef/formatters/base.rb | 3 | ||||
-rw-r--r-- | lib/chef/formatters/doc.rb | 36 | ||||
-rw-r--r-- | lib/chef/knife/core/subcommand_loader.rb | 6 | ||||
-rw-r--r-- | lib/chef/log.rb | 3 | ||||
-rw-r--r-- | lib/chef/mixin/deprecation.rb | 16 | ||||
-rw-r--r-- | lib/chef/node_map.rb | 4 | ||||
-rw-r--r-- | lib/chef/property.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider_resolver.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource.rb | 6 | ||||
-rw-r--r-- | lib/chef/resource/chef_gem.rb | 6 | ||||
-rw-r--r-- | lib/chef/resource/file/verification.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource_resolver.rb | 6 | ||||
-rw-r--r-- | lib/chef/run_context.rb | 8 | ||||
-rw-r--r-- | spec/integration/client/client_spec.rb | 53 | ||||
-rw-r--r-- | spec/unit/property_spec.rb | 28 |
24 files changed, 180 insertions, 62 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb index 0563822ede..f43b6bbd8d 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -382,7 +382,7 @@ class Chef def emit_warnings if Chef::Config[:chef_gem_compile_time] - Chef::Log.deprecation "setting chef_gem_compile_time to true is deprecated" + Chef.log.deprecation "setting chef_gem_compile_time to true is deprecated" end end diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index 458ac82467..e825bedb34 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -190,6 +190,22 @@ class Chef def resource_handler_map @resource_handler_map ||= Chef::Platform::ResourceHandlerMap.instance end + + # + # @overload log + # Get the current log object. + # + # @return An object that supports `deprecation(message)` + # + # @example + # run_context.log.deprecation("Deprecated!") + # + # @api private + def log + # `run_context.events` is the primary deprecation target if we're in a run. If we + # are not yet in a run, print to `Chef::Log`. + (run_context && run_context.events) || Chef::Log + end end reset! diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 8d302eeec2..0a7e1df2f7 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -51,12 +51,12 @@ class Chef attr_accessor :metadata_filenames def status=(new_status) - Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed") + Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status = new_status end def status - Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed") + Chef.log.deprecation("Deprecated method `status' called. This method will be removed.", caller(1..1)) @status end @@ -480,7 +480,7 @@ class Chef # @deprecated This method was used by the Ruby Chef Server and is no longer # needed. There is no replacement. def generate_manifest_with_urls(&url_generator) - Chef::Log.deprecation("Deprecated method #generate_manifest_with_urls called from #{caller(1).first}") + Chef.log.deprecation("Deprecated method #generate_manifest_with_urls.", caller(1..1)) rendered_manifest = manifest.dup COOKBOOK_SEGMENTS.each do |segment| diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index 34f468ff53..616f179d53 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -26,9 +26,8 @@ class Chef define_method(name) do |*args| message = [] message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 12." - message << "Please update your cookbooks accordingly. Accessed from:" - caller[0..3].each {|l| message << l} - Chef::Log.deprecation message + message << "Please update your cookbooks accordingly." + Chef.log.deprecation(message, caller(0..3)) super(*args) end end diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index 29cfcd478c..e3b91a7eab 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -140,8 +140,7 @@ class Chef # method_missing manually. Not a fan. Not. A. Fan. # if respond_to?(method_symbol) - Chef::Log.deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13.") - Chef::Log.deprecation("Use public_send() or send() instead.") + Chef.log.deprecation("Calling method_missing(#{method_symbol.inspect}) directly is deprecated in Chef 12 and will be removed in Chef 13. Use public_send() or send() instead.") return send(method_symbol, *args, &block) end @@ -150,7 +149,7 @@ class Chef # never called. DEPRECATED. # if run_context.definitions.has_key?(method_symbol.to_sym) - Chef::Log.deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") + Chef.log.deprecation("Definition #{method_symbol} (#{run_context.definitions[method_symbol.to_sym]}) was added to the run_context without calling Chef::DSL::Definitions.add_definition(#{method_symbol.to_sym.inspect}). This will become required in Chef 13.") Chef::DSL::Definitions.add_definition(method_symbol) return send(method_symbol, *args, &block) end diff --git a/lib/chef/dsl/resources.rb b/lib/chef/dsl/resources.rb index f15beaeab0..8e75223b0d 100644 --- a/lib/chef/dsl/resources.rb +++ b/lib/chef/dsl/resources.rb @@ -11,14 +11,14 @@ class Chef begin module_eval(<<-EOM, __FILE__, __LINE__+1) def #{dsl_name}(*args, &block) - Chef::Log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 + Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (\#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: \#{args}") if args.size > 1 declare_resource(#{dsl_name.inspect}, args[0], caller[0], &block) end EOM rescue SyntaxError # Handle the case where dsl_name has spaces, etc. define_method(dsl_name.to_sym) do |*args, &block| - Chef::Log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 + Chef.log.deprecation("Cannot create resource #{dsl_name} with more than one argument. All arguments except the name (#{args[0].inspect}) will be ignored. This will cause an error in Chef 13. Arguments: #{args}") if args.size > 1 declare_resource(dsl_name, args[0], caller[0], &block) end end diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index 0ae5101029..1c9a58be23 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -47,14 +47,19 @@ class Chef def ohai_completed(node) end - # Already have a client key, assuming this node has registered. + # Announce that we're not going to register the client. Generally because + # we already have the private key, or because we're deliberately not using + # a key. def skipping_registration(node_name, config) end - # About to attempt to register as +node_name+ + # About to attempt to create a private key registered to the server with + # client +node_name+. def registration_start(node_name, config) end + # Successfully created the private key and registered this client with the + # server. def registration_completed end @@ -340,7 +345,6 @@ class Chef def resource_completed(resource) end - # A stream has opened. def stream_opened(stream, options = {}) end @@ -376,8 +380,9 @@ class Chef def whyrun_assumption(action, resource, message) end - ## TODO: deprecation warning. this way we can queue them up and present - # them all at once. + # Emit a message about something being deprecated. + def deprecation(message, location=caller(2..2)[0]) + end # An uncategorized message. This supports the case that a user needs to # pass output that doesn't fit into one of the callbacks above. Note that diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb index 9e17d78507..0c5b27514c 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -28,6 +28,9 @@ class Chef # Define a method that will be forwarded to all def self.def_forwarding_method(method_name) define_method(method_name) do |*args| + if method_name == :deprecation && args.size == 1 + args << caller(2..2)[0] + end @subscribers.each do |s| # Skip new/unsupported event names. if s.respond_to?(method_name) @@ -49,4 +52,3 @@ class Chef end end end - diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index c901068aa0..d3756ef00c 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -212,6 +212,9 @@ class Chef file_load_failed(path, exception) end + def deprecation(message, location=caller(2..2)[0]) + Chef::Log.deprecation("#{message} at #{location}") + end end diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index a5d7e210c5..614cc44e6d 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -43,6 +43,26 @@ class Chef def run_completed(node) @end_time = Time.now + # Print out deprecations. + if !deprecations.empty? + puts_line "" + puts_line "Deprecated features used!" + deprecations.each do |message, locations| + if locations.size == 1 + puts_line " #{message} at #{locations.size} location:" + else + puts_line " #{message} at #{locations.size} locations:" + end + locations.each do |location| + prefix = " - " + Array(location).each do |line| + puts_line "#{prefix}#{line}" + prefix = " " + end + end + end + puts_line "" + end if Chef::Config[:why_run] puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated" else @@ -336,6 +356,16 @@ class Chef end end + def deprecation(message, location=caller(2..2)[0]) + if Chef::Config[:treat_deprecation_warnings_as_errors] + super + end + + # Save deprecations to the screen until the end + deprecations[message] ||= Set.new + deprecations[message] << location + end + def indent indent_by(2) end @@ -343,6 +373,12 @@ class Chef def unindent indent_by(-2) end + + protected + + def deprecations + @deprecations ||= {} + end end end end diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb index 1d359ffd53..646a75a21c 100644 --- a/lib/chef/knife/core/subcommand_loader.rb +++ b/lib/chef/knife/core/subcommand_loader.rb @@ -51,7 +51,7 @@ class Chef Chef::Log.debug("Using autogenerated hashed command manifest #{plugin_manifest_path}") Knife::SubcommandLoader::HashedCommandLoader.new(chef_config_dir, plugin_manifest) elsif custom_manifest? - Chef::Log.deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") + Chef.log.deprecation("Using custom manifest #{plugin_manifest_path} is deprecated. Please use a `knife rehash` autogenerated manifest instead.") Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, plugin_manifest) else Knife::SubcommandLoader::GemGlobLoader.new(chef_config_dir) @@ -84,7 +84,7 @@ class Chef # Deprecated and un-used instance variable. @env = env unless env.nil? - Chef::Log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") + Chef.log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") end end @@ -149,7 +149,7 @@ class Chef # to get in the past. # def subcommand_files - Chef::Log.deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. + Chef.log.deprecation "Using Chef::Knife::SubcommandLoader directly is deprecated. Please use Chef::Knife::SubcommandLoader.for_config(chef_config_dir, env)" @subcommand_files ||= if Chef::Knife::SubcommandLoader.plugin_manifest? Chef::Knife::SubcommandLoader::CustomManifestLoader.new(chef_config_dir, env).subcommand_files diff --git a/lib/chef/log.rb b/lib/chef/log.rb index 9b27778a40..2cf08324c8 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -37,7 +37,8 @@ class Chef end end - def self.deprecation(msg=nil, &block) + def self.deprecation(msg=nil, location=caller(2..2)[0], &block) + msg = Array(msg) + [ location ] if location if Chef::Config[:treat_deprecation_warnings_as_errors] error(msg, &block) raise Chef::Exceptions::DeprecatedFeatureError.new(msg) diff --git a/lib/chef/mixin/deprecation.rb b/lib/chef/mixin/deprecation.rb index a3eacf75cb..c90daee4f5 100644 --- a/lib/chef/mixin/deprecation.rb +++ b/lib/chef/mixin/deprecation.rb @@ -102,20 +102,20 @@ class Chef def deprecated_attr_reader(name, alternative, level=:warn) define_method(name) do - Chef::Log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") - Chef::Log.deprecation(alternative) - Chef::Log.deprecation("Called from:") - caller[0..3].each {|c| Chef::Log.deprecation(c)} + Chef.log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.") + Chef.log.deprecation(alternative) + Chef.log.deprecation("Called from:") + caller[0..3].each {|c| Chef.log.deprecation(c)} instance_variable_get("@#{name}") end end def deprecated_attr_writer(name, alternative, level=:warn) define_method("#{name}=") do |value| - Chef::Log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") - Chef::Log.deprecation(alternative) - Chef::Log.deprecation("Called from:") - caller[0..3].each {|c| Chef::Log.deprecation(c)} + Chef.log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.") + Chef.log.deprecation(alternative) + Chef.log.deprecation("Called from:") + caller[0..3].each {|c| Chef.log.deprecation(c)} instance_variable_set("@#{name}", value) end end diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index d905c8779e..2e62054b80 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -32,8 +32,8 @@ class Chef # @return [NodeMap] Returns self for possible chaining # def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, on_platform: nil, on_platforms: nil, canonical: nil, override: nil, &block) - Chef::Log.deprecation "The on_platform option to node_map has been deprecated" if on_platform - Chef::Log.deprecation "The on_platforms option to node_map has been deprecated" if on_platforms + Chef.log.deprecation("The on_platform option to node_map has been deprecated") if on_platform + Chef.log.deprecation("The on_platforms option to node_map has been deprecated") if on_platforms platform ||= on_platform || on_platforms filters = {} filters[:platform] = platform if platform diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 1a3b8ec72c..ccdc711698 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -228,7 +228,7 @@ class Chef if value.nil? && !explicitly_accepts_nil?(resource) # If you say "my_property nil" and the property explicitly accepts # nil values, we consider this a get. - 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. Please change your code to explicitly accept nil using \"property :#{name}, [MyType, nil]\", or stop setting this value to nil.") return get(resource) end diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index f2a493c3e6..5f2430e26e 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -421,7 +421,7 @@ class Chef module DeprecatedLWRPClass def const_missing(class_name) if deprecated_constants[class_name.to_sym] - Chef::Log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") + Chef.log.deprecation("Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.") deprecated_constants[class_name.to_sym] else raise NameError, "uninitialized constant Chef::Provider::#{class_name}" diff --git a/lib/chef/provider_resolver.rb b/lib/chef/provider_resolver.rb index 8459bc1328..113b1081ee 100644 --- a/lib/chef/provider_resolver.rb +++ b/lib/chef/provider_resolver.rb @@ -157,8 +157,8 @@ class Chef # perf concern otherwise.) handlers = providers.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource) } handlers.each do |handler| - Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") - Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource.resource_name}, but provides #{resource.resource_name.inspect} was never called!") + Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 5bef40625f..6b8c5434f5 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -809,7 +809,7 @@ class Chef end if !options[:default].frozen? && (options[:default].is_a?(Array) || options[:default].is_a?(Hash)) - Chef::Log.warn("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") + Chef.log.deprecation("Property #{self}.#{name} has an array or hash default (#{options[:default]}). This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes. Either freeze the constant with `.freeze` to prevent appending, or use lazy { #{options[:default].inspect} }.") end local_properties = properties(false) @@ -1211,7 +1211,7 @@ class Chef # @deprecated Use resource_name instead. # def self.dsl_name - Chef::Log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." + Chef.log.deprecation "Resource.dsl_name is deprecated and will be removed in Chef 13. Use resource_name instead." if name name = self.name.split('::')[-1] convert_to_snake_case(name) @@ -1288,7 +1288,7 @@ class Chef # def self.provider_base(arg=nil) if arg - Chef::Log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") + Chef.log.deprecation("Resource.provider_base is deprecated and will be removed in Chef 13. Use provides on the provider, or provider on the resource, instead.") end @provider_base ||= arg || Chef::Provider end diff --git a/lib/chef/resource/chef_gem.rb b/lib/chef/resource/chef_gem.rb index 0c2fdfa819..4d198421ce 100644 --- a/lib/chef/resource/chef_gem.rb +++ b/lib/chef/resource/chef_gem.rb @@ -50,9 +50,9 @@ class Chef # Chef::Resource.run_action: Caveat: this skips Chef::Runner.run_action, where notifications are handled # Action could be an array of symbols, but probably won't (think install + enable for a package) if compile_time.nil? - Chef::Log.deprecation "#{self} chef_gem compile_time installation is deprecated" - Chef::Log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." - Chef::Log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." + Chef.log.deprecation "#{self} chef_gem compile_time installation is deprecated" + Chef.log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior." + Chef.log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required." end if compile_time || compile_time.nil? diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb index faf4791884..654f2d72ce 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -108,7 +108,7 @@ class Chef def verify_command(path, opts) # First implementation interpolated `file`; docs & RFC claim `path` # is interpolated. Until `file` can be deprecated, interpolate both. - Chef::Log.deprecation( + Chef.log.deprecation( '%{file} is deprecated in verify command and will not be '\ 'supported in Chef 13. Please use %{path} instead.' ) if @command.include?('%{file}') diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index 47b3df18af..14b0ff849d 100644 --- a/lib/chef/resource_resolver.rb +++ b/lib/chef/resource_resolver.rb @@ -56,7 +56,7 @@ class Chef attr_reader :resource_name # @api private def resource - Chef::Log.deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") + Chef.log.deprecation("Chef::ResourceResolver.resource deprecated. Use resource_name instead.") resource_name end # @api private @@ -174,8 +174,8 @@ class Chef if handlers.empty? handlers = resources.select { |handler| overrode_provides?(handler) && handler.provides?(node, resource_name) } handlers.each do |handler| - Chef::Log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") - Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") + Chef.log.deprecation("#{handler}.provides? returned true when asked if it provides DSL #{resource_name}, but provides #{resource_name.inspect} was never called!") + Chef.log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.") end end handlers diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index b1113f594e..dd2da0d7ac 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -533,22 +533,22 @@ ERROR_MESSAGE # These need to be settable so deploy can run a resource_collection # independent of any cookbooks via +recipe_eval+ def resource_collection=(value) - Chef::Log.deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @resource_collection = value end def audits=(value) - Chef::Log.deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @audits = value end def immediate_notification_collection=(value) - Chef::Log.deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @immediate_notification_collection = value end def delayed_notification_collection=(value) - Chef::Log.deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + Chef.log.deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @delayed_notification_collection = value end end diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 8c72048965..1a030c130b 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -303,6 +303,59 @@ EOM end + when_the_repository "has a cookbook that generates deprecation warnings" do + before do + file 'cookbooks/x/recipes/default.rb', <<-EOM + class ::MyResource < Chef::Resource + use_automatic_resource_name + property :x, default: [] + property :y, default: {} + end + + my_resource 'blah' do + 1.upto(10) do + x nil + end + x nil + end + EOM + end + + def match_indices(regex, str) + result = [] + pos = 0 + while match = regex.match(str, pos) + result << match.begin(0) + pos = match.end(0) + 1 + end + result + end + + it "should output each deprecation warning only once, at the end of the run" do + file 'config/client.rb', <<EOM +local_mode true +cookbook_path "#{path_to('cookbooks')}" +# Mimick what happens when you are on the console +formatters << :doc +log_level :warn +EOM + + ENV.delete('CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS') + + result = shell_out!("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default'", :cwd => chef_dir) + expect(result.error?).to be_falsey + + # Search to the end of the client run in the output + run_complete = result.stdout.index("Running handlers complete") + expect(run_complete).to be >= 0 + + # Make sure there is exactly one result for each, and that it occurs *after* the complete message. + expect(match_indices(/MyResource.x has an array or hash default/, result.stdout)).to match([ be > run_complete ]) + expect(match_indices(/MyResource.y has an array or hash default/, result.stdout)).to match([ be > run_complete ]) + expect(match_indices(/nil currently does not overwrite the value of/, result.stdout)).to match([ be > run_complete ]) + end + end + when_the_repository "has a cookbook with only an audit recipe" do before do diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index 55eaead9ba..a9b592ec46 100644 --- a/spec/unit/property_spec.rb +++ b/spec/unit/property_spec.rb @@ -462,22 +462,26 @@ describe "Chef::Resource.property" do end context "hash default" do - with_property ':x, default: {}' do - it "when x is not set, it returns {}" do - expect(resource.x).to eq({}) - end - it "The same exact value is returned multiple times in a row" do - value = resource.x - expect(value).to eq({}) - expect(resource.x.object_id).to eq(value.object_id) - end - it "Multiple instances of x receive the exact same value" do - expect(resource.x.object_id).to eq(resource_class.new('blah2').x.object_id) + context "(deprecations allowed)" do + before { Chef::Config[:treat_deprecation_warnings_as_errors] = false } + + with_property ':x, default: {}' do + it "when x is not set, it returns {}" do + expect(resource.x).to eq({}) + end + it "The same exact value is returned multiple times in a row" do + value = resource.x + expect(value).to eq({}) + expect(resource.x.object_id).to eq(value.object_id) + end + it "Multiple instances of x receive the exact same value" do + expect(resource.x.object_id).to eq(resource_class.new('blah2').x.object_id) + end end end it "when a property is declared with default: {}, a warning is issued" do - expect(Chef::Log).to receive(:warn).with(match(/^Property .+\.x has an array or hash default \(\{\}\)\. This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes\. Either freeze the constant with \`\.freeze\` to prevent appending, or use lazy \{ \{\} \}\.$/)) + expect(Chef::Log).to receive(:deprecation).with(match(/^Property .+\.x has an array or hash default \(\{\}\)\. This means that if one resource modifies or appends to it, all other resources of the same type will also see the changes\. Either freeze the constant with \`\.freeze\` to prevent appending, or use lazy \{ \{\} \}\.$/)) resource_class.class_eval("property :x, default: {}", __FILE__, __LINE__) expect(resource.x).to eq({}) end |