summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-06-30 08:36:21 -0700
committerJay Mundrawala <jdmundrawala@gmail.com>2015-07-06 18:12:50 -0700
commitea08388327a64776852144f0ac236354c46abab5 (patch)
treeda838ed8a6641f2869c12e75a7552506187c1a8a
parent628fd26934ffe2a73ccc8a5076306cac597159f5 (diff)
downloadchef-ea08388327a64776852144f0ac236354c46abab5.tar.gz
Merge pull request #3603 from chef/jdm/lwrp-base
Fix ability to monkey match LWRP through Chef::Resource::MyLwrp
-rw-r--r--lib/chef/resource.rb53
-rw-r--r--lib/chef/resource/lwrp_base.rb57
-rw-r--r--spec/unit/lwrp_spec.rb10
3 files changed, 59 insertions, 61 deletions
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 86e8bac019..cd01f920cf 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -1300,56 +1300,9 @@ class Chef
Chef::Resource.send(:remove_const, class_name)
end
- # In order to generate deprecation warnings when you use Chef::Resource::MyLwrp,
- # we make a special subclass (identical in nearly all respects) of the
- # actual LWRP. When you say any of these, a deprecation warning will be
- # generated:
- #
- # - Chef::Resource::MyLwrp.new(...)
- # - resource.is_a?(Chef::Resource::MyLwrp)
- # - resource.kind_of?(Chef::Resource::MyLwrp)
- # - case resource
- # when Chef::Resource::MyLwrp
- # end
- #
- resource_subclass = Class.new(resource_class) do
- resource_name nil # we do not actually provide anything
- def initialize(*args, &block)
- Chef::Log.deprecation("Using an LWRP by its name (#{self.class.name}) directly is no longer supported in Chef 13 and will be removed. Use Chef::Resource.resource_for_node(node, name) instead.")
- super
- end
- def self.resource_name(*args)
- if args.empty?
- @resource_name ||= superclass.resource_name
- else
- super
- end
- end
- self
- end
- eval("Chef::Resource::#{class_name} = resource_subclass")
- # Make case, is_a and kind_of work with the new subclass, for backcompat.
- # Any subclass of Chef::Resource::ResourceClass is already a subclass of resource_class
- # Any subclass of resource_class is considered a subclass of Chef::Resource::ResourceClass
- resource_class.class_eval do
- define_method(:is_a?) do |other|
- other.is_a?(Module) && other === self
- end
- define_method(:kind_of?) do |other|
- other.is_a?(Module) && other === self
- end
- end
- resource_subclass.class_eval do
- define_singleton_method(:===) do |other|
- Chef::Log.deprecation("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 13 and will be removed. Use Chef::Resource.resource_for_node(node, name) instead.")
- # resource_subclass is a superclass of all resource_class descendants.
- if self == resource_subclass && other.class <= resource_class
- return true
- end
- super(other)
- end
- end
- deprecated_constants[class_name.to_sym] = resource_subclass
+ Chef::Resource.const_set(class_name, resource_class)
+
+ deprecated_constants[class_name.to_sym] = resource_class
end
def self.deprecated_constants
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
index ef3c2b5bba..8089b585ed 100644
--- a/lib/chef/resource/lwrp_base.rb
+++ b/lib/chef/resource/lwrp_base.rb
@@ -52,17 +52,52 @@ class Chef
resource_name = filename_to_qualified_string(cookbook_name, filename)
# We load the class first to give it a chance to set its own name
- resource_class = Class.new(self)
- resource_class.resource_name resource_name.to_sym
- resource_class.run_context = run_context
- resource_class.class_from_file(filename)
-
- # Make a useful string for the class (rather than <Class:312894723894>)
- resource_class.instance_eval do
- define_singleton_method(:to_s) do
- "LWRP resource #{resource_name} from cookbook #{cookbook_name}"
+ deprecated_resource_class = Class.new(self).tap do |resource_class|
+ resource_class.resource_name(nil)
+ resource_class.run_context = run_context
+ resource_class.instance_eval do
+ define_method(:initialize) do |*args, &block|
+ Chef::Log::deprecation("Deprecated Thing") if chef_deprecated_access
+ super(*args, &block)
+ end
+ define_method(:chef_deprecated_access) do
+ true
+ end
+ end
+
+ resource_class.class_from_file(filename)
+
+ # Make a useful string for the class (rather than <Class:312894723894>)
+ resource_class.instance_eval do
+ define_singleton_method(:to_s) do
+ "LWRP resource #{resource_name} from cookbook #{cookbook_name}"
+ end
+ define_singleton_method(:inspect) { to_s }
+ end
+ end
+
+ resource_class = Class.new(deprecated_resource_class).tap do |resource_class|
+ resource_class.resource_name(resource_name.to_sym)
+ resource_class.run_context = run_context
+ resource_class.instance_eval do
+ define_method(:chef_deprecated_access) do
+ false
+ end
+ end
+ resource_class.class_eval do
+ define_singleton_method(:===) do |instance|
+ super(instance) || instance.class <= deprecated_resource_class
+ end
+ end
+ end
+
+ deprecated_resource_class.class_eval do
+ define_method(:kind_of?) do |klass|
+ super(klass) || klass == resource_class
+ end
+ define_method(:is_a?) do |klass|
+ super(klass) || klass == resource_class
end
- define_singleton_method(:inspect) { to_s }
end
Chef::Log.debug("Loaded contents of #{filename} into resource #{resource_name} (#{resource_class})")
@@ -70,7 +105,7 @@ class Chef
LWRPBase.loaded_lwrps[filename] = true
# Create the deprecated Chef::Resource::LwrpFoo class
- Chef::Resource.register_deprecated_lwrp_class(resource_class, convert_to_class_name(resource_name))
+ Chef::Resource.register_deprecated_lwrp_class(deprecated_resource_class, convert_to_class_name(resource_name))
resource_class
end
diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index 55df9cb8fa..7e2ed998b8 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -177,6 +177,16 @@ describe "LWRP" do
end
end
+ it "allows monkey patching of the lwrp through Chef::Resource" do
+ monkey = Module.new do
+ def issue_3607
+ end
+ end
+ allow(Chef::Config).to receive(:[]).with(:treat_deprecation_warnings_as_errors).and_return(false)
+ Chef::Resource::LwrpFoo.send(:include, monkey)
+ expect { get_lwrp(:lwrp_foo).new("blah").issue_3607 }.not_to raise_error
+ end
+
it "should load the resource into a properly-named class and emit a warning when it is initialized" do
expect { Chef::Resource::LwrpFoo.new('hi') }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
end