Class: Builderator::Config::Attributes
- Inherits:
-
Object
- Object
- Builderator::Config::Attributes
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/builderator/config/attributes.rb
Overview
Shared Attribute Mixin
Direct Known Subclasses
Defined Under Namespace
Classes: Collection, Namespace
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
-
#extends ⇒ Object
readonly
Returns the value of attribute extends.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
Class Method Summary collapse
- .attribute(attribute_name, default = nil, **options) ⇒ Object
-
.collection(collection_name, &definition) ⇒ Object
A Collection is a named-set of items in a sub-node of the attribute-set.
-
.namespace(namespace_name, &definition) ⇒ Object
A Namespace is a singleton sub-node of the attribute-set.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#clean ⇒ Object
Clear dirty state flag.
- #compile(evaluate = true) ⇒ Object
-
#dirty(update = false) ⇒ Object
All dirty state should aggregate at the root node.
- #dirty!(set) ⇒ Object
-
#initialize(attributes = {}, options = {}, &block) ⇒ Attributes
constructor
A new instance of Attributes.
- #merge(other) ⇒ Object
- #reset! ⇒ Object
-
#root ⇒ Object
Get the root Attributes object.
- #root? ⇒ Boolean
- #seal ⇒ Object
- #to_json(*_) ⇒ Object
- #unseal ⇒ Object
Constructor Details
#initialize(attributes = {}, options = {}, &block) ⇒ Attributes
Returns a new instance of Attributes.
178 179 180 181 182 183 184 185 186 187 |
# File 'lib/builderator/config/attributes.rb', line 178 def initialize(attributes = {}, = {}, &block) @attributes = Rash.coerce(attributes) @nodes = {} @block = block ## Track change status for consumers @parent = .fetch(:parent, self) @extends = [:extends] @dirty = false end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
173 174 175 |
# File 'lib/builderator/config/attributes.rb', line 173 def attributes @attributes end |
#extends ⇒ Object (readonly)
Returns the value of attribute extends.
176 177 178 |
# File 'lib/builderator/config/attributes.rb', line 176 def extends @extends end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
174 175 176 |
# File 'lib/builderator/config/attributes.rb', line 174 def nodes @nodes end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
175 176 177 |
# File 'lib/builderator/config/attributes.rb', line 175 def parent @parent end |
Class Method Details
.attribute(attribute_name, default = nil, **options) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/builderator/config/attributes.rb', line 17 def attribute(attribute_name, default = nil, **) ## # Helpers for Array-type attributes ## if [:type] == :list define_method(attribute_name) do |*arg, **| ## Instantiate List if it doesn't exist yet. `||=` will always return a new Rash. @attributes[attribute_name] = Config::List.new() unless @attributes.has?(attribute_name, Config::List) @attributes[attribute_name].set(*arg.flatten) unless arg.empty? @attributes[attribute_name] end define_method([:singular]) do |*arg, **| send(attribute_name, ).push(*arg.flatten) end if .include?(:singular) return end ## # Helpers for Hash-type attributes ## if [:type] == :hash define_method(attribute_name) do |arg = nil| ## Instantiate List if it doesn't exist yet. `||=` will always return a new Rash. @attributes[attribute_name] = Config::Rash.new unless @attributes.has?(attribute_name, Config::Rash) dirty(@attributes[attribute_name].merge!(Config::Rash.coerce(arg)).any?) unless arg.nil? @attributes[attribute_name] end return end ## Getter/Setter define_method(attribute_name) do |*arg| set_or_return(attribute_name, arg.first, default, ) end ## Setter define_method("#{attribute_name}=") do |arg| set_if_valid(attribute_name, arg, ) end end |
.collection(collection_name, &definition) ⇒ Object
A Collection is a named-set of items in a sub-node of the attribute-set.
Like Namespaces, Collections map to a top-level key, but they also have multiple second-order keys:
e.g. ‘collection :vagrant …` adds a DSL method `vagrant(name = :default, &block)` which maps to `attributes[<name>]`
Multiple entities can be added to the collection by calling the DSL method with unique ‘name` arguments. Multiple calls to the DSL method with the same name argument will update the existing entity in place
An entry can be defined as an extension of another node by passing a hash as the instance name: ‘name => Config.node(:name)`. This will use the values defined in `Config.node(:name)` as defaults for the new entry
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/builderator/config/attributes.rb', line 108 def collection(collection_name, &definition) collection_class = Collection.create(collection_name, &definition) define_method(collection_name) do |instance_name = nil, &block| extension_base = nil ## Allow extension to be defined as a key-value if instance_name.is_a?(Hash) extension_base = instance_name.first.last instance_name = instance_name.first.first end nodes[collection_name] ||= collection_class.new( @attributes[collection_name], :parent => self) return nodes[collection_name] if instance_name.nil? nodes[collection_name].fetch(instance_name, :extends => extension_base, &block) end end |
.namespace(namespace_name, &definition) ⇒ Object
A Namespace is a singleton sub-node of the attribute-set
e.g. ‘namespace :chef …` maps to `attributes` and adds a method `chef(&block)` to the DSL which is used as follows:
“‘ chef do
run_list 'foo', 'bar'
...
end “‘
Multiple calls to the DSL method are safe and will update the same sub-node.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/builderator/config/attributes.rb', line 79 def namespace(namespace_name, &definition) namespace_class = Namespace.create(namespace_name, &definition) define_method(namespace_name) do |&block| nodes[namespace_name] ||= namespace_class.new( @attributes[namespace_name], :name => namespace_name, :parent => self, &block) end end |
Instance Method Details
#==(other) ⇒ Object
169 170 171 |
# File 'lib/builderator/config/attributes.rb', line 169 def ==(other) attributes == other.attributes end |
#clean ⇒ Object
Clear dirty state flag
190 191 192 |
# File 'lib/builderator/config/attributes.rb', line 190 def clean @dirty = false end |
#compile(evaluate = true) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/builderator/config/attributes.rb', line 200 def compile(evaluate = true) ## Underlay base values if present if extends.is_a?(Attributes) previous_state = attributes dirty_state = dirty attributes.merge!(extends.attributes) @block.call(self) if @block && evaluate nodes.each { |_, node| node.compile } root.dirty!(dirty_state || previous_state.diff(attributes).any?) return self end ## Compile this node and its children @block.call(self) if @block && evaluate nodes.each { |_, node| node.compile } self end |
#dirty(update = false) ⇒ Object
All dirty state should aggregate at the root node
160 161 162 163 |
# File 'lib/builderator/config/attributes.rb', line 160 def dirty(update = false) return @dirty ||= update if root? root.dirty(update) end |
#dirty!(set) ⇒ Object
165 166 167 |
# File 'lib/builderator/config/attributes.rb', line 165 def dirty!(set) @dirty = set end |
#merge(other) ⇒ Object
223 224 225 226 |
# File 'lib/builderator/config/attributes.rb', line 223 def merge(other) dirty(attributes.merge!(other.attributes).any?) self end |
#reset! ⇒ Object
194 195 196 197 198 |
# File 'lib/builderator/config/attributes.rb', line 194 def reset! @attributes = Config::Rash.new @nodes = {} @dirty = false end |
#root ⇒ Object
Get the root Attributes object
149 150 151 152 153 |
# File 'lib/builderator/config/attributes.rb', line 149 def root return self if root? parent.root end |
#root? ⇒ Boolean
155 156 157 |
# File 'lib/builderator/config/attributes.rb', line 155 def root? parent == self end |
#seal ⇒ Object
138 139 140 141 |
# File 'lib/builderator/config/attributes.rb', line 138 def seal attributes.seal self end |
#to_json(*_) ⇒ Object
228 229 230 |
# File 'lib/builderator/config/attributes.rb', line 228 def to_json(*_) JSON.pretty_generate(to_hash) end |
#unseal ⇒ Object
143 144 145 146 |
# File 'lib/builderator/config/attributes.rb', line 143 def unseal attributes.unseal self end |