poise-derived 0 → 1.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 +4 -4
- data/.gitignore +11 -0
- data/.kitchen.yml +3 -0
- data/.travis.yml +40 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +32 -0
- data/LICENSE +201 -0
- data/README.md +110 -0
- data/Rakefile +17 -0
- data/chef/recipes/default.rb +17 -0
- data/lib/poise_derived.rb +22 -0
- data/lib/poise_derived/cheftie.rb +18 -0
- data/lib/poise_derived/core_ext.rb +28 -0
- data/lib/poise_derived/core_ext/deep_merge.rb +55 -0
- data/lib/poise_derived/core_ext/string.rb +35 -0
- data/lib/poise_derived/dsl.rb +45 -0
- data/lib/poise_derived/handler.rb +43 -0
- data/lib/poise_derived/lazy_attribute.rb +125 -0
- data/lib/poise_derived/version.rb +20 -0
- data/poise-derived.gemspec +41 -0
- data/test/cookbook/attributes/default.rb +46 -0
- data/test/cookbook/metadata.rb +18 -0
- data/test/cookbook/recipes/default.rb +28 -0
- data/test/gemfiles/chef-12.10.gemfile +20 -0
- data/test/gemfiles/chef-12.11.gemfile +20 -0
- data/test/gemfiles/chef-12.12.gemfile +19 -0
- data/test/gemfiles/chef-12.13.gemfile +19 -0
- data/test/gemfiles/chef-12.14.gemfile +19 -0
- data/test/gemfiles/chef-12.3.gemfile +20 -0
- data/test/gemfiles/chef-12.4.gemfile +21 -0
- data/test/gemfiles/chef-12.5.gemfile +20 -0
- data/test/gemfiles/chef-12.6.gemfile +20 -0
- data/test/gemfiles/chef-12.7.gemfile +20 -0
- data/test/gemfiles/chef-12.8.gemfile +20 -0
- data/test/gemfiles/chef-12.9.gemfile +20 -0
- data/test/gemfiles/chef-12.gemfile +19 -0
- data/test/gemfiles/master.gemfile +21 -0
- data/test/integration/default/serverspec/default_spec.rb +35 -0
- data/test/spec/lazy_attribute_spec.rb +158 -0
- data/test/spec/spec_helper.rb +21 -0
- metadata +123 -8
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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 PoiseDerived
|
19
|
+
autoload :DSL, 'poise_derived/dsl'
|
20
|
+
autoload :LazyAttribute, 'poise_derived/lazy_attribute'
|
21
|
+
autoload :VERSION, 'poise_derived/version'
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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_derived/core_ext'
|
18
|
+
require 'poise_derived/handler'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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_derived/core_ext/deep_merge'
|
18
|
+
require 'poise_derived/core_ext/string'
|
19
|
+
|
20
|
+
|
21
|
+
module PoiseDerived
|
22
|
+
# Here be dragons.
|
23
|
+
#
|
24
|
+
# @since 1.0.0
|
25
|
+
# @api private
|
26
|
+
module CoreExt
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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/mixin/deep_merge'
|
18
|
+
|
19
|
+
require 'poise_derived/lazy_attribute'
|
20
|
+
|
21
|
+
|
22
|
+
module PoiseDerived
|
23
|
+
module CoreExt
|
24
|
+
# Monkey-patch deep merge to carry over LazyAttribute on override. This means
|
25
|
+
# that if a lazy is set in a cookbook and then that attribute is overridden
|
26
|
+
# in a role or another cookbook, the override value gets wrapped in a
|
27
|
+
# LazyAttribute too so it will act as a template string. There is no way to
|
28
|
+
# put a block in JSON data so that would have to be explicit.
|
29
|
+
#
|
30
|
+
# @since 1.0.0
|
31
|
+
# @api private
|
32
|
+
module DeepMerge
|
33
|
+
def deep_merge!(source, dest)
|
34
|
+
if source.is_a?(PoiseDerived::LazyAttribute) && dest.is_a?(String)
|
35
|
+
source._override(dest)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def hash_only_merge!(merge_onto, merge_with)
|
42
|
+
if merge_onto.is_a?(PoiseDerived::LazyAttribute) && merge_with.is_a?(String)
|
43
|
+
merge_onto._override(merge_with)
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Kinder, gentler monkey patching. The singleton_class is the important
|
50
|
+
# one since everything in Chef calls these are module methods.
|
51
|
+
Chef::Mixin::DeepMerge.prepend(self)
|
52
|
+
Chef::Mixin::DeepMerge.singleton_class.prepend(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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_derived/lazy_attribute'
|
18
|
+
|
19
|
+
|
20
|
+
# Monkeypatch String so that our magic works in case statements. If you're
|
21
|
+
# reading this, something has probably gone wrong. I'm so sorry.
|
22
|
+
#
|
23
|
+
# @since 1.0.0
|
24
|
+
# @api private
|
25
|
+
class String
|
26
|
+
old_method = method(:===)
|
27
|
+
define_singleton_method(:===) do |obj|
|
28
|
+
if obj.class <= ::PoiseDerived::LazyAttribute
|
29
|
+
true
|
30
|
+
else
|
31
|
+
old_method.call(obj)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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/node'
|
18
|
+
|
19
|
+
require 'poise_derived/lazy_attribute'
|
20
|
+
|
21
|
+
|
22
|
+
module PoiseDerived
|
23
|
+
module DSL
|
24
|
+
def _lazy_attribute(str=nil, &block)
|
25
|
+
PoiseDerived::LazyAttribute.new(self, str, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Install the DSL addition globally.
|
29
|
+
#
|
30
|
+
# @return [void]
|
31
|
+
def self.install
|
32
|
+
Chef::Log.debug('[poise-derived] Installing node DSL')
|
33
|
+
Chef::Node.prepend(self)
|
34
|
+
alias_method(:lazy, :_lazy_attribute)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Disable the DSL extension so `node.lazy` will no longer work.
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def self.uninstall
|
41
|
+
Chef::Log.debug('[poise-derived] Uninstalling node DSL')
|
42
|
+
remove_method(:lazy)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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/chef_class'
|
18
|
+
require 'chef/event_dispatch/base'
|
19
|
+
|
20
|
+
require 'poise_derived/dsl'
|
21
|
+
|
22
|
+
|
23
|
+
module PoiseDerived
|
24
|
+
# A small event handler to install and uninstall our DSL addition so it only
|
25
|
+
# appears during attribute compilation. Is this a good idea?
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
class Handler < Chef::EventDispatch::Base
|
29
|
+
include Singleton
|
30
|
+
|
31
|
+
def attribute_load_start(count)
|
32
|
+
PoiseDerived::DSL.install
|
33
|
+
end
|
34
|
+
|
35
|
+
def attribute_load_complete
|
36
|
+
PoiseDerived::DSL.uninstall
|
37
|
+
end
|
38
|
+
|
39
|
+
# Install event handler.
|
40
|
+
Chef::Log.debug('[poise-derived] Installing event handler')
|
41
|
+
Chef.run_context.events.register(self.instance)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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 PoiseDerived
|
19
|
+
# A class to lazily evaluate node attributes either from format strings or
|
20
|
+
# code blocks.
|
21
|
+
#
|
22
|
+
# @example Cookbook attributes file
|
23
|
+
# default['mycookbook']['version'] = '1.0'
|
24
|
+
# default['mycookbook']['url'] = lazy 'https://example.com/myapp-%{mycookbook.version}.zip'
|
25
|
+
class LazyAttribute
|
26
|
+
# Parser regexp for format strings.
|
27
|
+
# @api private
|
28
|
+
FORMAT_STRING_REGEXP = /%\{([^}]+)\}/
|
29
|
+
|
30
|
+
def initialize(node, str=nil, &block)
|
31
|
+
unless (!!str) ^ (!!block)
|
32
|
+
raise ArgumentError.new('Either a string or block must be passed when creating a lazy attribute')
|
33
|
+
end
|
34
|
+
@node = node
|
35
|
+
@value = str || block
|
36
|
+
end
|
37
|
+
|
38
|
+
# Shorter inspect output for debugging so we don't vomit the node into the
|
39
|
+
# log or spec output.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def inspect
|
43
|
+
if @value.is_a?(Proc)
|
44
|
+
"#<#{self.class.name} @value=proc>"
|
45
|
+
else
|
46
|
+
"#<#{self.class.name} @value=#{@value.inspect}>"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Return a copy of this attribute with the same node context but an
|
51
|
+
# override value as the format string. This can't support blocks because of
|
52
|
+
# how it is called generally.
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
# @see PoiseDerived::CoreExt
|
56
|
+
# @return [PoiseDerived::LazyAttribute]
|
57
|
+
def _override(str)
|
58
|
+
self.class.new(@node, str)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @!group delegators
|
62
|
+
# Delegate to the lazy value.
|
63
|
+
# @api private
|
64
|
+
def method_missing(method, *args, &block)
|
65
|
+
_evaluate.send(method, *args, &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Delegate to the lazy value.
|
69
|
+
# @api private
|
70
|
+
def respond_to_missing?(method, include_all)
|
71
|
+
_evaluate.respond_to?(method, include_all)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Delegate to the lazy value.
|
75
|
+
# @api private
|
76
|
+
def to_s
|
77
|
+
_evaluate.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
# Make sure we implement to_str because that activates the == hack.
|
81
|
+
# @api private
|
82
|
+
def to_str
|
83
|
+
to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# Fake is_a? and kind_of? for params_validate and `_pv_kind_of`.
|
87
|
+
# @api private
|
88
|
+
def is_a?(klass)
|
89
|
+
return true if Object.instance_method(:is_a?).bind(self).call(klass)
|
90
|
+
klass <= String
|
91
|
+
end
|
92
|
+
|
93
|
+
# @api private
|
94
|
+
# @see is_a?
|
95
|
+
alias_method :kind_of?, :is_a?
|
96
|
+
|
97
|
+
# Specifically delegate == because not caught by method_missing.
|
98
|
+
# @api private
|
99
|
+
def ==(other)
|
100
|
+
_evaluate == other
|
101
|
+
end
|
102
|
+
# !@endgroup
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Evaluate the lazy attribute.
|
107
|
+
#
|
108
|
+
# @return [Object]
|
109
|
+
def _evaluate
|
110
|
+
return @evaluate_cache if defined?(@evaluate_cache)
|
111
|
+
@evaluate_cache = if @value.is_a?(Proc)
|
112
|
+
# Block mode, just run the block.
|
113
|
+
@node.instance_eval(&@value).to_s
|
114
|
+
else
|
115
|
+
# String mode, parse the template string and fill it in.
|
116
|
+
format_keys = @value.scan(FORMAT_STRING_REGEXP).inject({}) do |memo, (key)|
|
117
|
+
# Keys must be symbols because Ruby.
|
118
|
+
memo[key.to_sym] = key.split(/\./).inject(@node) {|n, k| n.nil? ? n : n[k] }
|
119
|
+
memo
|
120
|
+
end
|
121
|
+
@value % format_keys
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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 PoiseDerived
|
19
|
+
VERSION = '1.0.0'
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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
|
+
lib = File.expand_path('../lib', __FILE__)
|
18
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
19
|
+
require 'poise_derived/version'
|
20
|
+
|
21
|
+
Gem::Specification.new do |spec|
|
22
|
+
spec.name = 'poise-derived'
|
23
|
+
spec.version = PoiseDerived::VERSION
|
24
|
+
spec.authors = ['Noah Kantrowitz']
|
25
|
+
spec.email = %w{noah@coderanger.net}
|
26
|
+
spec.description = 'A Chef cookbook for defining lazily evaluated node attributes.'
|
27
|
+
spec.summary = spec.description
|
28
|
+
spec.homepage = 'https://github.com/poise/poise-derived'
|
29
|
+
spec.license = 'Apache 2.0'
|
30
|
+
|
31
|
+
spec.files = `git ls-files`.split($/)
|
32
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
33
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
34
|
+
spec.require_paths = %w{lib}
|
35
|
+
|
36
|
+
spec.add_dependency 'chef', '~> 12.3'
|
37
|
+
spec.add_dependency 'halite', '~> 1.0'
|
38
|
+
|
39
|
+
spec.add_development_dependency 'poise', '~> 2.0'
|
40
|
+
spec.add_development_dependency 'poise-boiler', '~> 1.0'
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, 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
|
+
# Baseline for sanity.
|
18
|
+
default['a']['value'] = 'a'
|
19
|
+
|
20
|
+
default['b']['value'] = lazy 'b'
|
21
|
+
|
22
|
+
default['c']['one'] = '1'
|
23
|
+
default['c']['value'] = lazy '%{c.one}'
|
24
|
+
|
25
|
+
default['d']['value'] = lazy { 'd' }
|
26
|
+
|
27
|
+
default['e']['one'] = 1
|
28
|
+
default['e']['two'] = '2'
|
29
|
+
default['e']['value'] = lazy '%{e.one} %{e.two}'
|
30
|
+
|
31
|
+
# This value is changed later.
|
32
|
+
default['f']['one'] = '1'
|
33
|
+
default['f']['value'] = lazy '%{f.one}'
|
34
|
+
|
35
|
+
# This value is changed later.
|
36
|
+
default['g']['one'] = '1'
|
37
|
+
default['g']['value'] = lazy { node['g']['one'] }
|
38
|
+
|
39
|
+
# This template is changed later.
|
40
|
+
default['h']['one'] = '1'
|
41
|
+
default['h']['two'] = '2'
|
42
|
+
default['h']['value'] = lazy 'one %{h.one}'
|
43
|
+
|
44
|
+
default['i']['one'] = '1'
|
45
|
+
default['i']['two'] = lazy 'one %{i.one}'
|
46
|
+
default['i']['value'] = lazy 'two %{i.two} 2'
|