lutaml 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -6
  3. data/.rubocop.yml +1 -0
  4. data/LUTAML.adoc +372 -0
  5. data/Makefile +2 -0
  6. data/bin/console +5 -0
  7. data/bin/folder_yaml2lutaml.sh +6 -0
  8. data/bin/plantuml2lutaml +59 -0
  9. data/bin/yaml2lutaml +144 -0
  10. data/exe/lutaml-sysml +20 -0
  11. data/exe/lutaml-wsd2uml +59 -0
  12. data/exe/lutaml-yaml2uml +144 -0
  13. data/lib/lutaml/express/README.adoc +55 -0
  14. data/lib/lutaml/express/parsers/exp.rb +21 -0
  15. data/lib/lutaml/express/version.rb +7 -0
  16. data/lib/lutaml/express.rb +9 -0
  17. data/lib/lutaml/parser.rb +7 -0
  18. data/lib/lutaml/sysml/README.md +40 -0
  19. data/lib/lutaml/sysml/allocate.rb +8 -0
  20. data/lib/lutaml/sysml/allocated.rb +7 -0
  21. data/lib/lutaml/sysml/binding_connector.rb +7 -0
  22. data/lib/lutaml/sysml/block.rb +27 -0
  23. data/lib/lutaml/sysml/constraint_block.rb +12 -0
  24. data/lib/lutaml/sysml/copy.rb +6 -0
  25. data/lib/lutaml/sysml/derive_requirement.rb +7 -0
  26. data/lib/lutaml/sysml/nested_connector_end.rb +11 -0
  27. data/lib/lutaml/sysml/refine.rb +7 -0
  28. data/lib/lutaml/sysml/requirement.rb +34 -0
  29. data/lib/lutaml/sysml/requirement_related.rb +7 -0
  30. data/lib/lutaml/sysml/satisfy.rb +7 -0
  31. data/lib/lutaml/sysml/test_case.rb +22 -0
  32. data/lib/lutaml/sysml/trace.rb +7 -0
  33. data/lib/lutaml/sysml/verify.rb +6 -0
  34. data/lib/lutaml/sysml/version.rb +5 -0
  35. data/lib/lutaml/sysml/xmi_file.rb +417 -0
  36. data/lib/lutaml/sysml.rb +10 -0
  37. data/lib/lutaml/uml/README.adoc +44 -0
  38. data/lib/lutaml/uml/abstraction.rb +11 -0
  39. data/lib/lutaml/uml/activity.rb +11 -0
  40. data/lib/lutaml/uml/actor.rb +19 -0
  41. data/lib/lutaml/uml/association.rb +43 -0
  42. data/lib/lutaml/uml/behavior.rb +11 -0
  43. data/lib/lutaml/uml/class.rb +83 -0
  44. data/lib/lutaml/uml/classifier.rb +11 -0
  45. data/lib/lutaml/uml/connector.rb +21 -0
  46. data/lib/lutaml/uml/constraint.rb +12 -0
  47. data/lib/lutaml/uml/constructor_end.rb +16 -0
  48. data/lib/lutaml/uml/data_type.rb +75 -0
  49. data/lib/lutaml/uml/dependency.rb +21 -0
  50. data/lib/lutaml/uml/diagram.rb +8 -0
  51. data/lib/lutaml/uml/document.rb +81 -0
  52. data/lib/lutaml/uml/enum.rb +45 -0
  53. data/lib/lutaml/uml/event.rb +12 -0
  54. data/lib/lutaml/uml/final_state.rb +11 -0
  55. data/lib/lutaml/uml/formatter/base.rb +67 -0
  56. data/lib/lutaml/uml/formatter/graphviz.rb +334 -0
  57. data/lib/lutaml/uml/formatter.rb +21 -0
  58. data/lib/lutaml/uml/has_attributes.rb +14 -0
  59. data/lib/lutaml/uml/has_members.rb +30 -0
  60. data/lib/lutaml/uml/instance.rb +17 -0
  61. data/lib/lutaml/uml/model.rb +13 -0
  62. data/lib/lutaml/uml/node/base.rb +21 -0
  63. data/lib/lutaml/uml/node/class_node.rb +57 -0
  64. data/lib/lutaml/uml/node/class_relationship.rb +14 -0
  65. data/lib/lutaml/uml/node/document.rb +18 -0
  66. data/lib/lutaml/uml/node/field.rb +34 -0
  67. data/lib/lutaml/uml/node/has_name.rb +15 -0
  68. data/lib/lutaml/uml/node/has_type.rb +15 -0
  69. data/lib/lutaml/uml/node/method.rb +29 -0
  70. data/lib/lutaml/uml/node/method_argument.rb +16 -0
  71. data/lib/lutaml/uml/node/relationship.rb +28 -0
  72. data/lib/lutaml/uml/opaque_behavior.rb +11 -0
  73. data/lib/lutaml/uml/operation.rb +31 -0
  74. data/lib/lutaml/uml/package.rb +53 -0
  75. data/lib/lutaml/uml/parsers/attribute.rb +70 -0
  76. data/lib/lutaml/uml/parsers/dsl.rb +413 -0
  77. data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +59 -0
  78. data/lib/lutaml/uml/parsers/dsl_transform.rb +27 -0
  79. data/lib/lutaml/uml/parsers/yaml.rb +46 -0
  80. data/lib/lutaml/uml/port.rb +8 -0
  81. data/lib/lutaml/uml/primitive_type.rb +14 -0
  82. data/lib/lutaml/uml/property.rb +27 -0
  83. data/lib/lutaml/uml/pseudostate.rb +11 -0
  84. data/lib/lutaml/uml/realization.rb +11 -0
  85. data/lib/lutaml/uml/region.rb +12 -0
  86. data/lib/lutaml/uml/serializers/association.rb +58 -0
  87. data/lib/lutaml/uml/serializers/base.rb +16 -0
  88. data/lib/lutaml/uml/serializers/class.rb +29 -0
  89. data/lib/lutaml/uml/serializers/top_element_attribute.rb +14 -0
  90. data/lib/lutaml/uml/serializers/yaml_view.rb +18 -0
  91. data/lib/lutaml/uml/state.rb +12 -0
  92. data/lib/lutaml/uml/state_machine.rb +12 -0
  93. data/lib/lutaml/uml/top_element.rb +58 -0
  94. data/lib/lutaml/uml/top_element_attribute.rb +39 -0
  95. data/lib/lutaml/uml/transition.rb +12 -0
  96. data/lib/lutaml/uml/trigger.rb +12 -0
  97. data/lib/lutaml/uml/value.rb +31 -0
  98. data/lib/lutaml/uml/version.rb +7 -0
  99. data/lib/lutaml/uml/vertex.rb +11 -0
  100. data/lib/lutaml/uml.rb +13 -0
  101. data/lib/lutaml/version.rb +1 -1
  102. data/lib/lutaml/xmi/README.adoc +24 -0
  103. data/lib/lutaml/xmi/parsers/xml.rb +600 -0
  104. data/lib/lutaml/xmi/version.rb +5 -0
  105. data/lib/lutaml/xmi.rb +7 -0
  106. data/lib/lutaml/xml/lutaml_path/document_wrapper.rb +45 -0
  107. data/lib/lutaml/xml/mapper.rb +448 -0
  108. data/lib/lutaml/xml/parsers/xml.rb +57 -0
  109. data/lib/lutaml/xml.rb +9 -0
  110. data/lutaml.gemspec +8 -3
  111. metadata +192 -16
@@ -0,0 +1,448 @@
1
+ require "shale"
2
+
3
+ module Lutaml
4
+ module Xml
5
+ class Mapper < Shale::Mapper
6
+ # rubocop:disable Metrics/AbcSize
7
+ # rubocop:disable Metrics/MethodLength
8
+ # rubocop:disable Metrics/BlockLength
9
+ # rubocop:disable Metrics/CyclomaticComplexity
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ class << self
12
+ # Convert XML document to Object
13
+ #
14
+ # @param [Shale::Adapter::<XML adapter>::Node] element
15
+ # @param [Array<Symbol>] only
16
+ # @param [Array<Symbol>] except
17
+ # @param [any] context
18
+ #
19
+ # @return [model instance]
20
+ #
21
+ # @api public
22
+ def of_xml(element, only: nil, except: nil, context: nil)
23
+ instance = model.new
24
+
25
+ attributes
26
+ .values
27
+ .select(&:default)
28
+ .each { |attr| instance.send(attr.setter, attr.default.call) }
29
+
30
+ grouping = Shale::Mapping::Group::XmlGrouping.new
31
+ delegates = Shale::Mapping::Delegates.new
32
+
33
+ only = to_partial_render_attributes(only)
34
+ except = to_partial_render_attributes(except)
35
+
36
+ element.attributes.each do |key, value|
37
+ mapping = xml_mapping.attributes[key.to_s]
38
+ next unless mapping
39
+
40
+ if mapping.group
41
+ grouping.add(mapping, :attribute, value)
42
+ elsif mapping.method_from
43
+ mapper = new
44
+
45
+ if mapper.method(mapping.method_from).arity == 3
46
+ mapper.send(mapping.method_from, instance, value, context)
47
+ else
48
+ mapper.send(mapping.method_from, instance, value)
49
+ end
50
+ else
51
+ receiver_attributes = get_receiver_attributes(mapping)
52
+ attribute = receiver_attributes[mapping.attribute]
53
+ next unless attribute
54
+
55
+ next if only && !only.key?(attribute.name)
56
+ next if except&.key?(attribute.name)
57
+
58
+ casted_value = attribute.type.cast(value)
59
+
60
+ if attribute.collection?
61
+ if mapping.receiver
62
+ delegates.add_collection(
63
+ attributes[mapping.receiver],
64
+ attribute.setter,
65
+ casted_value,
66
+ )
67
+ else
68
+ instance.send(attribute.name) << casted_value
69
+ end
70
+ elsif mapping.receiver
71
+ delegates.add(attributes[mapping.receiver], attribute.setter,
72
+ casted_value)
73
+ else
74
+ instance.send(attribute.setter, casted_value)
75
+ end
76
+ end
77
+ end
78
+
79
+ content_mapping = xml_mapping.content
80
+
81
+ if content_mapping
82
+ if content_mapping.group
83
+ grouping.add(content_mapping, :content, element)
84
+ elsif content_mapping.method_from
85
+ mapper = new
86
+
87
+ if mapper.method(content_mapping.method_from).arity == 3
88
+ mapper.send(content_mapping.method_from, instance, element,
89
+ context)
90
+ else
91
+ mapper.send(content_mapping.method_from, instance, element)
92
+ end
93
+ else
94
+ get_content_value(content_mapping, element, only, except,
95
+ delegates, instance)
96
+ end
97
+ end
98
+
99
+ # rubocop:disable Metrics/BlockNesting
100
+ element.instance_variable_get(:@node)&.children&.each do |nokogiri_node|
101
+ if nokogiri_node.name == "text"
102
+ content_value = get_content_value(content_mapping, nokogiri_node,
103
+ only, except, delegates, instance)
104
+ instance.all_content << ["content", content_value]
105
+ next
106
+ elsif nokogiri_node.name == "comment"
107
+ instance.all_content << ["comment", nokogiri_node.text]
108
+ next
109
+ end
110
+
111
+ node = element.class.new(nokogiri_node)
112
+ mapping = xml_mapping.elements[node.name]
113
+
114
+ next unless mapping
115
+
116
+ if mapping.group
117
+ grouping.add(mapping, :element, node)
118
+ elsif mapping.method_from
119
+ mapper = new
120
+
121
+ if mapper.method(mapping.method_from).arity == 3
122
+ mapper.send(mapping.method_from, instance, node, context)
123
+ else
124
+ mapper.send(mapping.method_from, instance, node)
125
+ end
126
+ else
127
+ receiver_attributes = get_receiver_attributes(mapping)
128
+ attribute = receiver_attributes[mapping.attribute]
129
+ next unless attribute
130
+
131
+ if only
132
+ attribute_only = only[attribute.name]
133
+ next unless only.key?(attribute.name)
134
+ end
135
+
136
+ if except
137
+ attribute_except = except[attribute.name]
138
+ next if except.key?(attribute.name) && attribute_except.nil?
139
+ end
140
+
141
+ value = attribute.type.of_xml(
142
+ node,
143
+ only: attribute_only,
144
+ except: attribute_except,
145
+ context: context,
146
+ )
147
+
148
+ casted_value = attribute.type.cast(value)
149
+ instance.all_content << [mapping, casted_value]
150
+
151
+ if attribute.collection?
152
+ if mapping.receiver
153
+ delegates.add_collection(
154
+ attributes[mapping.receiver],
155
+ attribute.setter,
156
+ casted_value,
157
+ )
158
+ else
159
+ instance.send(attribute.name) << casted_value
160
+ end
161
+ elsif mapping.receiver
162
+ delegates.add(attributes[mapping.receiver], attribute.setter,
163
+ casted_value)
164
+ else
165
+ instance.send(attribute.setter, casted_value)
166
+ end
167
+ end
168
+ end
169
+ # rubocop:enable Metrics/BlockNesting
170
+
171
+ delegates.each do |delegate|
172
+ receiver = get_receiver(instance, delegate.receiver_attribute)
173
+ receiver.send(delegate.setter, delegate.value)
174
+ end
175
+
176
+ grouping.each do |group|
177
+ mapper = new
178
+
179
+ if mapper.method(group.method_from).arity == 3
180
+ mapper.send(group.method_from, instance, group.dict, context)
181
+ else
182
+ mapper.send(group.method_from, instance, group.dict)
183
+ end
184
+ end
185
+
186
+ instance
187
+ end
188
+
189
+ # Convert Object to XML document
190
+ #
191
+ # @param [any] instance Object to convert
192
+ # @param [String, nil] node_name XML node name
193
+ # @param [Shale::Adapter::<xml adapter>::Document, nil]
194
+ # doc Object to convert
195
+ # @param [Array<Symbol>] only
196
+ # @param [Array<Symbol>] except
197
+ # @param [any] context
198
+ #
199
+ # @raise [IncorrectModelError]
200
+ #
201
+ # @return [::REXML::Document, ::Nokogiri::Document, ::Ox::Document]
202
+ #
203
+ # @api public
204
+ def as_xml(
205
+ instance,
206
+ node_name = nil,
207
+ doc = nil,
208
+ _cdata = nil,
209
+ only: nil,
210
+ except: nil,
211
+ context: nil,
212
+ version: nil
213
+ )
214
+ unless instance.is_a?(model)
215
+ msg = "argument is a '#{instance.class}' but should be a '#{model}'"
216
+ raise IncorrectModelError, msg
217
+ end
218
+
219
+ unless doc
220
+ doc = Shale.xml_adapter.create_document(version)
221
+
222
+ element = as_xml(
223
+ instance,
224
+ xml_mapping.prefixed_root,
225
+ doc,
226
+ only: only,
227
+ except: except,
228
+ context: context,
229
+ )
230
+ doc.add_element(doc.doc, element)
231
+
232
+ return doc.doc
233
+ end
234
+
235
+ element = doc.create_element(node_name)
236
+
237
+ doc.add_namespace(
238
+ xml_mapping.default_namespace.prefix,
239
+ xml_mapping.default_namespace.name,
240
+ )
241
+
242
+ grouping = Shale::Mapping::Group::XmlGrouping.new
243
+
244
+ only = to_partial_render_attributes(only)
245
+ except = to_partial_render_attributes(except)
246
+
247
+ # rubocop:disable Metrics/BlockNesting
248
+ xml_mapping.attributes.each_value do |mapping|
249
+ if mapping.group
250
+ grouping.add(mapping, :attribute, nil)
251
+ elsif mapping.method_to
252
+ mapper = new
253
+
254
+ if mapper.method(mapping.method_to).arity == 4
255
+ mapper.send(mapping.method_to, instance, element, doc, context)
256
+ else
257
+ mapper.send(mapping.method_to, instance, element, doc)
258
+ end
259
+ else
260
+ receiver = if mapping.receiver
261
+ instance.send(mapping.receiver)
262
+ else
263
+ instance
264
+ end
265
+
266
+ receiver_attributes = get_receiver_attributes(mapping)
267
+ attribute = receiver_attributes[mapping.attribute]
268
+ next unless attribute
269
+
270
+ next if only && !only.key?(attribute.name)
271
+ next if except&.key?(attribute.name)
272
+
273
+ value = receiver.send(attribute.name) if receiver
274
+
275
+ if mapping.render_nil? || !value.nil?
276
+ doc.add_namespace(mapping.namespace.prefix,
277
+ mapping.namespace.name)
278
+ doc.add_attribute(element, mapping.prefixed_name, value)
279
+ end
280
+ end
281
+ end
282
+ # rubocop:enable Metrics/BlockNesting
283
+
284
+ # rubocop:disable Metrics/BlockNesting
285
+ instance.all_content.each do |mapping, content|
286
+ if mapping == "comment"
287
+ comment = Nokogiri::XML::Comment.new(doc.doc, content)
288
+ doc.add_element(element, comment)
289
+ elsif mapping == "content"
290
+ content_mapping = xml_mapping.content
291
+ if content_mapping
292
+ if content_mapping.group
293
+ grouping.add(content_mapping, :content, nil)
294
+ elsif content_mapping.method_to
295
+ mapper = new
296
+
297
+ if mapper.method(content_mapping.method_to).arity == 4
298
+ mapper.send(content_mapping.method_to, instance, element,
299
+ doc, context)
300
+ else
301
+ mapper.send(content_mapping.method_to, instance, element, doc)
302
+ end
303
+ else
304
+ receiver_attributes = get_receiver_attributes(content_mapping)
305
+ attribute = receiver_attributes[content_mapping.attribute]
306
+
307
+ if attribute
308
+ skip = false
309
+
310
+ skip = true if only && !only.key?(attribute.name)
311
+ skip = true if except&.key?(attribute.name)
312
+
313
+ unless skip
314
+ # value = receiver.send(attribute.name) if receiver
315
+ value = content
316
+
317
+ if content_mapping.cdata
318
+ doc.create_cdata(value, element)
319
+ else
320
+ a = Nokogiri::XML::Text.new(value, doc.doc)
321
+ doc.add_element(element, a)
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
327
+ elsif mapping.group
328
+ grouping.add(mapping, :element, nil)
329
+ elsif mapping.method_to
330
+ mapper = new
331
+
332
+ if mapper.method(mapping.method_to).arity == 4
333
+ mapper.send(mapping.method_to, instance, element, doc, context)
334
+ else
335
+ mapper.send(mapping.method_to, instance, element, doc)
336
+ end
337
+ else
338
+ receiver_attributes = get_receiver_attributes(mapping)
339
+ attribute = receiver_attributes[mapping.attribute]
340
+ next unless attribute
341
+
342
+ if only
343
+ attribute_only = only[attribute.name]
344
+ next unless only.key?(attribute.name)
345
+ end
346
+
347
+ if except
348
+ attribute_except = except[attribute.name]
349
+ next if except.key?(attribute.name) && attribute_except.nil?
350
+ end
351
+
352
+ value = content
353
+
354
+ if mapping.render_nil? || !value.nil?
355
+ doc.add_namespace(mapping.namespace.prefix,
356
+ mapping.namespace.name)
357
+ end
358
+
359
+ if value.nil?
360
+ if mapping.render_nil?
361
+ child = doc.create_element(mapping.prefixed_name)
362
+ doc.add_element(element, child)
363
+ end
364
+ elsif attribute.collection?
365
+ [*value].each do |v|
366
+ next if v.nil?
367
+
368
+ child = attribute.type.as_xml(
369
+ v,
370
+ mapping.prefixed_name,
371
+ doc,
372
+ mapping.cdata,
373
+ only: attribute_only,
374
+ except: attribute_except,
375
+ context: context,
376
+ )
377
+ doc.add_element(element, child)
378
+ end
379
+ else
380
+ child = attribute.type.as_xml(
381
+ value,
382
+ mapping.prefixed_name,
383
+ doc,
384
+ mapping.cdata,
385
+ only: attribute_only,
386
+ except: attribute_except,
387
+ context: context,
388
+ )
389
+ doc.add_element(element, child)
390
+ end
391
+ end
392
+ end
393
+ # rubocop:enable Metrics/BlockNesting
394
+
395
+ grouping.each do |group|
396
+ mapper = new
397
+
398
+ if mapper.method(group.method_to).arity == 4
399
+ mapper.send(group.method_to, instance, element, doc, context)
400
+ else
401
+ mapper.send(group.method_to, instance, element, doc)
402
+ end
403
+ end
404
+
405
+ element
406
+ end
407
+
408
+ def get_content_value(content_mapping, element, only, except, delegates, instance)
409
+ receiver_attributes = get_receiver_attributes(content_mapping)
410
+ attribute = receiver_attributes[content_mapping.attribute]
411
+
412
+ if attribute
413
+ skip = false
414
+
415
+ # rubocop:disable Metrics/BlockNesting
416
+ skip = true if only && !only.key?(attribute.name)
417
+ skip = true if except&.key?(attribute.name)
418
+
419
+ unless skip
420
+ value = attribute.type.cast(attribute.type.of_xml(element))
421
+
422
+ if content_mapping.receiver
423
+ delegates.add(attributes[content_mapping.receiver],
424
+ attribute.setter, value)
425
+ else
426
+ instance.send(attribute.setter, value)
427
+ end
428
+ end
429
+ # rubocop:enable Metrics/BlockNesting
430
+ end
431
+ end
432
+ end
433
+ # rubocop:enable Metrics/AbcSize
434
+ # rubocop:enable Metrics/MethodLength
435
+ # rubocop:enable Metrics/BlockLength
436
+ # rubocop:enable Metrics/CyclomaticComplexity
437
+ # rubocop:enable Metrics/PerceivedComplexity
438
+
439
+ attr_accessor :all_content
440
+
441
+ def initialize(*args)
442
+ @all_content = []
443
+
444
+ super
445
+ end
446
+ end
447
+ end
448
+ end
@@ -0,0 +1,57 @@
1
+ require "nokogiri"
2
+ require "htmlentities"
3
+ require "lutaml/uml/has_attributes"
4
+ require "lutaml/uml/document"
5
+
6
+ require "shale/schema"
7
+
8
+ module Lutaml
9
+ module Xml
10
+ module Parsers
11
+ # Class for parsing .xml schema files into ::Lutaml::Uml::Document
12
+ class Xml
13
+ def self.load_schema(schema, root_schema)
14
+ result = Shale::Schema.from_xml([schema])
15
+
16
+ result.values.each do |klass|
17
+ # Temporary solution will update in the parser
18
+ klass = klass.gsub(/^require.*?\n/, "")
19
+ klass = klass.gsub(/< Shale::Mapper/, "< Lutaml::Xml::Mapper")
20
+
21
+ eval(klass, TOPLEVEL_BINDING)
22
+ end
23
+
24
+ @@root_schema = root_schema
25
+ end
26
+
27
+ def self.parse(file)
28
+ new(file, @@root_schema).parse
29
+ end
30
+
31
+ def initialize(file, root_schema)
32
+ @file = file
33
+ @root_schema = root_schema
34
+ @root_class = Object.const_get(root_schema)
35
+ end
36
+
37
+ def parse
38
+ doc = File.read(@file)
39
+
40
+ @root_class.from_xml(doc)
41
+ end
42
+
43
+ private
44
+
45
+ def load_schema(schema)
46
+ result = Shale::Schema.from_xml([schema])
47
+
48
+ result.values.each do |klass|
49
+ klass = klass.gsub(/^require.*?\n/, "")
50
+
51
+ eval(klass, TOPLEVEL_BINDING)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/lutaml/xml.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "lutaml/xml/parsers/xml"
2
+
3
+ require "lutaml/xml/mapper"
4
+ require "lutaml/xml/lutaml_path/document_wrapper"
5
+
6
+ require "shale"
7
+ require "shale/adapter/nokogiri"
8
+
9
+ Shale.xml_adapter = Shale::Adapter::Nokogiri
data/lutaml.gemspec CHANGED
@@ -30,14 +30,19 @@ Gem::Specification.new do |spec|
30
30
  spec.required_ruby_version = ">= 2.7.0"
31
31
 
32
32
  spec.add_runtime_dependency "expressir", "~> 1.3"
33
- spec.add_runtime_dependency "lutaml-express"
34
- spec.add_runtime_dependency "lutaml-uml"
35
- spec.add_runtime_dependency "lutaml-xmi"
33
+ spec.add_runtime_dependency "hashie", "~> 4.1.0"
34
+ spec.add_runtime_dependency "htmlentities"
36
35
  spec.add_runtime_dependency "nokogiri", "~> 1.10"
36
+ spec.add_runtime_dependency "parslet", "~> 2.0.0"
37
+ spec.add_runtime_dependency "ruby-graphviz", "~> 1.2"
37
38
  spec.add_runtime_dependency "thor", "~> 1.0"
39
+ spec.add_runtime_dependency "xmi"
38
40
 
41
+ spec.add_development_dependency "byebug"
42
+ spec.add_development_dependency "equivalent-xml", "~> 0.6.0"
39
43
  spec.add_development_dependency "pry", "~> 0.12.2"
40
44
  spec.add_development_dependency "rake", "~> 13.0"
41
45
  spec.add_development_dependency "rspec", "~> 3.11"
42
46
  spec.add_development_dependency "rubocop", "~> 1.58"
47
+ spec.add_development_dependency "rubocop-performance", "~> 1.19"
43
48
  end