diff options
author | John Keiser <john@johnkeiser.com> | 2015-09-01 22:31:39 -0700 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2015-09-01 22:31:39 -0700 |
commit | 1ef5f566480ba84091a12f2b6c5e85f44af54a5b (patch) | |
tree | 2e05374221cb5e6df5b52e6eab45af849e718929 | |
parent | ad8fd4d65b48519ac154ad9bf9774322b0c6d902 (diff) | |
parent | a8d5109721deb5d90687f38e10bb37765a5ac65a (diff) | |
download | chef-1ef5f566480ba84091a12f2b6c5e85f44af54a5b.tar.gz |
Merge branch 'jk/dedup-messages'
34 files changed, 219 insertions, 101 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb index 0563822ede..970544c068 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..c2cb9e2b24 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -190,6 +190,29 @@ class Chef def resource_handler_map @resource_handler_map ||= Chef::Platform::ResourceHandlerMap.instance end + + # + # Emit a deprecation message. + # + # @param message The message to send. + # @param location The location. Defaults to the caller who called you (since + # generally the person who triggered the check is the one that needs to be + # fixed). + # + # @example + # Chef.deprecation("Deprecated!") + # + # @api private this will likely be removed in favor of an as-yet unwritten + # `Chef.log` + def log_deprecation(message, location=caller(2..2)[0]) + # `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`. + if run_context && run_context.events + run_context.events.deprecation(message, location) + else + Chef::Log.deprecation(message, location) + end + end end reset! diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 8d302eeec2..bff3146572 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/mixin/template.rb b/lib/chef/deprecation/mixin/template.rb index 36d18ad90d..58a661c4bd 100644 --- a/lib/chef/deprecation/mixin/template.rb +++ b/lib/chef/deprecation/mixin/template.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::Mixin::Template # This module contains the deprecated functions of # Chef::Mixin::Template. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module Template @@ -46,4 +46,3 @@ class Chef end end end - diff --git a/lib/chef/deprecation/provider/cookbook_file.rb b/lib/chef/deprecation/provider/cookbook_file.rb index dfbf4a39a4..92f5ce3623 100644 --- a/lib/chef/deprecation/provider/cookbook_file.rb +++ b/lib/chef/deprecation/provider/cookbook_file.rb @@ -24,7 +24,7 @@ class Chef # == Deprecation::Provider::CookbookFile # This module contains the deprecated functions of # Chef::Provider::CookbookFile. These functions are refactored to - # different components. They are frozen and will be removed in Chef 12. + # different components. They are frozen and will be removed in Chef 13. # module CookbookFile diff --git a/lib/chef/deprecation/provider/file.rb b/lib/chef/deprecation/provider/file.rb index 125f31fe10..31038ab3d8 100644 --- a/lib/chef/deprecation/provider/file.rb +++ b/lib/chef/deprecation/provider/file.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::File # This module contains the deprecated functions of # Chef::Provider::File. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module File diff --git a/lib/chef/deprecation/provider/remote_file.rb b/lib/chef/deprecation/provider/remote_file.rb index 4452de67cd..c06a5cc695 100644 --- a/lib/chef/deprecation/provider/remote_file.rb +++ b/lib/chef/deprecation/provider/remote_file.rb @@ -23,7 +23,7 @@ class Chef # == Deprecation::Provider::RemoteFile # This module contains the deprecated functions of # Chef::Provider::RemoteFile. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module RemoteFile @@ -83,4 +83,3 @@ class Chef end end end - diff --git a/lib/chef/deprecation/provider/template.rb b/lib/chef/deprecation/provider/template.rb index d7a228e97a..34e5f54b7e 100644 --- a/lib/chef/deprecation/provider/template.rb +++ b/lib/chef/deprecation/provider/template.rb @@ -25,7 +25,7 @@ class Chef # == Deprecation::Provider::Template # This module contains the deprecated functions of # Chef::Provider::Template. These functions are refactored to different - # components. They are frozen and will be removed in Chef 12. + # components. They are frozen and will be removed in Chef 13. # module Template diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index 34f468ff53..376629710e 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -25,10 +25,9 @@ class Chef m = instance_method(name) 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 << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 13." + 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..26c0ec6768 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..49588ed516 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..966a3f32ec 100644 --- a/lib/chef/event_dispatch/dispatcher.rb +++ b/lib/chef/event_dispatch/dispatcher.rb @@ -25,28 +25,30 @@ class Chef # define the forwarding in one go: # - # Define a method that will be forwarded to all - def self.def_forwarding_method(method_name) - define_method(method_name) do |*args| - @subscribers.each do |s| - # Skip new/unsupported event names. - if s.respond_to?(method_name) - mth = s.method(method_name) - # Anything with a *args is arity -1, so use all arguments. - arity = mth.arity < 0 ? args.length : mth.arity - # Trim arguments to match what the subscriber expects to allow - # adding new arguments without breaking compat. - mth.call(*args.take(arity)) - end - end + def call_subscribers(method_name, *args) + @subscribers.each do |s| + # Skip new/unsupported event names. + next if !s.respond_to?(method_name) + mth = s.method(method_name) + # Trim arguments to match what the subscriber expects to allow + # adding new arguments without breaking compat. + args = args.take(mth.arity) if mth.arity < args.size && mth.arity >= 0 + mth.call(*args) end end (Base.instance_methods - Object.instance_methods).each do |method_name| - def_forwarding_method(method_name) + class_eval <<-EOM + def #{method_name}(*args) + call_subscribers(#{method_name.inspect}, *args) + end + EOM end + # Special case deprecation, since it needs to know its caller + def deprecation(message, location=caller(2..2)[0]) + call_subscribers(:deprecation, message, location) + end 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..808e053c40 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..bf846c2072 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -37,7 +37,11 @@ class Chef end end - def self.deprecation(msg=nil, &block) + def self.deprecation(msg=nil, location=caller(2..2)[0], &block) + if msg + msg << " at #{Array(location).join("\n")}" + msg = msg.join("") if msg.respond_to?(:join) + end 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..562af541bd 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..751f9576f6 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..09198d90f1 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..3138704a55 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..82a24fc078 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..ee75dec3b9 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..7e9d21ebd2 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..9b0788fad3 100644 --- a/lib/chef/resource/file/verification.rb +++ b/lib/chef/resource/file/verification.rb @@ -108,9 +108,10 @@ 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.' + 'supported in Chef 13. Please use %{path} instead.', + caller(2..2)[0] ) if @command.include?('%{file}') command = @command % {:file => path, :path => path} interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts) diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb index 47b3df18af..67cf134c62 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..0c8d3d1a48 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/spec_helper.rb b/spec/spec_helper.rb index d0d02f1a2a..aadf55f64b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -185,6 +185,8 @@ RSpec.configure do |config| config.run_all_when_everything_filtered = true config.before(:each) do + Chef.reset! + Chef::Config.reset # By default, treat deprecation warnings as errors in tests. diff --git a/spec/unit/chef_class_spec.rb b/spec/unit/chef_class_spec.rb index d6bf74572e..f1b877520c 100644 --- a/spec/unit/chef_class_spec.rb +++ b/spec/unit/chef_class_spec.rb @@ -46,10 +46,6 @@ describe "Chef class" do Chef.set_provider_priority_map(provider_priority_map) end - after do - Chef.reset! - end - context "priority maps" do context "#get_provider_priority_array" do it "should use the current node to get the right priority_map" do diff --git a/spec/unit/deprecation_spec.rb b/spec/unit/deprecation_spec.rb index 2e1f3c39f3..674de5ec1d 100644 --- a/spec/unit/deprecation_spec.rb +++ b/spec/unit/deprecation_spec.rb @@ -65,19 +65,16 @@ describe Chef::Deprecation do end context 'deprecation warning messages' do - before(:each) do - @warning_output = [ ] - allow(Chef::Log).to receive(:warn) { |msg| @warning_output << msg } - end + RSpec::Matchers.define_negated_matcher :a_non_empty_array, :be_empty it 'should be enabled for deprecated methods' do + expect(Chef::Log).to receive(:warn).with(a_non_empty_array) TestClass.new.deprecated_method(10) - expect(@warning_output).not_to be_empty end it 'should contain stack trace' do + expect(Chef::Log).to receive(:warn).with(a_string_including(".rb")) TestClass.new.deprecated_method(10) - expect(@warning_output.join("").include?(".rb")).to be_truthy end end diff --git a/spec/unit/event_dispatch/dsl_spec.rb b/spec/unit/event_dispatch/dsl_spec.rb index f467ea81ea..0f7adce7a8 100644 --- a/spec/unit/event_dispatch/dsl_spec.rb +++ b/spec/unit/event_dispatch/dsl_spec.rb @@ -32,10 +32,6 @@ describe Chef::EventDispatch::DSL do Chef.set_run_context(run_context) end - after do - Chef.reset! - end - subject{ described_class.new('test') } it 'set handler name' do diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index 55eaead9ba..50764aa7a2 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( /^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 \{ \{\} \}\.$/, /property_spec\.rb/ ) resource_class.class_eval("property :x, default: {}", __FILE__, __LINE__) expect(resource.x).to eq({}) end diff --git a/spec/unit/resource/file/verification_spec.rb b/spec/unit/resource/file/verification_spec.rb index 04ae9ad629..6b929789c8 100644 --- a/spec/unit/resource/file/verification_spec.rb +++ b/spec/unit/resource/file/verification_spec.rb @@ -88,7 +88,7 @@ describe Chef::Resource::File::Verification do end it "warns about deprecation when \%{file} is used" do - expect(Chef::Log).to receive(:deprecation).with(/%{file} is deprecated/) + expect(Chef::Log).to receive(:deprecation).with(/%{file} is deprecated/, /verification_spec\.rb/) test_command = platform_specific_verify_command('file') Chef::Resource::File::Verification.new(parent_resource, test_command, {}) .verify(temp_path) |