glue_gun_dsl 0.1.14 → 0.1.15
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/lib/glue_gun/dsl.rb +118 -48
- data/lib/glue_gun/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a573097a1db8e4af5573a1b0374e43dc12dcadc22f4e4a950bd6d5fe4a9084a1
|
4
|
+
data.tar.gz: 1db836fbee10ab0594495e5f137f0337ec62a8b90eeabc29bc55be0dab6ade9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad634073ed8206277b1eb502b2da7eff90e92cc820adcabc1dc647dee8e2f0c7cdf4ea7c2cc9fdd4b8a3b5f46caff7a6d4c55f82d3780a180b719af5729d4a51
|
7
|
+
data.tar.gz: 3048844dcbae257696ab142798ead0957b97bda029c151da4d9e5181b90d3da43099ecd6ec79784efb2499b0fd699a0dca2e24513e1fc20c461dae3648a4390d
|
data/lib/glue_gun/dsl.rb
CHANGED
@@ -61,7 +61,10 @@ module GlueGun
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
if attribute_definitions.keys.include?(:root_dir) && attribute_definitions.dig(:root_dir, :options,
|
65
|
+
:default).nil?
|
66
|
+
normal_attributes.reverse_merge!(root_dir: detect_root_dir)
|
67
|
+
end
|
65
68
|
|
66
69
|
# Call super to allow ActiveModel to assign attributes
|
67
70
|
super(normal_attributes)
|
@@ -98,13 +101,19 @@ module GlueGun
|
|
98
101
|
end
|
99
102
|
end
|
100
103
|
|
101
|
-
def dependency(component_type, factory_class = nil, &block)
|
102
|
-
if
|
103
|
-
|
104
|
+
def dependency(component_type, options = {}, factory_class = nil, &block)
|
105
|
+
if options.is_a?(Class)
|
106
|
+
factory_class = options
|
107
|
+
options = {}
|
108
|
+
end
|
109
|
+
is_array = options[:array] || false
|
110
|
+
|
111
|
+
if factory_class.present?
|
112
|
+
dependency_definitions[component_type] = { factory_class: factory_class, array: is_array }
|
104
113
|
else
|
105
114
|
dependency_builder = DependencyBuilder.new(component_type)
|
106
115
|
dependency_builder.instance_eval(&block)
|
107
|
-
dependency_definitions[component_type] = dependency_builder
|
116
|
+
dependency_definitions[component_type] = { builder: dependency_builder, array: is_array }
|
108
117
|
end
|
109
118
|
|
110
119
|
# Define singleton method to allow hardcoding dependencies in subclasses
|
@@ -170,16 +179,49 @@ module GlueGun
|
|
170
179
|
|
171
180
|
def initialize_dependency(component_type, init_args = {}, definition = nil)
|
172
181
|
definition ||= self.class.dependency_definitions[component_type]
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
182
|
+
is_array = definition[:array]
|
183
|
+
|
184
|
+
if is_array
|
185
|
+
dep = []
|
186
|
+
config = []
|
187
|
+
Array(init_args).each do |args|
|
188
|
+
d, c = initialize_single_dependency(component_type, args, definition)
|
189
|
+
dep.push(d)
|
190
|
+
config.push(c)
|
191
|
+
end
|
192
|
+
else
|
193
|
+
dep, config = initialize_single_dependency(component_type, init_args, definition)
|
178
194
|
end
|
179
195
|
|
180
|
-
|
196
|
+
dependencies[component_type] = {
|
197
|
+
instance: dep,
|
198
|
+
option: config
|
199
|
+
}
|
200
|
+
|
201
|
+
dep
|
202
|
+
end
|
203
|
+
|
204
|
+
def initialize_factory_dependency(component_type, init_args, definition)
|
205
|
+
factory_instance = definition[:factory_class].new
|
181
206
|
|
182
|
-
|
207
|
+
# Pass the parent instance to the factory
|
208
|
+
factory_instance.instance_variable_set(:@parent, self)
|
209
|
+
|
210
|
+
dep_defs = factory_instance.dependency_definitions
|
211
|
+
definition = dep_defs[dep_defs.keys.first]
|
212
|
+
|
213
|
+
if dep_defs.key?(component_type)
|
214
|
+
factory_instance.send(:initialize_single_dependency, component_type, init_args, definition)
|
215
|
+
elsif dep_defs.keys.one?
|
216
|
+
factory_instance.send(:initialize_single_dependency, dep_defs.keys.first, init_args, definition)
|
217
|
+
else
|
218
|
+
raise ArgumentError,
|
219
|
+
"Don't know how to use Factory #{factory_instance.class} to build dependency '#{component_type}'"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def initialize_builder_dependency(component_type, init_args, definition)
|
224
|
+
dependency_builder = definition[:builder]
|
183
225
|
|
184
226
|
if init_args && init_args.is_a?(Hash) && init_args.key?(:option_name)
|
185
227
|
option_name = init_args[:option_name]
|
@@ -192,30 +234,24 @@ module GlueGun
|
|
192
234
|
|
193
235
|
raise ArgumentError, "Unknown #{component_type} option '#{option_name}'" unless option_config
|
194
236
|
|
195
|
-
|
196
|
-
|
197
|
-
# Build dependency attributes, including sourcing from parent
|
198
|
-
dep_attributes = build_dependency_attributes(option_config, dep_attributes)
|
237
|
+
[instantiate_dependency(option_config, init_args), option_config]
|
238
|
+
end
|
199
239
|
|
200
|
-
|
201
|
-
|
202
|
-
|
240
|
+
def initialize_single_dependency(component_type, init_args, definition)
|
241
|
+
if dependency_injected?(component_type, init_args)
|
242
|
+
dep = init_args
|
243
|
+
option_config = injected_dependency(component_type, init_args)
|
244
|
+
elsif definition[:factory_class]
|
245
|
+
dep, option_config = initialize_factory_dependency(component_type, init_args, definition)
|
246
|
+
else
|
247
|
+
dep, option_config = initialize_builder_dependency(component_type, init_args, definition)
|
203
248
|
end
|
204
249
|
|
205
|
-
|
206
|
-
|
207
|
-
# Keep track of dependencies for attribute binding
|
208
|
-
dependencies[component_type] = {
|
209
|
-
instance: dependency_instance,
|
210
|
-
option: option_config
|
211
|
-
}
|
212
|
-
|
213
|
-
dependency_instance
|
250
|
+
[dep, option_config]
|
214
251
|
end
|
215
252
|
|
216
253
|
def build_dependency_attributes(option_config, dep_attributes)
|
217
254
|
option_config.attributes.each do |attr_name, attr_config|
|
218
|
-
# If the attribute is already provided, use it
|
219
255
|
if dep_attributes.key?(attr_name)
|
220
256
|
value = dep_attributes[attr_name]
|
221
257
|
else
|
@@ -223,6 +259,8 @@ module GlueGun
|
|
223
259
|
send(attr_config.source)
|
224
260
|
elsif respond_to?(attr_name)
|
225
261
|
send(attr_name)
|
262
|
+
elsif instance_variable_defined?(:@parent) && @parent.respond_to?(attr_name)
|
263
|
+
@parent.send(attr_name)
|
226
264
|
else
|
227
265
|
attr_config.default
|
228
266
|
end
|
@@ -235,7 +273,7 @@ module GlueGun
|
|
235
273
|
end
|
236
274
|
|
237
275
|
def determine_option_name(component_type, init_args)
|
238
|
-
dependency_builder = self.class.dependency_definitions[component_type]
|
276
|
+
dependency_builder = self.class.dependency_definitions[component_type][:builder]
|
239
277
|
|
240
278
|
option_name = nil
|
241
279
|
|
@@ -269,11 +307,18 @@ module GlueGun
|
|
269
307
|
[option_name, init_args]
|
270
308
|
end
|
271
309
|
|
272
|
-
def instantiate_dependency(option_config,
|
310
|
+
def instantiate_dependency(option_config, init_args)
|
311
|
+
dep_attributes = init_args.is_a?(Hash) ? init_args : {}
|
312
|
+
|
313
|
+
# Build dependency attributes, including sourcing from parent
|
314
|
+
dep_attributes = build_dependency_attributes(option_config, dep_attributes)
|
315
|
+
|
316
|
+
if dep_attributes.key?(:id)
|
317
|
+
raise ArgumentError,
|
318
|
+
"cannot bind attribute 'id' between #{self.class.name} and #{option_config.class_name}. ID is reserved for primary keys in Ruby on Rails"
|
319
|
+
end
|
273
320
|
dependency_class = option_config.class_name
|
274
|
-
|
275
|
-
dependency_instance.validate! if false # dependency_instance.respond_to?(:validate!)
|
276
|
-
dependency_instance
|
321
|
+
dependency_class.new(dep_attributes)
|
277
322
|
end
|
278
323
|
|
279
324
|
def propagate_changes
|
@@ -287,33 +332,58 @@ module GlueGun
|
|
287
332
|
end
|
288
333
|
|
289
334
|
def propagate_attribute_change(attr_name, value)
|
290
|
-
self.class.dependency_definitions.each do |component_type,
|
335
|
+
self.class.dependency_definitions.each do |component_type, _builder|
|
291
336
|
dependency_instance = send(component_type)
|
292
|
-
option_config = dependencies.dig(component_type, :option)
|
293
|
-
next unless option_config
|
294
337
|
|
295
|
-
|
296
|
-
|
297
|
-
end
|
338
|
+
if dependency_instance.is_a?(Array)
|
339
|
+
option_config = dependencies.dig(component_type, :option)
|
298
340
|
|
299
|
-
|
300
|
-
|
301
|
-
if dependency_instance.respond_to?("#{dep_attr_name}=")
|
302
|
-
dependency_instance.send("#{dep_attr_name}=",
|
303
|
-
block.call(value))
|
341
|
+
dependency_instance.zip(option_config).each do |dep, opt|
|
342
|
+
propagate_attribute_to_instance(attr_name, value, dep, opt)
|
304
343
|
end
|
344
|
+
else
|
345
|
+
option_config = dependencies.dig(component_type, :option)
|
346
|
+
next unless option_config
|
347
|
+
|
348
|
+
propagate_attribute_to_instance(attr_name, value, dependency_instance, option_config)
|
305
349
|
end
|
306
350
|
end
|
307
351
|
end
|
308
352
|
|
309
|
-
def
|
310
|
-
|
311
|
-
|
353
|
+
def propagate_attribute_to_instance(attr_name, value, dependency_instance, option_config)
|
354
|
+
bound_attrs = option_config.attributes.select do |_, attr_config|
|
355
|
+
(attr_config.source == attr_name.to_sym) || (attr_config.name == attr_name.to_sym)
|
356
|
+
end
|
357
|
+
|
358
|
+
bound_attrs.each do |dep_attr_name, config_attr|
|
359
|
+
block = config_attr.block.present? ? config_attr.block : proc { |att| att }
|
360
|
+
if dependency_instance.respond_to?("#{dep_attr_name}=")
|
361
|
+
dependency_instance.send("#{dep_attr_name}=",
|
362
|
+
block.call(value))
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def injected_dependency(component_type, value)
|
368
|
+
definition = self.class.dependency_definitions[component_type]
|
369
|
+
builder = definition[:builder]
|
370
|
+
factory = definition[:factory_class]
|
371
|
+
|
372
|
+
option_configs = if builder
|
373
|
+
builder.option_configs
|
374
|
+
else
|
375
|
+
factory.dependency_definitions.values.first.values.first.option_configs
|
376
|
+
end
|
377
|
+
option_configs.values.select do |option|
|
312
378
|
option_class = option.class_name
|
313
379
|
value.is_a?(option_class)
|
314
380
|
end
|
315
381
|
end
|
316
382
|
|
383
|
+
def dependency_injected?(component_type, value)
|
384
|
+
injected_dependency(component_type, value).any?
|
385
|
+
end
|
386
|
+
|
317
387
|
def dependencies
|
318
388
|
@dependencies ||= {}
|
319
389
|
end
|
data/lib/glue_gun/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glue_gun_dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Shollenberger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|