diff options
-rw-r--r-- | lib/chef/provider.rb | 35 | ||||
-rw-r--r-- | spec/integration/recipes/resource_action_spec.rb | 23 |
2 files changed, 49 insertions, 9 deletions
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb index 43d58740f2..089c28be50 100644 --- a/lib/chef/provider.rb +++ b/lib/chef/provider.rb @@ -297,17 +297,34 @@ class Chef # compile the resources, converging them, and then checking if any # were updated (and updating new-resource if so) def action(name, &block) - class_eval <<-EOM, __FILE__, __LINE__+1 - def action_#{name} - return_value = compile_action_#{name} - Chef::Runner.new(run_context).converge - return_value - ensure - if run_context.resource_collection.any? {|r| r.updated? } - new_resource.updated_by_last_action(true) + # We first try to create the method using "def method_name", which is + # preferred because it actually shows up in stack traces. If that + # fails, we try define_method. + begin + class_eval <<-EOM, __FILE__, __LINE__+1 + def action_#{name} + return_value = compile_action_#{name} + Chef::Runner.new(run_context).converge + return_value + ensure + if run_context.resource_collection.any? {|r| r.updated? } + new_resource.updated_by_last_action(true) + end + end + EOM + rescue SyntaxError + define_method("action_#{name}") do + begin + return_value = send("compile_action_#{name}") + Chef::Runner.new(run_context).converge + return_value + ensure + if run_context.resource_collection.any? {|r| r.updated? } + new_resource.updated_by_last_action(true) + end end end - EOM + end # We put the action in its own method so that super() works. define_method("compile_action_#{name}", &block) end diff --git a/spec/integration/recipes/resource_action_spec.rb b/spec/integration/recipes/resource_action_spec.rb index cee79133a9..1881ab0d03 100644 --- a/spec/integration/recipes/resource_action_spec.rb +++ b/spec/integration/recipes/resource_action_spec.rb @@ -340,4 +340,27 @@ describe "Resource.action" do expect(NoActionJackson.action_was).to eq [:nothing] end end + + context "With a resource with action a-b-c d" do + before(:context) { + class WeirdActionJackson < Chef::Resource + use_automatic_resource_name + + class <<self + attr_accessor :action_was + end + + action "a-b-c d" do + WeirdActionJackson.action_was = action + end + end + } + + it "Running the action works" do + expect_recipe { + weird_action_jackson 'hi' + }.to be_up_to_date + expect(WeirdActionJackson.action_was).to eq :"a-b-c d" + end + end end |