glue_gun_dsl 0.1.14 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/glue_gun/dsl.rb +134 -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: cc6aaef2a48bc81e0383a4b88f0afc691a3f99097e12877579c7d579953cfea7
|
4
|
+
data.tar.gz: ceb228b7381a0fbc7e2b3c07fe650cc05d89524dcec7199490fafb8813117bcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7624649374c85a5822bb6a74096e50c69947db98bd1097ec020e3e82edde37c35a9057905534271da63385ef1c37d43b479712d0442247837151c0ab23ef9cbc
|
7
|
+
data.tar.gz: 1f18555d5938dc3fb16bed600e3216502601e0b97c8a7c0998b22dd636cea40263f5ec7225767232e873778690c5ca0d752786c4e5017b371c35b17d191277aa
|
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,20 @@ 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
|
+
is_hash = options[:hash] || false
|
111
|
+
|
112
|
+
if factory_class.present?
|
113
|
+
dependency_definitions[component_type] = { factory_class: factory_class, array: is_array, hash: is_hash }
|
104
114
|
else
|
105
115
|
dependency_builder = DependencyBuilder.new(component_type)
|
106
116
|
dependency_builder.instance_eval(&block)
|
107
|
-
dependency_definitions[component_type] = dependency_builder
|
117
|
+
dependency_definitions[component_type] = { builder: dependency_builder, array: is_array, hash: is_hash }
|
108
118
|
end
|
109
119
|
|
110
120
|
# Define singleton method to allow hardcoding dependencies in subclasses
|
@@ -170,16 +180,58 @@ module GlueGun
|
|
170
180
|
|
171
181
|
def initialize_dependency(component_type, init_args = {}, definition = nil)
|
172
182
|
definition ||= self.class.dependency_definitions[component_type]
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
183
|
+
is_array = definition[:array]
|
184
|
+
is_hash = definition[:hash]
|
185
|
+
|
186
|
+
if is_array
|
187
|
+
dep = []
|
188
|
+
config = []
|
189
|
+
Array(init_args).each do |args|
|
190
|
+
d, c = initialize_single_dependency(component_type, args, definition)
|
191
|
+
dep.push(d)
|
192
|
+
config.push(c)
|
193
|
+
end
|
194
|
+
elsif is_hash
|
195
|
+
dep = {}
|
196
|
+
config = {}
|
197
|
+
init_args.each do |key, args|
|
198
|
+
d, c = initialize_single_dependency(component_type, args, definition)
|
199
|
+
dep[key] = d
|
200
|
+
config[key] = c
|
201
|
+
end
|
202
|
+
else
|
203
|
+
dep, config = initialize_single_dependency(component_type, init_args, definition)
|
178
204
|
end
|
179
205
|
|
180
|
-
|
206
|
+
dependencies[component_type] = {
|
207
|
+
instance: dep,
|
208
|
+
option: config
|
209
|
+
}
|
210
|
+
|
211
|
+
dep
|
212
|
+
end
|
213
|
+
|
214
|
+
def initialize_factory_dependency(component_type, init_args, definition)
|
215
|
+
factory_instance = definition[:factory_class].new
|
216
|
+
|
217
|
+
# Pass the parent instance to the factory
|
218
|
+
factory_instance.instance_variable_set(:@parent, self)
|
219
|
+
|
220
|
+
dep_defs = factory_instance.dependency_definitions
|
221
|
+
definition = dep_defs[dep_defs.keys.first]
|
181
222
|
|
182
|
-
|
223
|
+
if dep_defs.key?(component_type)
|
224
|
+
factory_instance.send(:initialize_single_dependency, component_type, init_args, definition)
|
225
|
+
elsif dep_defs.keys.one?
|
226
|
+
factory_instance.send(:initialize_single_dependency, dep_defs.keys.first, init_args, definition)
|
227
|
+
else
|
228
|
+
raise ArgumentError,
|
229
|
+
"Don't know how to use Factory #{factory_instance.class} to build dependency '#{component_type}'"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def initialize_builder_dependency(component_type, init_args, definition)
|
234
|
+
dependency_builder = definition[:builder]
|
183
235
|
|
184
236
|
if init_args && init_args.is_a?(Hash) && init_args.key?(:option_name)
|
185
237
|
option_name = init_args[:option_name]
|
@@ -192,30 +244,24 @@ module GlueGun
|
|
192
244
|
|
193
245
|
raise ArgumentError, "Unknown #{component_type} option '#{option_name}'" unless option_config
|
194
246
|
|
195
|
-
|
196
|
-
|
197
|
-
# Build dependency attributes, including sourcing from parent
|
198
|
-
dep_attributes = build_dependency_attributes(option_config, dep_attributes)
|
247
|
+
[instantiate_dependency(option_config, init_args), option_config]
|
248
|
+
end
|
199
249
|
|
200
|
-
|
201
|
-
|
202
|
-
|
250
|
+
def initialize_single_dependency(component_type, init_args, definition)
|
251
|
+
if dependency_injected?(component_type, init_args)
|
252
|
+
dep = init_args
|
253
|
+
option_config = injected_dependency(component_type, init_args)
|
254
|
+
elsif definition[:factory_class]
|
255
|
+
dep, option_config = initialize_factory_dependency(component_type, init_args, definition)
|
256
|
+
else
|
257
|
+
dep, option_config = initialize_builder_dependency(component_type, init_args, definition)
|
203
258
|
end
|
204
259
|
|
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
|
260
|
+
[dep, option_config]
|
214
261
|
end
|
215
262
|
|
216
263
|
def build_dependency_attributes(option_config, dep_attributes)
|
217
264
|
option_config.attributes.each do |attr_name, attr_config|
|
218
|
-
# If the attribute is already provided, use it
|
219
265
|
if dep_attributes.key?(attr_name)
|
220
266
|
value = dep_attributes[attr_name]
|
221
267
|
else
|
@@ -223,6 +269,8 @@ module GlueGun
|
|
223
269
|
send(attr_config.source)
|
224
270
|
elsif respond_to?(attr_name)
|
225
271
|
send(attr_name)
|
272
|
+
elsif instance_variable_defined?(:@parent) && @parent.respond_to?(attr_name)
|
273
|
+
@parent.send(attr_name)
|
226
274
|
else
|
227
275
|
attr_config.default
|
228
276
|
end
|
@@ -235,7 +283,7 @@ module GlueGun
|
|
235
283
|
end
|
236
284
|
|
237
285
|
def determine_option_name(component_type, init_args)
|
238
|
-
dependency_builder = self.class.dependency_definitions[component_type]
|
286
|
+
dependency_builder = self.class.dependency_definitions[component_type][:builder]
|
239
287
|
|
240
288
|
option_name = nil
|
241
289
|
|
@@ -269,11 +317,18 @@ module GlueGun
|
|
269
317
|
[option_name, init_args]
|
270
318
|
end
|
271
319
|
|
272
|
-
def instantiate_dependency(option_config,
|
320
|
+
def instantiate_dependency(option_config, init_args)
|
321
|
+
dep_attributes = init_args.is_a?(Hash) ? init_args : {}
|
322
|
+
|
323
|
+
# Build dependency attributes, including sourcing from parent
|
324
|
+
dep_attributes = build_dependency_attributes(option_config, dep_attributes)
|
325
|
+
|
326
|
+
if dep_attributes.key?(:id)
|
327
|
+
raise ArgumentError,
|
328
|
+
"cannot bind attribute 'id' between #{self.class.name} and #{option_config.class_name}. ID is reserved for primary keys in Ruby on Rails"
|
329
|
+
end
|
273
330
|
dependency_class = option_config.class_name
|
274
|
-
|
275
|
-
dependency_instance.validate! if false # dependency_instance.respond_to?(:validate!)
|
276
|
-
dependency_instance
|
331
|
+
dependency_class.new(dep_attributes)
|
277
332
|
end
|
278
333
|
|
279
334
|
def propagate_changes
|
@@ -287,33 +342,64 @@ module GlueGun
|
|
287
342
|
end
|
288
343
|
|
289
344
|
def propagate_attribute_change(attr_name, value)
|
290
|
-
self.class.dependency_definitions.each do |component_type,
|
345
|
+
self.class.dependency_definitions.each do |component_type, _builder|
|
291
346
|
dependency_instance = send(component_type)
|
292
|
-
option_config = dependencies.dig(component_type, :option)
|
293
|
-
next unless option_config
|
294
347
|
|
295
|
-
|
296
|
-
|
297
|
-
end
|
348
|
+
if dependency_instance.is_a?(Array)
|
349
|
+
option_config = dependencies.dig(component_type, :option)
|
298
350
|
|
299
|
-
|
300
|
-
|
301
|
-
if dependency_instance.respond_to?("#{dep_attr_name}=")
|
302
|
-
dependency_instance.send("#{dep_attr_name}=",
|
303
|
-
block.call(value))
|
351
|
+
dependency_instance.zip(option_config).each do |dep, opt|
|
352
|
+
propagate_attribute_to_instance(attr_name, value, dep, opt)
|
304
353
|
end
|
354
|
+
elsif dependency_instance.is_a?(Hash)
|
355
|
+
option_config = dependencies.dig(component_type, :option)
|
356
|
+
|
357
|
+
dependency_instance.each do |key, dep|
|
358
|
+
propagate_attribute_to_instance(attr_name, value, dep, option_config[key])
|
359
|
+
end
|
360
|
+
else
|
361
|
+
option_config = dependencies.dig(component_type, :option)
|
362
|
+
next unless option_config
|
363
|
+
|
364
|
+
propagate_attribute_to_instance(attr_name, value, dependency_instance, option_config)
|
305
365
|
end
|
306
366
|
end
|
307
367
|
end
|
308
368
|
|
309
|
-
def
|
310
|
-
|
311
|
-
|
369
|
+
def propagate_attribute_to_instance(attr_name, value, dependency_instance, option_config)
|
370
|
+
bound_attrs = option_config.attributes.select do |_, attr_config|
|
371
|
+
(attr_config.source == attr_name.to_sym) || (attr_config.name == attr_name.to_sym)
|
372
|
+
end
|
373
|
+
|
374
|
+
bound_attrs.each do |dep_attr_name, config_attr|
|
375
|
+
block = config_attr.block.present? ? config_attr.block : proc { |att| att }
|
376
|
+
if dependency_instance.respond_to?("#{dep_attr_name}=")
|
377
|
+
dependency_instance.send("#{dep_attr_name}=",
|
378
|
+
block.call(value))
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
def injected_dependency(component_type, value)
|
384
|
+
definition = self.class.dependency_definitions[component_type]
|
385
|
+
builder = definition[:builder]
|
386
|
+
factory = definition[:factory_class]
|
387
|
+
|
388
|
+
option_configs = if builder
|
389
|
+
builder.option_configs
|
390
|
+
else
|
391
|
+
factory.dependency_definitions.values.first.values.first.option_configs
|
392
|
+
end
|
393
|
+
option_configs.values.select do |option|
|
312
394
|
option_class = option.class_name
|
313
395
|
value.is_a?(option_class)
|
314
396
|
end
|
315
397
|
end
|
316
398
|
|
399
|
+
def dependency_injected?(component_type, value)
|
400
|
+
injected_dependency(component_type, value).any?
|
401
|
+
end
|
402
|
+
|
317
403
|
def dependencies
|
318
404
|
@dependencies ||= {}
|
319
405
|
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.16
|
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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|