universe_compiler 0.3.12 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +160 -11
- data/lib/universe_compiler/entity.rb +1 -0
- data/lib/universe_compiler/entity/field_constraint_management.rb +8 -2
- data/lib/universe_compiler/entity/field_management.rb +57 -1
- data/lib/universe_compiler/entity/relations_management.rb +49 -27
- data/lib/universe_compiler/entity/type_management.rb +41 -4
- data/lib/universe_compiler/entity/validation.rb +6 -0
- data/lib/universe_compiler/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d32cb08d065dc49ae220b4f681c37719f8cad091
|
4
|
+
data.tar.gz: 97af0f860e453d852d9a77ff69d52e350dd2ec88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 700546bad667dedb998bb527ac6fd19c815cb870ccf82d77fb3c42c8927c7ffe915b122a3ef592bd805ca3358fee054ff3c0bfb4dde4c2a5f4740b6f09b4b977
|
7
|
+
data.tar.gz: 9a5fce641199557bb8e9fdfbbaa483554d4e2e28ba38078b2757417977b079ab9ba160f83b0f4d52302f430c0276804c51770e47ad150acdb88d6e33bb49ba62
|
data/README.md
CHANGED
@@ -8,9 +8,13 @@ UniverseCompiler
|
|
8
8
|
- [Core Concepts](#core-concepts)
|
9
9
|
- [Entities](#entities)
|
10
10
|
- [Overview](#overview-1)
|
11
|
-
|
12
|
-
|
13
|
-
- [
|
11
|
+
- [Special directives](#special-directives)
|
12
|
+
- [Constraints directives](#constraints-directives)
|
13
|
+
- [Relational directives](#relational-directives)
|
14
|
+
- [Basic relations](#basic-relations)
|
15
|
+
- [Advanced relations](#advanced-relations)
|
16
|
+
- [Validations](#validations)
|
17
|
+
- [Compilation](#compilation)
|
14
18
|
- [Inheritance](#inheritance)
|
15
19
|
- [Overrides](#overrides)
|
16
20
|
- [Generate a graph of entities using `Graphviz`](#generate-a-graph-of-entities-using-graphviz)
|
@@ -135,7 +139,7 @@ a.valid? # => false, not compliant with regexp specified
|
|
135
139
|
a.bar = 'Yo man'
|
136
140
|
a.valid? # => true
|
137
141
|
```
|
138
|
-
|
142
|
+
### Special directives
|
139
143
|
|
140
144
|
By default every entity has a `type`. It is available using the `#type` instance method or the
|
141
145
|
`::entity_type` class method. The default value for the entity type is coming
|
@@ -166,7 +170,7 @@ EntityD.new # => #<EntityD:46943375641700 composite_key=["entity_d", "my_seed_2"
|
|
166
170
|
```
|
167
171
|
|
168
172
|
|
169
|
-
|
173
|
+
### Constraints directives
|
170
174
|
|
171
175
|
The generic form to declare a field is the `field` statement. Any constraint can be declared using the `field`
|
172
176
|
method. Here is the signature:
|
@@ -187,11 +191,6 @@ Then some methods taking parameter:
|
|
187
191
|
* should_match
|
188
192
|
* class_name
|
189
193
|
|
190
|
-
You have as well relationship methods:
|
191
|
-
|
192
|
-
* has_one
|
193
|
-
* has_many
|
194
|
-
|
195
194
|
So for each of these methods can be used either as "real" methods or as `field` parameter. For example:
|
196
195
|
```ruby
|
197
196
|
class MyEntity < UniverseCompiler::Entity::Base
|
@@ -206,9 +205,159 @@ class MyEntity < UniverseCompiler::Entity::Base
|
|
206
205
|
end
|
207
206
|
```
|
208
207
|
Notice the fact that in the latter form `my_field` is "declared" more than once.
|
208
|
+
|
209
|
+
### Relational directives
|
210
|
+
|
211
|
+
#### Basic relations
|
212
|
+
|
213
|
+
`universe_compiler` provides two relational directives
|
214
|
+
|
215
|
+
* has_one
|
216
|
+
* has_many
|
217
|
+
|
218
|
+
They specify relations to other entities and work both mainly the same way.
|
219
|
+
|
220
|
+
In it's simplest form you can define:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
class MyEntity < UniverseCompiler::Entity::Base
|
224
|
+
has_one :another_entity_type
|
225
|
+
not_null :another_entity_type
|
226
|
+
has_one AnotherEntityClass
|
227
|
+
has_many :bar
|
228
|
+
end
|
229
|
+
```
|
230
|
+
|
231
|
+
:information_source: You can notice that you can specify either an entity type or an entity class.
|
232
|
+
|
233
|
+
:information_source: You can use `not_null` and `not_empty` with `has_one` directives, **but on a separated declaration**. With `has_many` you can use `not_empty` (you could use `not_null` but it would always be satisfied as by default a `has_many` relation returns an empty array).
|
234
|
+
|
235
|
+
For `has_one`, the accessors generated are like for `field`. With the previous class, for `has_many` the accessors are _pluralized_ (like in activerecord).
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
e = MyEntity.new fields: {name: :foo}
|
239
|
+
# You can then issue
|
240
|
+
e.another_entity_type # =>nil
|
241
|
+
e.another_entity_type = ...
|
242
|
+
e.another_entity_class # =>nil
|
243
|
+
e.bars # =>[]
|
244
|
+
```
|
245
|
+
|
246
|
+
You can notice the `has_one` accessors defined using a class rather than an entity type, has been _camelized_.
|
247
|
+
:warning: Notice the `has_many` directive generated _pluralized_ accessors !
|
248
|
+
|
249
|
+
This is the default behaviour, but you can override this using the `name` option (for both `has_one` and `has_many`):
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
class MyEntity < UniverseCompiler::Entity::Base
|
253
|
+
has_one :another_entity_type, name: :better_name
|
254
|
+
has_many :foo, name: :bars
|
255
|
+
end
|
256
|
+
```
|
257
|
+
:warning: with the `has_many` directive if you specify a `name`, the accessors name is **not pluralized** (hence there, we specify the name as being `bars` and not `bar`).
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
# You can then issue
|
261
|
+
e.bettername # =>nil
|
262
|
+
e.bars # =>[]
|
263
|
+
```
|
264
|
+
|
265
|
+
:information_source: Of course like any other field, you can still use the internal `fields`:
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
e.bettername == e.fields[:bettername]
|
269
|
+
e.bettername == e.[:bettername]
|
270
|
+
e.bars == e[:bars]
|
271
|
+
```
|
272
|
+
|
273
|
+
#### Advanced relations
|
274
|
+
|
275
|
+
Sometimes you may want entities _targeted_ by `has_one` or `has_many` relations to _be aware_ of this fact. **You can then implement complex relations without duplicating information**.
|
276
|
+
|
277
|
+
This is called **reverse methods**.
|
278
|
+
|
279
|
+
**:warning: This can only work within a universe !**
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
class EntityA < UniverseCompiler::Entity::Base
|
283
|
+
auto_named_entity_type
|
284
|
+
entity_type :leaf
|
285
|
+
end
|
286
|
+
|
287
|
+
class EntityB < UniverseCompiler::Entity::Base
|
288
|
+
entity_type :root
|
289
|
+
end
|
290
|
+
|
291
|
+
class EntityC < UniverseCompiler::Entity::Base
|
292
|
+
entity_type :tree
|
293
|
+
|
294
|
+
has_one :root, with_reverse_method: :tree, unique: true
|
295
|
+
has_many :leaf, name: :leaves, with_reverse_method: :trunk, unique: true
|
296
|
+
end
|
297
|
+
```
|
298
|
+
|
299
|
+
:warning: When you declare a reverse method using the `with_reverse_method` option, **an extra method is created on the target entity class**, not the one containing the has_one/many directive !
|
300
|
+
|
301
|
+
It allows the following kind of code:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
u = UniverseCompiler::Universe::Base.new
|
305
|
+
t = EntityC.new fields: {name: :my_tree}
|
306
|
+
u << t
|
307
|
+
(1..10).each {|_| l = EntityA.new ; t.leaves << l ; u << l }
|
308
|
+
|
309
|
+
t.leaves
|
310
|
+
#=> [#<EntityA:47410094357440 composite_key=[:leaf, #"2aad17a4-096c-4de5-9be0-ee80ef522b2b"], @universe='Unnamed #Universe'>,
|
311
|
+
# #<EntityA:47410094356680 composite_key=[:leaf, #"56500c9f-0e64-4a48-9894-0e4e485ab001"], @universe='Unnamed #Universe'>,
|
312
|
+
# #<EntityA:47410094355880 composite_key=[:leaf, #"2d5eeabb-e237-4741-8c44-0e2e9636b811"], @universe='Unnamed #Universe'>,
|
313
|
+
# #<EntityA:47410094355100 composite_key=[:leaf, #"f17d7aa1-c505-4594-889a-e3d4f8813246"], @universe='Unnamed #Universe'>,
|
314
|
+
# #<EntityA:47410094354340 composite_key=[:leaf, #"268d8a0c-cb28-42a0-85ab-2dd6217e6e6f"], @universe='Unnamed #Universe'>,
|
315
|
+
# #<EntityA:47410094353560 composite_key=[:leaf, #"8d822cde-30d4-4841-bd0a-a1570583c355"], @universe='Unnamed #Universe'>,
|
316
|
+
# #<EntityA:47410094352740 composite_key=[:leaf, #"dfffe2c2-b283-47ec-b799-3ef79c8584b4"], @universe='Unnamed #Universe'>,
|
317
|
+
# #<EntityA:47410094351940 composite_key=[:leaf, #"c8c111da-ad70-412e-9f2c-7af11894641c"], @universe='Unnamed #Universe'>,
|
318
|
+
# #<EntityA:47410094351140 composite_key=[:leaf, #"e1158988-6659-426e-912c-73f827e7429f"], @universe='Unnamed #Universe'>,
|
319
|
+
# #<EntityA:47410094350360 composite_key=[:leaf, #"64b0e4c6-a718-43b9-ae8f-beeea5145c20"], @universe='Unnamed #Universe'>]
|
320
|
+
t.leaves.last.trunk
|
321
|
+
# => #<EntityC:47410094828200 composite_key=[:tree, :my_tree], @universe='Unnamed Universe'>
|
322
|
+
t.leaves.last.fields
|
323
|
+
# => {:name=>"c881f93d-7216-49a0-a7d4-b5a2a4a314d4"}
|
324
|
+
t.leaves.last.respond_to? :trunk
|
325
|
+
# => true
|
326
|
+
```
|
327
|
+
|
328
|
+
You can then notice that any _leaf_ has a new `trunk` method which returns the entity it is referenced from (in this case the _tree_ entity). **The fields themselves are not modified !**
|
209
329
|
|
210
330
|
|
211
|
-
|
331
|
+
What happens if multiple entities reference the same entity ?
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
t2 = EntityC.new fields: {name: :oak}
|
335
|
+
u << t2
|
336
|
+
# And let's insert on entity A already added to t
|
337
|
+
t2.leaves << t.leaves.last
|
338
|
+
t.leaves.last.trunk
|
339
|
+
# UniverseCompiler::Error: 'leaf/18693021-c0a3-4e47-be89-291850d7a0ff#trunk' should return only one 'tree' !
|
340
|
+
```
|
341
|
+
|
342
|
+
An exception is returned. the `unique` option actually specifies that only one entity should reference it !
|
343
|
+
If you don't specify this option, an array is returned instead and this check is not performed.
|
344
|
+
|
345
|
+
### Validations
|
346
|
+
|
347
|
+
Every constraint defined on a field or a relation is enforced when an entity is validated (which is as well true when saving it). Continuing on previous example:
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
t.leaves.last.valid?
|
351
|
+
# => false
|
352
|
+
t.leaves.last.valid? raise_error: true
|
353
|
+
# UniverseCompiler::Error: Invalid entity '[:leaf, "0ecd1283-e98e-43ec-943b-b92e2e8ffa2b"]' for fields trunk !
|
354
|
+
|
355
|
+
```
|
356
|
+
|
357
|
+
:information_source: Here above is just an example regarding the reverse methods but any constraint added to an entity is enforced at validation time (`not_null`, `is_hash`... all of them).
|
358
|
+
|
359
|
+
|
360
|
+
## Compilation
|
212
361
|
|
213
362
|
The compilation mechanism is related to universes.
|
214
363
|
When compiling a universe it actually:
|
@@ -75,8 +75,6 @@ module UniverseCompiler
|
|
75
75
|
|
76
76
|
end
|
77
77
|
|
78
|
-
private
|
79
|
-
|
80
78
|
def define_constraint(field_name, constraint_name = nil, value = nil)
|
81
79
|
fields_constraints[field_name] ||= {}
|
82
80
|
check_constraints_incompatibilities(field_name, constraint_name)
|
@@ -85,6 +83,14 @@ module UniverseCompiler
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
86
|
+
private
|
87
|
+
|
88
|
+
def define_constraints_on_target_entity_type(target_entity_type, source_field, reverse_method = nil)
|
89
|
+
target_class = UniverseCompiler::Entity::TypeManagement.types_classes_mapping[target_entity_type]
|
90
|
+
raise 'NOT IMPLEMENTED'
|
91
|
+
end
|
92
|
+
|
93
|
+
|
88
94
|
def check_constraints_incompatibilities(field_name, constraint_name)
|
89
95
|
unless INCOMPATIBLE_CONSTRAINTS[constraint_name].nil?
|
90
96
|
INCOMPATIBLE_CONSTRAINTS[constraint_name].each do |incompatible_constraint|
|
@@ -3,11 +3,67 @@ module UniverseCompiler
|
|
3
3
|
|
4
4
|
module FieldManagement
|
5
5
|
|
6
|
-
|
7
6
|
private
|
8
7
|
|
8
|
+
def define_reverse_methods
|
9
|
+
self.class.fields_constraints.each do |method_name, constraints|
|
10
|
+
next unless constraints[:reverse_method]
|
11
|
+
|
12
|
+
define_reverse_method method_name, constraints[:reverse_method]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_reverse_method(default_method_name, method_definition_constraints)
|
17
|
+
metaclass = class << self; self ; end
|
18
|
+
method_name = normalize_method_name(default_method_name, method_definition_constraints)
|
19
|
+
UniverseCompiler.logger.debug 'Defining reverse method "%s" on class %s (%s)' % [method_name, metaclass, self.type]
|
20
|
+
raise UniverseCompiler::Error, "'#{method_name}' already exists on class '#{metaclass}'. Skipped !" if self.respond_to? method_name
|
21
|
+
method_definition_constraints[:actual_method] = method_name
|
22
|
+
|
23
|
+
check_operation = case method_definition_constraints[:relation_type]
|
24
|
+
when :has_one
|
25
|
+
'=='.to_sym
|
26
|
+
when :has_many
|
27
|
+
'include?'.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
metaclass.instance_eval do
|
31
|
+
define_method method_name do
|
32
|
+
raise UniverseCompiler::Error, "Entity '#{as_path}' is not in a universe. Reverse methods can't work !" if universe.nil?
|
33
|
+
|
34
|
+
res = universe.get_entities(criterion: :by_type, value: method_definition_constraints[:source_entity]).select do |entity|
|
35
|
+
entity[method_definition_constraints[:source_field]].send check_operation, self
|
36
|
+
end
|
37
|
+
return res if res.nil? || res.empty?
|
38
|
+
|
39
|
+
if method_definition_constraints[:unique_result]
|
40
|
+
if res.size == 1
|
41
|
+
return res.first
|
42
|
+
else
|
43
|
+
UniverseCompiler.logger.warn 'Too many results. Must be one or none !'
|
44
|
+
UniverseCompiler.logger.debug res.inspect
|
45
|
+
raise UniverseCompiler::Error, "'#{self.as_path}##{method_name}' should return maximum one '#{method_definition_constraints[:source_entity]}' !"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
res
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
def normalize_method_name(default_method_name, method_definition_constraints)
|
57
|
+
if default_method_name == method_definition_constraints[:source_entity]
|
58
|
+
"referenced_from_#{method_definition_constraints[:source_entity]}_entities"
|
59
|
+
else
|
60
|
+
default_method_name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
9
64
|
def define_known_fields_accessors
|
10
65
|
self.class.fields_constraints.each do |field_name, constraints|
|
66
|
+
next if constraints[:reverse_method]
|
11
67
|
define_field_accessor field_name
|
12
68
|
if fields[field_name].nil?
|
13
69
|
fields[field_name] = [] if constraints[:has_many] || constraints[:is_array]
|
@@ -5,40 +5,62 @@ module UniverseCompiler
|
|
5
5
|
|
6
6
|
module RelationsManagement
|
7
7
|
|
8
|
-
def has_one(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
def has_one(target_entity_type_or_class, name: nil, with_reverse_method: nil, unique: false)
|
9
|
+
target_entity_type = normalize_entity_type target_entity_type_or_class
|
10
|
+
field_name = relation_field_name name, target_entity_type
|
11
|
+
define_constraint field_name, :has_one, target_entity_type
|
12
|
+
return unless with_reverse_method
|
13
|
+
|
14
|
+
define_constraint_for_reverse_method :has_one,
|
15
|
+
target_entity_type,
|
16
|
+
field_name,
|
17
|
+
with_reverse_method,
|
18
|
+
unique
|
17
19
|
end
|
18
20
|
|
19
|
-
def has_many(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
when Symbol, String
|
32
|
-
define_constraint field_name, :has_many, entity_type.to_sym
|
33
|
-
end
|
21
|
+
def has_many(target_entity_type_or_class, name: nil, with_reverse_method: nil, unique: false)
|
22
|
+
target_entity_type = normalize_entity_type target_entity_type_or_class
|
23
|
+
field_name = relation_field_name name, target_entity_type
|
24
|
+
field_name = field_name.to_s.pluralize.to_sym if name.nil?
|
25
|
+
define_constraint field_name, :has_many, target_entity_type
|
26
|
+
return unless with_reverse_method
|
27
|
+
|
28
|
+
define_constraint_for_reverse_method :has_many,
|
29
|
+
target_entity_type,
|
30
|
+
field_name,
|
31
|
+
with_reverse_method,
|
32
|
+
unique
|
34
33
|
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def relation_field_name(name, target_entity_type)
|
38
|
+
case name
|
39
|
+
when NilClass
|
40
|
+
target_entity_type
|
41
|
+
when String, Symbol
|
42
|
+
name.to_sym
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
46
|
+
def define_constraint_for_reverse_method(relation_type, target_entity_type, source_field_name, with_reverse_method, unique)
|
47
|
+
reverse_method_name = case with_reverse_method
|
48
|
+
when TrueClass
|
49
|
+
self.entity_type
|
50
|
+
when String, Symbol
|
51
|
+
with_reverse_method.to_sym
|
52
|
+
end
|
53
|
+
target_class = UniverseCompiler::Entity::TypeManagement.type_class_mapping(target_entity_type)
|
54
|
+
method_creation_data = {
|
55
|
+
source_entity: self.entity_type,
|
56
|
+
source_field: source_field_name,
|
57
|
+
relation_type: relation_type,
|
58
|
+
unique_result: unique
|
59
|
+
}
|
60
|
+
target_class.define_constraint reverse_method_name, :reverse_method, method_creation_data
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
42
64
|
end
|
43
65
|
|
44
66
|
end
|
@@ -3,6 +3,8 @@ module UniverseCompiler
|
|
3
3
|
|
4
4
|
module TypeManagement
|
5
5
|
|
6
|
+
# **
|
7
|
+
# Methods to be added into the class the UniverseCompiler::Entity::TypeManagement is included in.
|
6
8
|
module ClassMethods
|
7
9
|
|
8
10
|
def entity_type(value = nil)
|
@@ -16,17 +18,45 @@ module UniverseCompiler
|
|
16
18
|
def entity_type=(value)
|
17
19
|
raise UniverseCompiler::Error, "You cannot change an entity type for class '#{self.name}'" unless @entity_type.nil?
|
18
20
|
raise UniverseCompiler::Error, 'Only Symbol is supported for entity_type !' unless value.is_a? Symbol
|
21
|
+
mapping = UniverseCompiler::Entity::TypeManagement.types_classes_mapping
|
22
|
+
if mapping.keys.include? value
|
23
|
+
raise UniverseCompiler::Error, "Type '#{value}' already registered for another class (#{mapping[value]})" unless self == mapping[value]
|
24
|
+
end
|
25
|
+
mapping[value] = self
|
19
26
|
@entity_type = value
|
20
27
|
end
|
21
28
|
|
29
|
+
private
|
30
|
+
|
31
|
+
def normalize_entity_type(entity_type_or_class)
|
32
|
+
case entity_type_or_class
|
33
|
+
when Class
|
34
|
+
entity_type_or_class.entity_type
|
35
|
+
when Symbol, String
|
36
|
+
entity_type_or_class.to_sym
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
end
|
23
41
|
|
24
|
-
|
25
|
-
|
42
|
+
# **
|
43
|
+
# Module methods to be directly used
|
44
|
+
|
45
|
+
def self.type_class_mapping(type_or_class)
|
46
|
+
case type_or_class
|
47
|
+
when Symbol, String
|
48
|
+
types_classes_mapping[type_or_class.to_sym]
|
49
|
+
when Class
|
50
|
+
type_or_class
|
51
|
+
end
|
26
52
|
end
|
27
53
|
|
28
|
-
def
|
29
|
-
|
54
|
+
def self.types_classes_mapping
|
55
|
+
@types_classes_mapping ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.valid_for_type?(entity)
|
59
|
+
entity.respond_to? :type and entity.class.respond_to? :entity_type
|
30
60
|
end
|
31
61
|
|
32
62
|
def self.included(base)
|
@@ -37,6 +67,13 @@ module UniverseCompiler
|
|
37
67
|
included base.class
|
38
68
|
end
|
39
69
|
|
70
|
+
# **
|
71
|
+
# The only instance method
|
72
|
+
|
73
|
+
def type
|
74
|
+
self.class.entity_type
|
75
|
+
end
|
76
|
+
|
40
77
|
end
|
41
78
|
|
42
79
|
end
|
@@ -53,6 +53,12 @@ module UniverseCompiler
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
+
when :reverse_method
|
57
|
+
begin
|
58
|
+
send value[:actual_method] if value[:unique_result]
|
59
|
+
rescue UniverseCompiler::Error => uce
|
60
|
+
invalid_for_constraint invalid, value[:actual_method], constraint_name, value
|
61
|
+
end
|
56
62
|
else
|
57
63
|
UniverseCompiler.logger.warn "Cannot handle unknown constraint '#{constraint_name}'! Skipping..."
|
58
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: universe_compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent B.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|