summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-05-02 00:11:40 -0700
committerJohn Keiser <john@johnkeiser.com>2015-05-13 13:43:14 -0700
commit8e09b80cbeeef8a1a396434bec9dc76737061b13 (patch)
treed1f6553fb27141088bcbd2b50c5faead8251ce26
parent200934f63c02c2b70532eb8a010337ac3b8e9803 (diff)
downloadchef-8e09b80cbeeef8a1a396434bec9dc76737061b13.tar.gz
Move LWRP class deprecation warning to const_missing
-rw-r--r--lib/chef/dsl/resources.rb16
-rw-r--r--lib/chef/provider/lwrp_base.rb1
-rw-r--r--lib/chef/resource.rb33
-rw-r--r--lib/chef/resource/lwrp_base.rb26
-rw-r--r--lib/chef/resource_resolver.rb2
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb2
-rw-r--r--spec/unit/lwrp_spec.rb38
-rw-r--r--spec/unit/resource/batch_spec.rb1
-rw-r--r--spec/unit/resource/powershell_spec.rb1
-rw-r--r--spec/unit/resource_spec.rb64
11 files changed, 111 insertions, 76 deletions
diff --git a/lib/chef/dsl/resources.rb b/lib/chef/dsl/resources.rb
index 482b14e3aa..4072ff2c89 100644
--- a/lib/chef/dsl/resources.rb
+++ b/lib/chef/dsl/resources.rb
@@ -8,14 +8,20 @@ class Chef
# @api private
module Resources
def self.add_resource_dsl(dsl_name)
- module_eval <<-EOM, __FILE__, __LINE__+1
- def #{dsl_name}(name, created_at=nil, &block)
- declare_resource(#{dsl_name.inspect}, name, created_at || caller[0], &block)
+ begin
+ module_eval(<<-EOM, __FILE__, __LINE__+1)
+ def #{dsl_name}(name, created_at=nil, &block)
+ declare_resource(#{dsl_name.inspect}, name, created_at || caller[0], &block)
+ end
+ EOM
+ rescue SyntaxError
+ define_method(dsl_name.to_sym) do |name, created_at=nil, &block|
+ declare_resource(dsl_name, name, created_at || caller[0], &block)
end
- EOM
+ end
end
def self.remove_resource_dsl(dsl_name)
- remove_method dsl_name if method_defined?(dsl_name)
+ remove_method(dsl_name) if method_defined?(dsl_name)
end
end
end
diff --git a/lib/chef/provider/lwrp_base.rb b/lib/chef/provider/lwrp_base.rb
index 492ddda6da..0eadfe9467 100644
--- a/lib/chef/provider/lwrp_base.rb
+++ b/lib/chef/provider/lwrp_base.rb
@@ -93,6 +93,7 @@ class Chef
else
provider_class = Class.new(self)
Chef::Provider.const_set(class_name, provider_class)
+ provider_class.provides provider_name.to_sym
provider_class.class_from_file(filename)
Chef::Log.debug("Loaded contents of #{filename} into a provider named #{provider_name} defined in Chef::Provider::#{class_name}")
end
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 7e0dd6395a..565313e3e1 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -1133,16 +1133,43 @@ class Chef
begin
rname = convert_to_class_name(short_name.to_s)
result = Chef::Resource.const_get(rname)
- Chef::Log.deprecation("Class Chef::Resource::#{rname} does not declare `provides #{short_name.inspect}`.")
- Chef::Log.deprecation("This will no longer work in Chef 13: you must use `provides` to provide DSL.")
- result
+ if result.is_a?(Chef::Resource)
+ Chef::Log.deprecation("Class Chef::Resource::#{rname} does not declare `provides #{short_name.inspect}`.")
+ Chef::Log.deprecation("This will no longer work in Chef 13: you must use `provides` to provide DSL.")
+ result
+ end
rescue NameError
nil
end
end
+ def self.const_missing(class_name)
+ if deprecated_constants[class_name.to_sym]
+ Chef::Log.deprecation("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::Resource.resource_for_node(node, name) instead.")
+ deprecated_constants[class_name.to_sym]
+ else
+ raise NameError, "uninitialized constant Chef::Resource::#{class_name}"
+ end
+ end
+
+ # @api private
+ def self.create_deprecated_lwrp_class(resource_class)
+ # Create a class in Chef::Resource::MyResource with deprecation
+ # warnings if you try to access it
+ class_name = convert_to_class_name(resource_class.resource_name)
+ if Chef::Resource.const_defined?(class_name, false)
+ Chef::Log.warn "#{class_name} already exists! Cannot create deprecation class for #{resource_class}"
+ else
+ deprecated_constants[class_name.to_sym] = resource_class
+ end
+ end
+
private
+ def self.deprecated_constants
+ @deprecated_constants ||= {}
+ end
+
def lookup_provider_constant(name)
begin
self.class.provider_base.const_get(convert_to_class_name(name.to_s))
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
index f702db5c96..3e3670b4ac 100644
--- a/lib/chef/resource/lwrp_base.rb
+++ b/lib/chef/resource/lwrp_base.rb
@@ -50,6 +50,7 @@ class Chef
resource_class = Class.new(self)
resource_class.resource_name = resource_name
resource_class.run_context = run_context
+ resource_class.provides resource_name.to_sym
resource_class.class_from_file(filename)
# Respect resource_name set inside the LWRP
@@ -62,34 +63,11 @@ class Chef
Chef::Log.debug("Loaded contents of #{filename} into #{resource_class}")
- create_deprecated_class_in_chef_resource(resource_class)
+ Chef::Resource.create_deprecated_lwrp_class(resource_class)
resource_class
end
- def self.create_deprecated_class_in_chef_resource(resource_class)
- # Create a class in Chef::Resource::MyResource with deprecation
- # warnings if you try to instantiate or inherit it (for Chef 12 compatibility)
- class_name = convert_to_class_name(resource_class.resource_name)
- if Chef::Resource.const_defined?(class_name, false)
- Chef::Log.debug "#{class_name} already exists! Cannot create deprecation class #{resource_class}"
- else
- Chef::Resource.const_set(class_name, Class.new(resource_class) do
- self.resource_name = resource_class.resource_name
- self.run_context = resource_class.run_context
- define_method(:initialize) do |*args, &block|
- Chef::Log.warn("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed.")
- super(*args, &block)
- end
- define_singleton_method(:inherited) do |*args, &block|
- Chef::Log.warn("Using an LWRP by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed.")
- super(*args, &block)
- end
- end)
- end
- Chef::Resource.const_get(class_name)
- end
-
def self.resource_name(arg = NULL_ARG)
if arg.equal?(NULL_ARG)
@resource_name || dsl_name
diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb
index 4560bac347..d4151e7125 100644
--- a/lib/chef/resource_resolver.rb
+++ b/lib/chef/resource_resolver.rb
@@ -30,7 +30,7 @@ class Chef
def initialize(node, resource)
@node = node
- @resource = resource
+ @resource = resource.to_sym
end
# return a deterministically sorted list of Chef::Resource subclasses
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index fb284c721b..7cc9b8f7d6 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -54,6 +54,9 @@ Dir['lib/chef/knife/**/*.rb'].
map {|f| f.gsub(%r[\.rb$], '') }.
each {|f| require f }
+require 'chef/resource_resolver'
+require 'chef/provider_resolver'
+
require 'chef/mixins'
require 'chef/dsl'
require 'chef/application'
diff --git a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
index 4cf3ba827a..02e4eb2fae 100644
--- a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
+++ b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
@@ -24,6 +24,7 @@ describe Chef::GuardInterpreter::ResourceGuardInterpreter do
node.default["kernel"] = Hash.new
node.default["kernel"][:machine] = :x86_64.to_s
+ node.automatic[:os] = 'windows'
node
end
@@ -144,4 +145,3 @@ describe Chef::GuardInterpreter::ResourceGuardInterpreter do
end
end
end
-
diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index 08273f3872..245074f0ab 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -31,6 +31,10 @@ describe "LWRP" do
$VERBOSE = @original_VERBOSE
end
+ def get_lwrp(name)
+ Chef::Resource.resource_for_node(name, Chef::Node.new)
+ end
+
describe "when overriding an existing class" do
before :each do
allow($stderr).to receive(:write)
@@ -43,7 +47,6 @@ describe "LWRP" do
expect(Chef::Log).not_to receive(:debug).with(/anymore/)
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
Object.send(:remove_const, 'LwrpFoo')
- Chef::Resource.send(:remove_const, 'LwrpFoo')
end
it "should not skip loading a provider when there's a top level symbol of the same name" do
@@ -53,7 +56,6 @@ describe "LWRP" do
expect(Chef::Log).not_to receive(:debug).with(/anymore/)
Chef::Provider::LWRPBase.build_from_file("lwrp", file, nil)
Object.send(:remove_const, 'LwrpBuckPasser')
- Chef::Provider.send(:remove_const, 'LwrpBuckPasser')
end
# @todo: we need a before block to manually remove_const all of the LWRPs that we
@@ -92,7 +94,7 @@ describe "LWRP" do
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
- first_lwr_foo_class = Chef::Resource::LwrpFoo
+ first_lwr_foo_class = get_lwrp(:lwrp_foo)
expect(Chef::Resource.resource_classes).to include(first_lwr_foo_class)
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
@@ -120,28 +122,28 @@ describe "LWRP" do
end
end
- it "should load the resource into a properly-named class" do
- expect(Chef::Resource.const_get("LwrpFoo")).to be_kind_of(Class)
+ it "should load the resource into a properly-named class and emit a warning about deprecation when accessing it" do
+ expect { Chef::Resource::LwrpFoo }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
end
it "should set resource_name" do
- expect(Chef::Resource::LwrpFoo.new("blah").resource_name).to eql(:lwrp_foo)
+ expect(get_lwrp(:lwrp_foo).new("blah").resource_name).to eql(:lwrp_foo)
end
it "should add the specified actions to the allowed_actions array" do
- expect(Chef::Resource::LwrpFoo.new("blah").allowed_actions).to include(:pass_buck, :twiddle_thumbs)
+ expect(get_lwrp(:lwrp_foo).new("blah").allowed_actions).to include(:pass_buck, :twiddle_thumbs)
end
it "should set the specified action as the default action" do
- expect(Chef::Resource::LwrpFoo.new("blah").action).to eq(:pass_buck)
+ expect(get_lwrp(:lwrp_foo).new("blah").action).to eq(:pass_buck)
end
it "should create a method for each attribute" do
- expect(Chef::Resource::LwrpFoo.new("blah").methods.map{ |m| m.to_sym}).to include(:monkey)
+ expect(get_lwrp(:lwrp_foo).new("blah").methods.map{ |m| m.to_sym}).to include(:monkey)
end
it "should build attribute methods that respect validation rules" do
- expect { Chef::Resource::LwrpFoo.new("blah").monkey(42) }.to raise_error(ArgumentError)
+ expect { get_lwrp(:lwrp_foo).new("blah").monkey(42) }.to raise_error(ArgumentError)
end
it "should have access to the run context and node during class definition" do
@@ -153,7 +155,7 @@ describe "LWRP" do
Chef::Resource::LWRPBase.build_from_file("lwrp", file, run_context)
end
- cls = Chef::Resource.const_get("LwrpNodeattr")
+ cls = get_lwrp(:lwrp_nodeattr)
expect(cls.node).to be_kind_of(Chef::Node)
expect(cls.run_context).to be_kind_of(Chef::RunContext)
expect(cls.node[:penguin_name]).to eql("jackass")
@@ -312,7 +314,7 @@ describe "LWRP" do
end
it "should properly handle a new_resource reference" do
- resource = Chef::Resource::LwrpFoo.new("morpheus")
+ resource = get_lwrp(:lwrp_foo).new("morpheus")
resource.monkey("bob")
resource.provider(:lwrp_monkey_name_printer)
resource.run_context = @run_context
@@ -332,7 +334,7 @@ describe "LWRP" do
end
it "should insert resources embedded in the provider into the middle of the resource collection" do
- injector = Chef::Resource::LwrpFoo.new("morpheus", @run_context)
+ injector = get_lwrp(:lwrp_foo).new("morpheus", @run_context)
injector.action(:pass_buck)
injector.provider(:lwrp_buck_passer)
dummy = Chef::Resource::ZenMaster.new("keanu reeves", @run_context)
@@ -349,11 +351,11 @@ describe "LWRP" do
end
it "should insert embedded resources from multiple providers, including from the last position, properly into the resource collection" do
- injector = Chef::Resource::LwrpFoo.new("morpheus", @run_context)
+ injector = get_lwrp(:lwrp_foo).new("morpheus", @run_context)
injector.action(:pass_buck)
injector.provider(:lwrp_buck_passer)
- injector2 = Chef::Resource::LwrpBar.new("tank", @run_context)
+ injector2 = get_lwrp(:lwrp_bar).new("tank", @run_context)
injector2.action(:pass_buck)
injector2.provider(:lwrp_buck_passer_2)
@@ -376,7 +378,7 @@ describe "LWRP" do
end
it "should properly handle a new_resource reference" do
- resource = Chef::Resource::LwrpFoo.new("morpheus", @run_context)
+ resource = get_lwrp(:lwrp_foo).new("morpheus", @run_context)
resource.monkey("bob")
resource.provider(:lwrp_monkey_name_printer)
@@ -387,7 +389,7 @@ describe "LWRP" do
end
it "should properly handle an embedded Resource accessing the enclosing Provider's scope" do
- resource = Chef::Resource::LwrpFoo.new("morpheus", @run_context)
+ resource = get_lwrp(:lwrp_foo).new("morpheus", @run_context)
resource.monkey("bob")
resource.provider(:lwrp_embedded_resource_accesses_providers_scope)
@@ -406,7 +408,7 @@ describe "LWRP" do
# Side effect of lwrp_inline_compiler provider for testing notifications.
$interior_ruby_block_2 = nil
# resource type doesn't matter, so make an existing resource type work with provider.
- @resource = Chef::Resource::LwrpFoo.new("morpheus", @run_context)
+ @resource = get_lwrp(:lwrp_foo).new("morpheus", @run_context)
@resource.allowed_actions << :test
@resource.action(:test)
@resource.provider(:lwrp_inline_compiler)
diff --git a/spec/unit/resource/batch_spec.rb b/spec/unit/resource/batch_spec.rb
index 4a056b8735..b8c2897f42 100644
--- a/spec/unit/resource/batch_spec.rb
+++ b/spec/unit/resource/batch_spec.rb
@@ -25,6 +25,7 @@ describe Chef::Resource::Batch do
node.default["kernel"] = Hash.new
node.default["kernel"][:machine] = :x86_64.to_s
+ node.automatic[:os] = 'windows'
run_context = Chef::RunContext.new(node, nil, nil)
diff --git a/spec/unit/resource/powershell_spec.rb b/spec/unit/resource/powershell_spec.rb
index c263172ae6..2505c4a3d7 100644
--- a/spec/unit/resource/powershell_spec.rb
+++ b/spec/unit/resource/powershell_spec.rb
@@ -25,6 +25,7 @@ describe Chef::Resource::PowershellScript do
node.default["kernel"] = Hash.new
node.default["kernel"][:machine] = :x86_64.to_s
+ node.automatic[:os] = 'windows'
run_context = Chef::RunContext.new(node, nil, nil)
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 6b2d6c89d3..0479778f55 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -731,35 +731,51 @@ describe Chef::Resource do
end
- describe "lookups from the platform map" do
- let(:klz1) { Class.new(Chef::Resource) }
- let(:klz2) { Class.new(Chef::Resource) }
+ describe "resource_for_node" do
+ describe "lookups from the platform map" do
+ let(:klz1) { Class.new(Chef::Resource) }
+
+ before(:each) do
+ Chef::Resource::Klz1 = klz1
+ @node = Chef::Node.new
+ @node.name("bumblebee")
+ @node.automatic[:platform] = "autobots"
+ @node.automatic[:platform_version] = "6.1"
+ Object.const_set('Soundwave', klz1)
+ klz1.provides :soundwave
+ end
- before(:each) do
- Chef::Resource::Klz1 = klz1
- Chef::Resource::Klz2 = klz2
- @node = Chef::Node.new
- @node.name("bumblebee")
- @node.automatic[:platform] = "autobots"
- @node.automatic[:platform_version] = "6.1"
- Object.const_set('Soundwave', klz1)
- klz2.provides :dinobot, :on_platforms => ['autobots']
- Object.const_set('Grimlock', klz2)
- end
+ after(:each) do
+ Object.send(:remove_const, :Soundwave)
+ Chef::Resource.send(:remove_const, :Klz1)
+ end
- after(:each) do
- Object.send(:remove_const, :Soundwave)
- Object.send(:remove_const, :Grimlock)
- Chef::Resource.send(:remove_const, :Klz1)
- Chef::Resource.send(:remove_const, :Klz2)
+ it "returns a resource by short_name if nothing else matches" do
+ expect(Chef::Resource.resource_for_node(:soundwave, @node)).to eql(klz1)
+ end
end
- describe "resource_for_node" do
- it "returns a resource by short_name and node" do
- expect(Chef::Resource.resource_for_node(:dinobot, @node)).to eql(Grimlock)
+ describe "lookups from the platform map" do
+ let(:klz2) { Class.new(Chef::Resource) }
+
+ before(:each) do
+ Chef::Resource::Klz2 = klz2
+ @node = Chef::Node.new
+ @node.name("bumblebee")
+ @node.automatic[:platform] = "autobots"
+ @node.automatic[:platform_version] = "6.1"
+ klz2.provides :dinobot, :on_platforms => ['autobots']
+ Object.const_set('Grimlock', klz2)
+ klz2.provides :grimlock
end
- it "returns a resource by short_name if nothing else matches" do
- expect(Chef::Resource.resource_for_node(:soundwave, @node)).to eql(Soundwave)
+
+ after(:each) do
+ Object.send(:remove_const, :Grimlock)
+ Chef::Resource.send(:remove_const, :Klz2)
+ end
+
+ it "returns a resource by short_name and node" do
+ expect(Chef::Resource.resource_for_node(:dinobot, @node)).to eql(klz2)
end
end