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.
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/builderator/config/attributes.rb', line 181 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.
176 177 178 |
# File 'lib/builderator/config/attributes.rb', line 176 def attributes @attributes end |
#extends ⇒ Object (readonly)
Returns the value of attribute extends.
179 180 181 |
# File 'lib/builderator/config/attributes.rb', line 179 def extends @extends end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
177 178 179 |
# File 'lib/builderator/config/attributes.rb', line 177 def nodes @nodes end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
178 179 180 |
# File 'lib/builderator/config/attributes.rb', line 178 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 62 63 64 |
# 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) unless arg.empty? @attributes[attribute_name].set(*arg.flatten) @attributes[attribute_name].set(*arg) if [:flatten] == false end @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
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/builderator/config/attributes.rb', line 111 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.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/builderator/config/attributes.rb', line 82 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
172 173 174 |
# File 'lib/builderator/config/attributes.rb', line 172 def ==(other) attributes == other.attributes end |
#clean ⇒ Object
Clear dirty state flag
193 194 195 |
# File 'lib/builderator/config/attributes.rb', line 193 def clean @dirty = false end |
#compile(evaluate = true) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/builderator/config/attributes.rb', line 203 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
163 164 165 166 |
# File 'lib/builderator/config/attributes.rb', line 163 def dirty(update = false) return @dirty ||= update if root? root.dirty(update) end |
#dirty!(set) ⇒ Object
168 169 170 |
# File 'lib/builderator/config/attributes.rb', line 168 def dirty!(set) @dirty = set end |
#merge(other) ⇒ Object
226 227 228 229 |
# File 'lib/builderator/config/attributes.rb', line 226 def merge(other) dirty(attributes.merge!(other.attributes).any?) self end |
#reset! ⇒ Object
197 198 199 200 201 |
# File 'lib/builderator/config/attributes.rb', line 197 def reset! @attributes = Config::Rash.new @nodes = {} @dirty = false end |
#root ⇒ Object
Get the root Attributes object
152 153 154 155 156 |
# File 'lib/builderator/config/attributes.rb', line 152 def root return self if root? parent.root end |
#root? ⇒ Boolean
158 159 160 |
# File 'lib/builderator/config/attributes.rb', line 158 def root? parent == self end |
#seal ⇒ Object
141 142 143 144 |
# File 'lib/builderator/config/attributes.rb', line 141 def seal attributes.seal self end |
#to_json(*_) ⇒ Object
231 232 233 |
# File 'lib/builderator/config/attributes.rb', line 231 def to_json(*_) JSON.pretty_generate(to_hash) end |
#unseal ⇒ Object
146 147 148 149 |
# File 'lib/builderator/config/attributes.rb', line 146 def unseal attributes.unseal self end |