poise 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.kitchen.travis.yml +9 -0
- data/.kitchen.yml +18 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +25 -0
- data/.yardopts +5 -0
- data/Berksfile +26 -0
- data/Berksfile.lock +10 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +32 -0
- data/LICENSE +202 -0
- data/README.md +198 -0
- data/Rakefile +17 -0
- data/lib/poise.rb +71 -0
- data/lib/poise/error.rb +24 -0
- data/lib/poise/helpers.rb +33 -0
- data/lib/poise/helpers/chefspec_matchers.rb +92 -0
- data/lib/poise/helpers/defined_in.rb +111 -0
- data/lib/poise/helpers/fused.rb +127 -0
- data/lib/poise/helpers/include_recipe.rb +62 -0
- data/lib/poise/helpers/inversion.rb +374 -0
- data/lib/poise/helpers/inversion/options_provider.rb +41 -0
- data/lib/poise/helpers/inversion/options_resource.rb +101 -0
- data/lib/poise/helpers/lazy_default.rb +62 -0
- data/lib/poise/helpers/lwrp_polyfill.rb +96 -0
- data/lib/poise/helpers/notifying_block.rb +78 -0
- data/lib/poise/helpers/option_collector.rb +117 -0
- data/lib/poise/helpers/resource_name.rb +99 -0
- data/lib/poise/helpers/subcontext_block.rb +58 -0
- data/lib/poise/helpers/subresources.rb +29 -0
- data/lib/poise/helpers/subresources/child.rb +217 -0
- data/lib/poise/helpers/subresources/container.rb +165 -0
- data/lib/poise/helpers/subresources/default_containers.rb +73 -0
- data/lib/poise/helpers/template_content.rb +165 -0
- data/lib/poise/provider.rb +55 -0
- data/lib/poise/resource.rb +75 -0
- data/lib/poise/subcontext.rb +27 -0
- data/lib/poise/subcontext/resource_collection.rb +56 -0
- data/lib/poise/subcontext/runner.rb +50 -0
- data/lib/poise/utils.rb +60 -0
- data/lib/poise/utils/resource_provider_mixin.rb +53 -0
- data/lib/poise/version.rb +20 -0
- data/poise.gemspec +38 -0
- data/test/cookbooks/poise_test/attributes/default.rb +17 -0
- data/test/cookbooks/poise_test/libraries/app.rb +43 -0
- data/test/cookbooks/poise_test/libraries/app_config.rb +46 -0
- data/test/cookbooks/poise_test/libraries/inversion.rb +67 -0
- data/test/cookbooks/poise_test/metadata.rb +18 -0
- data/test/cookbooks/poise_test/recipes/default.rb +25 -0
- data/test/cookbooks/poise_test/recipes/inversion.rb +42 -0
- data/test/gemfiles/chef-12.0.gemfile +18 -0
- data/test/gemfiles/chef-12.1.gemfile +18 -0
- data/test/gemfiles/chef-12.2.gemfile +18 -0
- data/test/gemfiles/chef-12.gemfile +18 -0
- data/test/gemfiles/master.gemfile +20 -0
- data/test/integration/default/serverspec/default_spec.rb +35 -0
- data/test/integration/default/serverspec/inversion_spec.rb +43 -0
- data/test/spec/helpers/chefspec_matchers_spec.rb +45 -0
- data/test/spec/helpers/defined_in_spec.rb +62 -0
- data/test/spec/helpers/fused_spec.rb +92 -0
- data/test/spec/helpers/include_recipe_spec.rb +34 -0
- data/test/spec/helpers/inversion/options_resource_spec.rb +212 -0
- data/test/spec/helpers/inversion_spec.rb +273 -0
- data/test/spec/helpers/lazy_default_spec.rb +74 -0
- data/test/spec/helpers/lwrp_polyfill_spec.rb +128 -0
- data/test/spec/helpers/notifying_block_spec.rb +87 -0
- data/test/spec/helpers/option_collector_spec.rb +82 -0
- data/test/spec/helpers/resource_name_spec.rb +39 -0
- data/test/spec/helpers/subcontext_block_spec.rb +94 -0
- data/test/spec/helpers/subresources/child_spec.rb +339 -0
- data/test/spec/helpers/subresources/container_spec.rb +175 -0
- data/test/spec/helpers/template_context_spec.rb +147 -0
- data/test/spec/poise_spec.rb +185 -0
- data/test/spec/provider_spec.rb +28 -0
- data/test/spec/resource_spec.rb +85 -0
- data/test/spec/spec_helper.rb +18 -0
- data/test/spec/utils/resource_provider_mixin_spec.rb +52 -0
- data/test/spec/utils_spec.rb +110 -0
- metadata +190 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/mash'
|
18
|
+
|
19
|
+
require 'poise/error'
|
20
|
+
|
21
|
+
|
22
|
+
module Poise
|
23
|
+
module Helpers
|
24
|
+
module Inversion
|
25
|
+
# A mixin for inversion options resources.
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 2.0.0
|
29
|
+
# @see Poise::Helpers::Inversion
|
30
|
+
module OptionsResource
|
31
|
+
include Poise
|
32
|
+
|
33
|
+
# Method missing delegation to allow DSL-style options.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# my_app_options 'app' do
|
37
|
+
# key1 'value1'
|
38
|
+
# key2 'value2'
|
39
|
+
# end
|
40
|
+
def method_missing(method_sym, *args, &block)
|
41
|
+
super(method_sym, *args, &block)
|
42
|
+
rescue NoMethodError
|
43
|
+
# First time we've seen this key and using it as an rvalue, NOPE.GIF.
|
44
|
+
raise unless !args.empty? || block || _options[method_sym]
|
45
|
+
if !args.empty? || block
|
46
|
+
_options[method_sym] = block || args.first
|
47
|
+
end
|
48
|
+
_options[method_sym]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Insert the options data in to the run state. This has to match the
|
52
|
+
# layout used in {Poise::Helpers::Inversion::Provider.inversion_options}.
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def after_created
|
56
|
+
raise Poise::Error.new("Inversion resource name not set for #{self.class.name}") unless self.class.inversion_resource
|
57
|
+
node.run_state['poise_inversion'] ||= {}
|
58
|
+
node.run_state['poise_inversion'][self.class.inversion_resource] ||= {}
|
59
|
+
node.run_state['poise_inversion'][self.class.inversion_resource][resource] ||= {}
|
60
|
+
node.run_state['poise_inversion'][self.class.inversion_resource][resource][for_provider] ||= {}
|
61
|
+
node.run_state['poise_inversion'][self.class.inversion_resource][resource][for_provider].update(_options)
|
62
|
+
end
|
63
|
+
|
64
|
+
module ClassMethods
|
65
|
+
# @overload inversion_resource()
|
66
|
+
# Return the inversion resource name for this class.
|
67
|
+
# @return [Symbol]
|
68
|
+
# @overload inversion_resource(val)
|
69
|
+
# Set the inversion resource name for this class. You can pass either
|
70
|
+
# a symbol in DSL format or a resource class that uses Poise. This
|
71
|
+
# name is used to determine which resources the inversion provider is
|
72
|
+
# a candidate for.
|
73
|
+
# @param val [Symbol, Class] Name to set.
|
74
|
+
# @return [Symbol]
|
75
|
+
def inversion_resource(val=nil)
|
76
|
+
if val
|
77
|
+
val = val.resource_name if val.is_a?(Class)
|
78
|
+
Chef::Log.debug("[#{self.name}] Setting inversion resource to #{val}")
|
79
|
+
@poise_inversion_resource = val.to_sym
|
80
|
+
end
|
81
|
+
@poise_inversion_resource || (superclass.respond_to?(:inversion_resource) ? superclass.inversion_resource : nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
def included(klass)
|
86
|
+
super
|
87
|
+
klass.extend(ClassMethods)
|
88
|
+
klass.class_exec do
|
89
|
+
actions(:run)
|
90
|
+
attribute(:resource, kind_of: String, name_attribute: true)
|
91
|
+
attribute(:for_provider, kind_of: [String, Symbol], default: '*')
|
92
|
+
attribute(:_options, kind_of: Hash, default: lazy { Mash.new })
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
extend ClassMethods
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module Poise
|
19
|
+
module Helpers
|
20
|
+
# Resource mixin to allow lazyily-evaluated defaults in resource attributes.
|
21
|
+
# This is designed to be used with {LWRPPolyfill} or a similar #attributes
|
22
|
+
# method.
|
23
|
+
#
|
24
|
+
# @since 1.0.0
|
25
|
+
# @example
|
26
|
+
# class MyResource < Chef::Resource
|
27
|
+
# include Poise::Helpers::LWRPPolyfill
|
28
|
+
# include Poise::Helpers::LazyDefault
|
29
|
+
# attribute(:path, default: lazy { name + '_temp' })
|
30
|
+
# end
|
31
|
+
module LazyDefault
|
32
|
+
# Override the default set_or_return to support lazy evaluation of the
|
33
|
+
# default value. This only actually matters when it is called from a class
|
34
|
+
# level context via #attributes.
|
35
|
+
def set_or_return(symbol, arg, validation)
|
36
|
+
if validation && validation[:default].is_a?(Chef::DelayedEvaluator)
|
37
|
+
validation = validation.dup
|
38
|
+
validation[:default] = instance_eval(&validation[:default])
|
39
|
+
end
|
40
|
+
super(symbol, arg, validation)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!classmethods
|
44
|
+
module ClassMethods
|
45
|
+
# Create a lazyily-evaluated block.
|
46
|
+
#
|
47
|
+
# @param block [Proc] Callable to return the default value.
|
48
|
+
# @return [Chef::DelayedEvaluator]
|
49
|
+
def lazy(&block)
|
50
|
+
Chef::DelayedEvaluator.new(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def included(klass)
|
54
|
+
super
|
55
|
+
klass.extend(ClassMethods)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
extend ClassMethods
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise/utils/resource_provider_mixin'
|
18
|
+
|
19
|
+
|
20
|
+
module Poise
|
21
|
+
module Helpers
|
22
|
+
# A resource and provider mixin to add back some compatability with Chef's
|
23
|
+
# LWRPBase classes.
|
24
|
+
#
|
25
|
+
# @since 1.0.0
|
26
|
+
module LWRPPolyfill
|
27
|
+
include Poise::Utils::ResourceProviderMixin
|
28
|
+
|
29
|
+
# Provide default_action and actions like LWRPBase but better equipped for subclassing.
|
30
|
+
module Resource
|
31
|
+
def initialize(*args)
|
32
|
+
super
|
33
|
+
# Try to not stomp on stuff if already set in a parent
|
34
|
+
@action = self.class.default_action if @action == :nothing
|
35
|
+
(@allowed_actions << self.class.actions).flatten!.uniq!
|
36
|
+
end
|
37
|
+
|
38
|
+
# @!classmethods
|
39
|
+
module ClassMethods
|
40
|
+
def default_action(name=nil)
|
41
|
+
if name
|
42
|
+
@default_action = name
|
43
|
+
actions(name)
|
44
|
+
end
|
45
|
+
@default_action || ( respond_to?(:superclass) && superclass.respond_to?(:default_action) && superclass.default_action ) || actions.first || :nothing
|
46
|
+
end
|
47
|
+
|
48
|
+
def actions(*names)
|
49
|
+
@actions ||= ( respond_to?(:superclass) && superclass.respond_to?(:actions) ? superclass.actions.dup : [] )
|
50
|
+
(@actions << names).flatten!.uniq!
|
51
|
+
@actions
|
52
|
+
end
|
53
|
+
|
54
|
+
def attribute(name, opts)
|
55
|
+
# Ruby 1.8 can go to hell
|
56
|
+
define_method(name) do |arg=nil, &block|
|
57
|
+
arg = block if arg.nil? # Try to allow passing either
|
58
|
+
set_or_return(name, arg, opts)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def included(klass)
|
63
|
+
super
|
64
|
+
klass.extend(ClassMethods)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
extend ClassMethods
|
69
|
+
end
|
70
|
+
|
71
|
+
# Helper to handle load_current_resource for direct subclasses of Provider
|
72
|
+
module Provider
|
73
|
+
# @!classmethods
|
74
|
+
module ClassMethods
|
75
|
+
def included(klass)
|
76
|
+
super
|
77
|
+
klass.extend(ClassMethods)
|
78
|
+
|
79
|
+
# Mask Chef::Provider#load_current_resource because it throws NotImplementedError.
|
80
|
+
if klass.is_a?(Class) && klass.superclass == Chef::Provider
|
81
|
+
klass.class_exec do
|
82
|
+
def load_current_resource
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reinstate the Chef DSL, removed in Chef 12.
|
88
|
+
klass.class_exec { include Chef::DSL::Recipe }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
extend ClassMethods
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise/helpers/subcontext_block'
|
18
|
+
require 'poise/subcontext/runner'
|
19
|
+
|
20
|
+
|
21
|
+
module Poise
|
22
|
+
module Helpers
|
23
|
+
# A provider mixin to provide #notifying_block, a scoped form of Chef's
|
24
|
+
# use_inline_resources.
|
25
|
+
#
|
26
|
+
# @since 1.0.0
|
27
|
+
# @example
|
28
|
+
# class MyProvider < Chef::Provider
|
29
|
+
# include Chef::Helpers::NotifyingBlock
|
30
|
+
#
|
31
|
+
# def action_run
|
32
|
+
# notifying_block do
|
33
|
+
# template '/etc/myapp.conf' do
|
34
|
+
# # ...
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
module NotifyingBlock
|
40
|
+
include Poise::Helpers::SubcontextBlock
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Create and converge a subcontext for the recipe DSL. This is similar to
|
45
|
+
# Chef's use_inline_resources but is scoped to a block. All DSL resources
|
46
|
+
# declared inside the block will be converged when the block returns, and
|
47
|
+
# the updated_by_last_action flag will be set if any of the inner
|
48
|
+
# resources are updated.
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
# @param block [Proc] Block to run in the subcontext.
|
52
|
+
# @return [void]
|
53
|
+
# @example
|
54
|
+
# def action_run
|
55
|
+
# notifying_block do
|
56
|
+
# template '/etc/myapp.conf' do
|
57
|
+
# # ...
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
def notifying_block(&block)
|
62
|
+
# Make sure to mark the resource as updated-by-last-action if
|
63
|
+
# any sub-run-context resources were updated (any actual
|
64
|
+
# actions taken against the system) during the
|
65
|
+
# sub-run-context convergence.
|
66
|
+
begin
|
67
|
+
subcontext = subcontext_block(&block)
|
68
|
+
# Converge the new context.
|
69
|
+
Poise::Subcontext::Runner.new(new_resource, subcontext).converge
|
70
|
+
ensure
|
71
|
+
new_resource.updated_by_last_action(
|
72
|
+
subcontext && subcontext.resource_collection.any?(&:updated?)
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/mash'
|
18
|
+
|
19
|
+
|
20
|
+
module Poise
|
21
|
+
module Helpers
|
22
|
+
# A resource mixin to add a new kind of attribute, an option collector.
|
23
|
+
# These attributes can act as mini-DSLs for things which would otherwise be
|
24
|
+
# key/value pairs.
|
25
|
+
#
|
26
|
+
# @since 1.0.0
|
27
|
+
# @example Defining an option collector
|
28
|
+
# class MyResource < Chef::Resource
|
29
|
+
# include Poise::Helpers::OptionCollector
|
30
|
+
# attribute(:my_options, option_collector: true)
|
31
|
+
# end
|
32
|
+
# @example Using an option collector
|
33
|
+
# my_resource 'name' do
|
34
|
+
# my_options do
|
35
|
+
# key1 'value1'
|
36
|
+
# key2 'value2'
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
module OptionCollector
|
40
|
+
# Instance context used to eval option blocks.
|
41
|
+
# @api private
|
42
|
+
class OptionEvalContext
|
43
|
+
attr_reader :_options
|
44
|
+
|
45
|
+
def initialize(parent)
|
46
|
+
@parent = parent
|
47
|
+
@_options = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(method_sym, *args, &block)
|
51
|
+
@parent.send(method_sym, *args, &block)
|
52
|
+
rescue NameError
|
53
|
+
# Even though method= in the block will set a variable instead of
|
54
|
+
# calling method_missing, still try to cope in case of self.method=.
|
55
|
+
method_sym = method_sym.to_s.chomp('=').to_sym
|
56
|
+
if args.length > 0 || block
|
57
|
+
@_options[method_sym] = args.first || block
|
58
|
+
elsif !@_options.include?(method_sym)
|
59
|
+
# We haven't seen this name before, re-raise the NameError.
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
@_options[method_sym]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!classmethods
|
67
|
+
module ClassMethods
|
68
|
+
# Override the normal #attribute() method to support defining option
|
69
|
+
# collectors too.
|
70
|
+
def attribute(name, options={})
|
71
|
+
# If present but false-y, make sure it is removed anyway so it
|
72
|
+
# doesn't confuse ParamsValidate.
|
73
|
+
if options.delete(:option_collector)
|
74
|
+
option_collector_attribute(name, options)
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Define an option collector attribute. Normally used via {.attribute}.
|
81
|
+
#
|
82
|
+
# @param name [String, Symbol] Name of the attribute to define.
|
83
|
+
# @param default [Object] Default value for the options.
|
84
|
+
def option_collector_attribute(name, default: {})
|
85
|
+
# Unlike LWRPBase.attribute, I don't care about Ruby 1.8. Worlds tiniest violin.
|
86
|
+
define_method(name.to_sym) do |arg=nil, &block|
|
87
|
+
iv_sym = :"@#{name}"
|
88
|
+
|
89
|
+
value = instance_variable_get(iv_sym) || begin
|
90
|
+
default = instance_eval(&default) if default.is_a?(Chef::DelayedEvaluator) # Handle lazy{}
|
91
|
+
Mash.new(default) # Wrap in a mash because fuck str vs sym.
|
92
|
+
end
|
93
|
+
if arg
|
94
|
+
raise Exceptions::ValidationFailed, "Option #{name} must be a Hash" if arg && !arg.is_a?(Hash)
|
95
|
+
# Should this and the update below be a deep merge?
|
96
|
+
value.update(arg)
|
97
|
+
end
|
98
|
+
if block
|
99
|
+
ctx = OptionEvalContext.new(self)
|
100
|
+
ctx.instance_exec(&block)
|
101
|
+
value.update(ctx._options)
|
102
|
+
end
|
103
|
+
instance_variable_set(iv_sym, value)
|
104
|
+
value
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def included(klass)
|
109
|
+
super
|
110
|
+
klass.extend(ClassMethods)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
extend ClassMethods
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|