expressir 2.1.27 → 2.1.29

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79f9083d84c90911c68536e3f07c4a2ebeb7675bca18d445b7af90d9ece6e7ee
4
- data.tar.gz: 69e648f694b883906a32fc316219db79dbaa053c2633a4543cd4b62673a9f88d
3
+ metadata.gz: fbc607242e5dfe5db0276c14d37cdc1d38fc07e4f0014134b20105e443a3b96c
4
+ data.tar.gz: 32ba2fe11da1f6439b7a97e30215df127aa6826ae6199f205fa4376c7624a4d2
5
5
  SHA512:
6
- metadata.gz: d9cc037357c9803c739a486089fc69b4799b1ba02f5f9de51216175447765f0e650dc02f8c525d2c4be8a3ea38e2ac953c5ef22e530ce4fea1f42f902eead456
7
- data.tar.gz: aca50dfe25f95e07453607f76df4ca532a3c3e97f8d95af08442c5a5ff402434a80e3fa6b2f8147992b72fefbaa1c3b9487f001095960b605abd5a3cfecd2bf1
6
+ metadata.gz: 06e09081cbb49ef2d4656e8f9104c830edf8fc0427ffbcef0f6fa686884468e561370656d74b3c0f893b1786e0e9d4d4d8f335d297e9e3ddb8211d9bc26bbfd1
7
+ data.tar.gz: 15350b06e45e272b7b7dbaee29c5030b794e67a30544344bf534ec2b86c89998fcb1123c1352201d4d41f217f8e11c3054f5e0ef3f94fccb96b3daa42aacda82
data/.rubocop_todo.yml CHANGED
@@ -1,115 +1,56 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-10-12 15:55:59 UTC using RuboCop version 1.81.1.
3
+ # on 2025-10-15 09:12:23 UTC using RuboCop version 1.81.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 9
9
+ # Offense count: 3
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: EnforcedStyle, IndentationWidth.
12
12
  # SupportedStyles: with_first_argument, with_fixed_indentation
13
13
  Layout/ArgumentAlignment:
14
14
  Exclude:
15
- - 'lib/expressir/commands/changes.rb'
16
- - 'spec/expressir/changes/schema_change_spec.rb'
17
- - 'spec/expressir/commands/changes_import_eengine_spec.rb'
18
- - 'spec/expressir/commands/changes_validate_spec.rb'
15
+ - 'lib/expressir/commands/changes_import_eengine.rb'
19
16
 
20
- # Offense count: 1
17
+ # Offense count: 4
21
18
  # This cop supports safe autocorrection (--autocorrect).
22
19
  # Configuration parameters: EnforcedStyleAlignWith.
23
20
  # SupportedStylesAlignWith: either, start_of_block, start_of_line
24
21
  Layout/BlockAlignment:
25
22
  Exclude:
26
- - 'lib/expressir/changes/schema_change.rb'
23
+ - 'lib/expressir/commands/changes_import_eengine.rb'
24
+ - 'spec/expressir/commands/changes_import_eengine_spec.rb'
27
25
 
28
- # Offense count: 1
26
+ # Offense count: 4
29
27
  # This cop supports safe autocorrection (--autocorrect).
30
28
  Layout/BlockEndNewline:
31
29
  Exclude:
32
- - 'lib/expressir/changes/schema_change.rb'
33
-
34
- # Offense count: 1
35
- # This cop supports safe autocorrection (--autocorrect).
36
- # Configuration parameters: AllowForAlignment.
37
- Layout/CommentIndentation:
38
- Exclude:
39
- - 'lib/expressir/commands/changes_validate.rb'
40
-
41
- # Offense count: 2
42
- # This cop supports safe autocorrection (--autocorrect).
43
- Layout/ElseAlignment:
44
- Exclude:
45
- - 'lib/expressir/commands/changes_validate.rb'
46
-
47
- # Offense count: 2
48
- # This cop supports safe autocorrection (--autocorrect).
49
- # Configuration parameters: EnforcedStyle.
50
- # SupportedStyles: empty_lines, no_empty_lines
51
- Layout/EmptyLinesAroundBlockBody:
52
- Exclude:
53
- - 'bin/validate_all_changes'
54
-
55
- # Offense count: 1
56
- # This cop supports safe autocorrection (--autocorrect).
57
- # Configuration parameters: EnforcedStyleAlignWith, Severity.
58
- # SupportedStylesAlignWith: keyword, variable, start_of_line
59
- Layout/EndAlignment:
60
- Exclude:
61
- - 'lib/expressir/commands/changes_validate.rb'
62
-
63
- # Offense count: 12
64
- # This cop supports safe autocorrection (--autocorrect).
65
- # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
66
- # SupportedHashRocketStyles: key, separator, table
67
- # SupportedColonStyles: key, separator, table
68
- # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
69
- Layout/HashAlignment:
70
- Exclude:
71
- - 'lib/expressir/commands/changes.rb'
72
- - 'spec/expressir/changes/schema_change_spec.rb'
73
- - 'spec/expressir/commands/changes_validate_spec.rb'
30
+ - 'lib/expressir/commands/changes_import_eengine.rb'
31
+ - 'spec/expressir/commands/changes_import_eengine_spec.rb'
74
32
 
75
- # Offense count: 6
33
+ # Offense count: 8
76
34
  # This cop supports safe autocorrection (--autocorrect).
77
35
  # Configuration parameters: Width, AllowedPatterns.
78
36
  Layout/IndentationWidth:
79
37
  Exclude:
80
- - 'bin/validate_all_changes'
81
- - 'lib/expressir/changes/schema_change.rb'
82
- - 'lib/expressir/commands/changes_validate.rb'
38
+ - 'lib/expressir/commands/changes_import_eengine.rb'
39
+ - 'spec/expressir/commands/changes_import_eengine_spec.rb'
83
40
 
84
- # Offense count: 574
41
+ # Offense count: 569
85
42
  # This cop supports safe autocorrection (--autocorrect).
86
43
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
87
44
  # URISchemes: http, https
88
45
  Layout/LineLength:
89
46
  Enabled: false
90
47
 
91
- # Offense count: 1
92
- # This cop supports safe autocorrection (--autocorrect).
93
- Layout/RescueEnsureAlignment:
94
- Exclude:
95
- - 'bin/validate_all_changes'
96
-
97
- # Offense count: 8
48
+ # Offense count: 3
98
49
  # This cop supports safe autocorrection (--autocorrect).
99
50
  # Configuration parameters: AllowInHeredoc.
100
51
  Layout/TrailingWhitespace:
101
52
  Exclude:
102
- - 'bin/validate_all_changes'
103
- - 'lib/expressir/commands/changes.rb'
104
- - 'spec/expressir/changes/schema_change_spec.rb'
105
- - 'spec/expressir/commands/changes_import_eengine_spec.rb'
106
- - 'spec/expressir/commands/changes_validate_spec.rb'
107
-
108
- # Offense count: 4
109
- # This cop supports safe autocorrection (--autocorrect).
110
- Lint/AmbiguousOperatorPrecedence:
111
- Exclude:
112
- - 'bin/validate_all_changes'
53
+ - 'lib/expressir/commands/changes_import_eengine.rb'
113
54
 
114
55
  # Offense count: 1
115
56
  # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
@@ -131,13 +72,13 @@ Lint/UnusedMethodArgument:
131
72
  Metrics/AbcSize:
132
73
  Enabled: false
133
74
 
134
- # Offense count: 2
75
+ # Offense count: 1
135
76
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
136
77
  # AllowedMethods: refine
137
78
  Metrics/BlockLength:
138
- Max: 72
79
+ Max: 46
139
80
 
140
- # Offense count: 59
81
+ # Offense count: 61
141
82
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
142
83
  Metrics/CyclomaticComplexity:
143
84
  Exclude:
@@ -155,12 +96,12 @@ Metrics/CyclomaticComplexity:
155
96
  - 'lib/expressir/model/model_element.rb'
156
97
  - 'spec/support/model_element_helper.rb'
157
98
 
158
- # Offense count: 109
99
+ # Offense count: 113
159
100
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
160
101
  Metrics/MethodLength:
161
102
  Max: 106
162
103
 
163
- # Offense count: 47
104
+ # Offense count: 48
164
105
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
165
106
  Metrics/PerceivedComplexity:
166
107
  Exclude:
@@ -194,7 +135,7 @@ Performance/MapMethodChain:
194
135
  - 'spec/expressir/commands/coverage_ignore_files_spec.rb'
195
136
  - 'spec/expressir/coverage_spec.rb'
196
137
 
197
- # Offense count: 122
138
+ # Offense count: 126
198
139
  # Configuration parameters: CountAsOne.
199
140
  RSpec/ExampleLength:
200
141
  Max: 123
@@ -210,13 +151,7 @@ RSpec/IndexedLet:
210
151
  - 'spec/expressir/model/data_types/set_spec.rb'
211
152
  - 'spec/expressir/model/data_types/string_spec.rb'
212
153
 
213
- # Offense count: 1
214
- # This cop supports safe autocorrection (--autocorrect).
215
- RSpec/IteratedExpectation:
216
- Exclude:
217
- - 'spec/expressir/schema_manifest_spec.rb'
218
-
219
- # Offense count: 254
154
+ # Offense count: 257
220
155
  RSpec/MultipleExpectations:
221
156
  Max: 114
222
157
 
@@ -237,13 +172,7 @@ RSpec/RepeatedExample:
237
172
  Exclude:
238
173
  - 'spec/expressir/model/data_types/logical_spec.rb'
239
174
 
240
- # Offense count: 2
241
- # This cop supports unsafe autocorrection (--autocorrect-all).
242
- Security/YAMLLoad:
243
- Exclude:
244
- - 'bin/validate_all_changes'
245
-
246
- # Offense count: 1
175
+ # Offense count: 6
247
176
  # This cop supports safe autocorrection (--autocorrect).
248
177
  # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
249
178
  # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
@@ -252,7 +181,8 @@ Security/YAMLLoad:
252
181
  # AllowedMethods: lambda, proc, it
253
182
  Style/BlockDelimiters:
254
183
  Exclude:
255
- - 'lib/expressir/changes/schema_change.rb'
184
+ - 'lib/expressir/commands/changes_import_eengine.rb'
185
+ - 'spec/expressir/commands/changes_import_eengine_spec.rb'
256
186
 
257
187
  # Offense count: 1
258
188
  # This cop supports safe autocorrection (--autocorrect).
@@ -266,60 +196,3 @@ Style/EmptyElse:
266
196
  Style/MissingRespondToMissing:
267
197
  Exclude:
268
198
  - 'lib/expressir/express/visitor.rb'
269
-
270
- # Offense count: 1
271
- # This cop supports unsafe autocorrection (--autocorrect-all).
272
- # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
273
- # SupportedStyles: predicate, comparison
274
- Style/NumericPredicate:
275
- Exclude:
276
- - 'spec/**/*'
277
- - 'lib/expressir/commands/changes_import_eengine.rb'
278
-
279
- # Offense count: 1
280
- # This cop supports safe autocorrection (--autocorrect).
281
- Style/RedundantBegin:
282
- Exclude:
283
- - 'bin/validate_all_changes'
284
-
285
- # Offense count: 4
286
- # This cop supports unsafe autocorrection (--autocorrect-all).
287
- # Configuration parameters: Mode.
288
- Style/StringConcatenation:
289
- Exclude:
290
- - 'bin/validate_all_changes'
291
-
292
- # Offense count: 4
293
- # This cop supports safe autocorrection (--autocorrect).
294
- # Configuration parameters: EnforcedStyle.
295
- # SupportedStyles: single_quotes, double_quotes
296
- Style/StringLiteralsInInterpolation:
297
- Exclude:
298
- - 'bin/validate_all_changes'
299
-
300
- # Offense count: 4
301
- # This cop supports safe autocorrection (--autocorrect).
302
- # Configuration parameters: EnforcedStyleForMultiline.
303
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
304
- Style/TrailingCommaInArguments:
305
- Exclude:
306
- - 'lib/expressir/changes/schema_change.rb'
307
- - 'lib/expressir/commands/changes_import_eengine.rb'
308
-
309
- # Offense count: 5
310
- # This cop supports safe autocorrection (--autocorrect).
311
- # Configuration parameters: EnforcedStyleForMultiline.
312
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
313
- Style/TrailingCommaInArrayLiteral:
314
- Exclude:
315
- - 'spec/expressir/changes/schema_change_spec.rb'
316
-
317
- # Offense count: 10
318
- # This cop supports safe autocorrection (--autocorrect).
319
- # Configuration parameters: EnforcedStyleForMultiline.
320
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
321
- Style/TrailingCommaInHashLiteral:
322
- Exclude:
323
- - 'bin/validate_all_changes'
324
- - 'lib/expressir/commands/changes_import_eengine.rb'
325
- - 'spec/expressir/changes/schema_change_spec.rb'
data/README.adoc CHANGED
@@ -724,13 +724,40 @@ This is useful for:
724
724
  * **Catching errors early**: Validates before committing changes
725
725
  * **Cleaning up files**: Removes inconsistencies in formatting
726
726
 
727
- ==== Importing from eengine XML
727
+ ==== Importing from Express Engine comparison report XML
728
728
 
729
- The `changes import-eengine` command converts eengine comparison XML files to
730
- EXPRESS Changes YAML format.
729
+ The `changes import-eengine` command converts Express Engine (eengine) comparison
730
+ XML files to EXPRESS Changes YAML format.
731
+
732
+ The eengine compare XML format is created through
733
+ `exp-engine-engine/kernel/compare.lisp` in the Express Engine code. Expressir is
734
+ compatible with v5.2.7 of eengine output.
735
+
736
+ The import command:
737
+
738
+ . Parses the eengine XML comparison file
739
+ . Automatically detects the XML mode (Schema/ARM/MIM)
740
+ . Extracts additions, modifications, and deletions
741
+ . Converts modified objects to EXPRESS Changes item format
742
+ . Preserves interface change information (`interfaced.items`)
743
+ . Creates or updates an EXPRESS Changes YAML file
744
+ . Supports appending new versions to existing files
745
+
746
+ When the output file already exists:
747
+
748
+ * **Same version**: Replaces the existing edition with that version
749
+ * **New version**: Adds a new edition to the file
750
+
751
+ This allows you to build up a complete change history incrementally across
752
+ multiple schema versions.
753
+
754
+ Syntax:
731
755
 
732
756
  [source, sh]
733
757
  ----
758
+ # Basic syntax
759
+ expressir changes import-eengine INPUT_XML SCHEMA_NAME VERSION [options]
760
+
734
761
  # Import and output to stdout
735
762
  expressir changes import-eengine comparison.xml schema_name "2"
736
763
 
@@ -744,26 +771,62 @@ expressir changes import-eengine comparison.xml schema_name "2" -o output.yaml -
744
771
  expressir changes import-eengine comparison.xml schema_name "3" -o existing.yaml
745
772
  ----
746
773
 
747
- [options="header"]
748
- |===
749
- | Option | Description
750
- | `-o, --output PATH` | Output YAML file path (stdout if not specified)
751
- | `--verbose` | Show verbose output
752
- |===
774
+ Where:
753
775
 
754
- The import command:
776
+ `INPUT_XML`:: Path to the eengine comparison XML file
777
+ `SCHEMA_NAME`:: Name of the schema being tracked (e.g., `aic_csg`, `action_schema`)
778
+ `VERSION`:: Version number for this set of changes (e.g., `"2"`, `"3"`)
755
779
 
756
- . Parses the eengine XML comparison file
757
- . Extracts additions, modifications, and removals
758
- . Creates or updates an EXPRESS Changes YAML file
759
- . Supports appending new versions to existing files
780
+ Options:
760
781
 
761
- When the output file already exists:
782
+ `-o, --output PATH`:: Output YAML file path (stdout if not specified)
783
+ `--verbose`:: Show verbose output including parsed items
762
784
 
763
- * **Same version**: Replaces the existing edition with that version
764
- * **New version**: Adds a new edition to the file
785
+ The command automatically detects and handles all three eengine XML comparison
786
+ formats:
787
+
788
+ Schema mode:: `<schema.changes>` root element with `<schema.additions>`,
789
+ `<schema.modifications>`, and `<schema.deletions>` sections. See API docs for
790
+ details.
791
+
792
+ Example workflow for importing changes from multiple versions:
793
+
794
+ .Importing multiple versions incrementally
795
+ [example]
796
+ [source, sh]
797
+ ----
798
+ # Import version 2 changes
799
+ expressir changes import-eengine v2_comparison.xml action_schema "2" \
800
+ -o action_schema.changes.yaml
765
801
 
766
- This allows you to build up a complete change history incrementally.
802
+ # Import version 3 changes (appends to existing file)
803
+ expressir changes import-eengine v3_comparison.xml action_schema "3" \
804
+ -o action_schema.changes.yaml
805
+
806
+ # Import version 4 changes (appends to existing file)
807
+ expressir changes import-eengine v4_comparison.xml action_schema "4" \
808
+ -o action_schema.changes.yaml
809
+
810
+ # Verify the result
811
+ cat action_schema.changes.yaml
812
+ ----
813
+
814
+ This creates a single YAML file tracking changes across all three versions:
815
+
816
+ [source,yaml]
817
+ ----
818
+ schema: action_schema
819
+ editions:
820
+ - version: '2'
821
+ description: Changes from eengine comparison
822
+ additions: [...]
823
+ - version: '3'
824
+ description: Changes from eengine comparison
825
+ additions: [...]
826
+ - version: '4'
827
+ description: Changes from eengine comparison
828
+ additions: [...]
829
+ ----
767
830
 
768
831
 
769
832
  == Usage: Ruby
@@ -1167,15 +1230,214 @@ expressir coverage schemas.yml --format json --exclude=TYPE:SELECT
1167
1230
 
1168
1231
  Expressir provides the `Changes` module for managing and tracking changes to
1169
1232
  EXPRESS schemas across versions. This module implements the EXPRESS Changes YAML
1170
- format defined by ELF (Express Language Foundation).
1233
+ format defined by ELF (Express Language Foundation) (ELF 5005).
1171
1234
 
1172
1235
  The Changes module enables:
1173
1236
 
1174
1237
  * Loading and saving schema change records from/to YAML files
1175
1238
  * Programmatic creation and manipulation of change records
1176
1239
  * Smart edition handling (replace same version, add new version)
1177
- * Support for all change types: additions, modifications, removals, deletions
1240
+ * Support for all change types: additions, modifications, deletions
1178
1241
  * Support for mapping changes in ARM/MIM schemas
1242
+ * Programmatic import from Express Engine comparison XML files
1243
+
1244
+
1245
+ === Importing from Express Engine XML programmatically
1246
+
1247
+ ==== General
1248
+
1249
+ Expressir provides programmatic API access for parsing Express Engine comparison XML
1250
+ and converting it to EXPRESS Changes format.
1251
+
1252
+ Parse Eengine XML into a structured object model:
1253
+
1254
+ [source,ruby]
1255
+ ----
1256
+ require "expressir/eengine/compare_report"
1257
+
1258
+ # Parse from XML string
1259
+ xml_content = File.read("comparison.xml")
1260
+ report = Expressir::Eengine::CompareReport.from_xml(xml_content)
1261
+
1262
+ # Or parse from file
1263
+ report = Expressir::Eengine::CompareReport.from_file("comparison.xml")
1264
+ ----
1265
+
1266
+ Convert Eengine XML directly to EXPRESS Changes format:
1267
+
1268
+ [source,ruby]
1269
+ ----
1270
+ require "expressir/commands/changes_import_eengine"
1271
+
1272
+ # Parse XML and convert to SchemaChange in one step
1273
+ xml_content = File.read("comparison.xml")
1274
+ change_schema = Expressir::Commands::ChangesImportEengine.from_xml(
1275
+ xml_content,
1276
+ "aic_csg", # schema name
1277
+ "1.0" # version
1278
+ )
1279
+
1280
+ # Use the SchemaChange object
1281
+ change_schema.editions.first.additions.each do |item|
1282
+ puts "#{item.type}: #{item.name}"
1283
+ puts " interfaced_items: #{item.interfaced_items}" if item.interfaced_items
1284
+ end
1285
+
1286
+ # Save to file
1287
+ change_schema.to_file("output.changes.yaml")
1288
+ ----
1289
+
1290
+ ==== Compare modes
1291
+
1292
+ ===== General
1293
+
1294
+ Expressir automatically detects and parses all three Eengine XML modes.
1295
+
1296
+ [source,ruby]
1297
+ ----
1298
+ # All modes are handled automatically
1299
+ arm_report = Expressir::Eengine::CompareReport.from_file("arm_comparison.xml")
1300
+ mim_report = Expressir::Eengine::CompareReport.from_file("mim_comparison.xml")
1301
+ schema_report = Expressir::Eengine::CompareReport.from_file("schema_comparison.xml")
1302
+
1303
+ puts arm_report.mode # => "arm"
1304
+ puts mim_report.mode # => "mim"
1305
+ puts schema_report.mode # => "schema"
1306
+ ----
1307
+
1308
+ ===== Schema mode
1309
+
1310
+ `<schema.changes>` with `<schema.additions>`, `<schema.modifications>`, `<schema.deletions>`
1311
+
1312
+ [example]
1313
+ ====
1314
+ [source,xml]
1315
+ ----
1316
+ <schema.changes schema_name="aic_csg">
1317
+ <schema.additions>
1318
+ <modified.object type="ENTITY" name="new_entity" />
1319
+ </schema.additions>
1320
+ <schema.modifications>
1321
+ <modified.object type="TYPE" name="modified_type" />
1322
+ </schema.modifications>
1323
+ <schema.deletions>
1324
+ <modified.object type="FUNCTION" name="removed_function" />
1325
+ </schema.deletions>
1326
+ </schema.changes>
1327
+ ----
1328
+ ====
1329
+
1330
+ ===== ARM mode
1331
+
1332
+ `<arm.changes>` root element with `<arm.additions>`,
1333
+ `<arm.modifications>`, and `<arm.deletions>` sections
1334
+
1335
+ [example]
1336
+ ====
1337
+ [source,xml]
1338
+ ----
1339
+ <arm.changes schema_name="example_arm">
1340
+ <arm.additions>
1341
+ <modified.object type="ENTITY" name="new_arm_entity" />
1342
+ </arm.additions>
1343
+ </arm.changes>
1344
+ ----
1345
+ ====
1346
+
1347
+
1348
+ ===== MIM mode
1349
+
1350
+ `<mim.changes>` root element with `<mim.additions>`,
1351
+ `<mim.modifications>`, and `<mim.deletions>` sections
1352
+
1353
+ [example]
1354
+ ====
1355
+ [source,xml]
1356
+ ----
1357
+ <mim.changes schema_name="example_mim">
1358
+ <mim.additions>
1359
+ <modified.object type="ENTITY" name="new_mim_entity" />
1360
+ </mim.additions>
1361
+ </mim.changes>
1362
+ ----
1363
+ ====
1364
+
1365
+ ==== Interface changes
1366
+
1367
+ The eengine XML format tracks interface changes (USE_FROM, REFERENCE_FROM) with
1368
+ the `interfaced.items` attribute. This attribute lists the specific items being
1369
+ imported or referenced from another schema.
1370
+
1371
+ .Example XML with interface changes
1372
+ [example]
1373
+ ====
1374
+ [source,xml]
1375
+ ----
1376
+ <schema.changes schema_name="aic_csg">
1377
+ <schema.additions>
1378
+ <modified.object type="USE_FROM" name="geometric_model_schema"
1379
+ interfaced.items="convex_hexahedron" />
1380
+
1381
+ <modified.object type="USE_FROM" name="geometric_model_schema"
1382
+ interfaced.items="cyclide_segment_solid" />
1383
+
1384
+ <modified.object type="REFERENCE_FROM" name="measure_schema"
1385
+ interfaced.items="length_measure" />
1386
+ </schema.additions>
1387
+ </schema.changes>
1388
+ ----
1389
+
1390
+ This will be converted to EXPRESS Changes YAML as:
1391
+
1392
+ [source,yaml]
1393
+ ----
1394
+ schema: aic_csg
1395
+ editions:
1396
+ - version: '2'
1397
+ description: Changes from eengine comparison
1398
+ additions:
1399
+ - type: USE_FROM
1400
+ name: geometric_model_schema
1401
+ interfaced_items: convex_hexahedron
1402
+ - type: USE_FROM
1403
+ name: geometric_model_schema
1404
+ interfaced_items: cyclide_segment_solid
1405
+ - type: REFERENCE_FROM
1406
+ name: measure_schema
1407
+ interfaced_items: length_measure
1408
+ ----
1409
+ ====
1410
+
1411
+ Eengine XML files track interface changes (USE_FROM, REFERENCE_FROM) with the
1412
+ `interfaced.items` attribute:
1413
+
1414
+ [source,ruby]
1415
+ ----
1416
+ report = Expressir::Eengine::CompareReport.from_file("comparison.xml")
1417
+
1418
+ # Find interface changes
1419
+ report.additions&.modified_objects&.each do |obj|
1420
+ if obj.type == "USE_FROM" || obj.type == "REFERENCE_FROM"
1421
+ puts "#{obj.type} #{obj.name}"
1422
+ puts " Items: #{obj.interfaced_items}" if obj.interfaced_items
1423
+ end
1424
+ end
1425
+ ----
1426
+
1427
+
1428
+ ==== Supported change types
1429
+
1430
+ The import command recognizes all standard EXPRESS construct types:
1431
+
1432
+ * `ENTITY` - Entity definitions
1433
+ * `TYPE` - Type definitions
1434
+ * `FUNCTION` - Function definitions
1435
+ * `PROCEDURE` - Procedure definitions
1436
+ * `RULE` - Rule definitions
1437
+ * `CONSTANT` - Constant definitions
1438
+ * `USE_FROM` - Interface imports (preserves `interfaced.items`)
1439
+ * `REFERENCE_FROM` - Interface references (preserves `interfaced.items`)
1440
+
1179
1441
 
1180
1442
  === Reading change files
1181
1443
 
@@ -1192,14 +1454,13 @@ change_schema = Expressir::Changes::SchemaChange.from_file("schema.changes.yaml"
1192
1454
  puts "Schema: #{change_schema.schema}"
1193
1455
 
1194
1456
  # Iterate through change editions
1195
- change_schema.edition_change.each do |edition|
1457
+ change_schema.editions.each do |edition|
1196
1458
  puts "Version #{edition.version}: #{edition.description}"
1197
1459
 
1198
1460
  # Access changes by type
1199
1461
  puts " Additions: #{edition.additions.size}" if edition.additions
1200
1462
  puts " Modifications: #{edition.modifications.size}" if edition.modifications
1201
1463
  puts " Deletions: #{edition.deletions.size}" if edition.deletions
1202
- puts " Removals: #{edition.removals.size}" if edition.removals
1203
1464
  end
1204
1465
  ----
1205
1466
 
@@ -1210,7 +1471,7 @@ Create a new change schema programmatically:
1210
1471
  [source,ruby]
1211
1472
  ----
1212
1473
  # Create a new empty change schema
1213
- change_schema = Expressir::Changes::SchemaChange.create_new("my_schema")
1474
+ change_schema = Expressir::Changes::SchemaChange.new(schema: "my_schema")
1214
1475
 
1215
1476
  # Create change items
1216
1477
  new_entity = Expressir::Changes::ItemChange.new(
@@ -1228,7 +1489,7 @@ modified_function = Expressir::Changes::ItemChange.new(
1228
1489
  changes = {
1229
1490
  additions: [new_entity],
1230
1491
  modifications: [modified_function],
1231
- removals: []
1492
+ deletions: []
1232
1493
  }
1233
1494
 
1234
1495
  change_schema.add_or_update_edition(
@@ -1292,9 +1553,8 @@ Change editions support categorizing changes into:
1292
1553
 
1293
1554
  `additions`:: New elements added to the schema
1294
1555
  `modifications`:: Existing elements that were modified
1295
- `removals`:: Elements removed from the schema
1296
- `deletions`:: Alternative term for removals (both supported)
1297
- `mapping`:: Mapping-related changes (for ARM/MIM modules)
1556
+ `deletions`:: Elements removed from the schema
1557
+ `mappings`:: Mapping-related changes (for ARM/MIM modules)
1298
1558
  `changes`:: General changes (alternative to mapping)
1299
1559
 
1300
1560
  [source,ruby]
@@ -1305,7 +1565,7 @@ edition = Expressir::Changes::EditionChange.new(
1305
1565
  additions: [item1, item2],
1306
1566
  modifications: [item3],
1307
1567
  deletions: [item4],
1308
- mapping: [mapping_change]
1568
+ mappings: [mapping_change]
1309
1569
  )
1310
1570
  ----
1311
1571
 
@@ -1326,7 +1586,7 @@ mapping_change = Expressir::Changes::MappingChange.new(
1326
1586
  ----
1327
1587
  ---
1328
1588
  schema: support_resource_schema
1329
- edition_change:
1589
+ editions:
1330
1590
  - version: '2'
1331
1591
  description: |-
1332
1592
  The definitions of the following EXPRESS entity data types were modified:
data/expressir.gemspec CHANGED
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_dependency "csv"
37
37
  spec.add_dependency "liquid"
38
38
  spec.add_dependency "lutaml-model"
39
+ spec.add_dependency "moxml"
39
40
  spec.add_dependency "parslet", "~> 2.0"
40
41
  spec.add_dependency "ruby-progressbar", "~> 1.11"
41
42
  spec.add_dependency "table_tennis"
@@ -12,9 +12,8 @@ module Expressir
12
12
  attribute :description, :string
13
13
  attribute :additions, ItemChange, collection: true
14
14
  attribute :modifications, ItemChange, collection: true
15
- attribute :removals, ItemChange, collection: true
16
15
  attribute :deletions, ItemChange, collection: true
17
- attribute :mapping, MappingChange, collection: true
16
+ attribute :mappings, MappingChange, collection: true
18
17
  attribute :changes, MappingChange, collection: true
19
18
 
20
19
  yaml do
@@ -22,9 +21,8 @@ module Expressir
22
21
  map "description", to: :description
23
22
  map "additions", to: :additions
24
23
  map "modifications", to: :modifications
25
- map "removals", to: :removals
26
24
  map "deletions", to: :deletions
27
- map "mapping", to: :mapping
25
+ map "mappings", to: :mappings
28
26
  map "changes", to: :changes
29
27
  end
30
28
  end
@@ -8,7 +8,7 @@ module Expressir
8
8
  class ItemChange < Lutaml::Model::Serializable
9
9
  attribute :type, :string
10
10
  attribute :name, :string
11
- attribute :description, :string
11
+ attribute :description, :string, collection: true
12
12
  attribute :interfaced_items, :string
13
13
 
14
14
  yaml do
@@ -6,11 +6,11 @@ module Expressir
6
6
  module Changes
7
7
  # Represents a mapping change entry
8
8
  class MappingChange < Lutaml::Model::Serializable
9
- attribute :change, :string
9
+ attribute :name, :string
10
10
  attribute :description, :string
11
11
 
12
12
  yaml do
13
- map "change", to: :change
13
+ map "name", to: :name
14
14
  map "description", to: :description
15
15
  end
16
16
  end
@@ -8,11 +8,11 @@ module Expressir
8
8
  # Represents changes to an EXPRESS schema across multiple versions
9
9
  class SchemaChange < Lutaml::Model::Serializable
10
10
  attribute :schema, :string
11
- attribute :edition_change, EditionChange, collection: true
11
+ attribute :editions, EditionChange, collection: true
12
12
 
13
13
  yaml do
14
14
  map "schema", to: :schema
15
- map "edition_change", to: :edition_change
15
+ map "editions", to: :editions
16
16
  end
17
17
 
18
18
  class << self
@@ -23,31 +23,26 @@ module Expressir
23
23
  def from_file(path)
24
24
  content = File.read(path)
25
25
  # Handle empty or minimal YAML files
26
- return new(schema: "", edition_change: []) if content.strip == "---"
26
+ return new if content.strip == "---" || content.strip.empty?
27
27
 
28
28
  from_yaml(content)
29
29
  end
30
-
31
- # Create a new empty SchemaChange
32
- #
33
- # @param schema_name [String] Name of the schema
34
- # @return [SchemaChange] New instance with empty change editions
35
- def create_new(schema_name)
36
- new(schema: schema_name, edition_change: [])
37
- end
38
30
  end
39
31
 
40
32
  # Add or update a change edition in this schema
41
33
  #
42
34
  # @param version [String] Version number
43
35
  # @param description [String] Description of changes
44
- # @param changes [Hash] Hash with :additions, :modifications, :removals
36
+ # @param changes [Hash] Hash with :additions, :modifications, :deletions
45
37
  # @return [EditionChange] The added or updated edition
46
38
  def add_or_update_edition(version, description, changes)
47
39
  version_str = version.to_s
48
40
 
41
+ # Initialize editions array if nil
42
+ self.editions ||= []
43
+
49
44
  # Find existing edition with this version
50
- existing_index = edition_change.find_index do |ed|
45
+ existing_index = editions.find_index do |ed|
51
46
  ed.version == version_str
52
47
  end
53
48
 
@@ -57,16 +52,15 @@ module Expressir
57
52
  description: description,
58
53
  additions: changes[:additions] || [],
59
54
  modifications: changes[:modifications] || [],
60
- removals: changes[:removals] || [],
61
55
  deletions: changes[:deletions] || [],
62
56
  )
63
57
 
64
58
  if existing_index
65
59
  # Replace existing edition with same version
66
- edition_change[existing_index] = edition
60
+ editions[existing_index] = edition
67
61
  else
68
62
  # Add new edition
69
- edition_change << edition
63
+ editions << edition
70
64
  end
71
65
 
72
66
  edition
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "changes/schema_change"
4
- require_relative "changes/edition_change"
5
- require_relative "changes/item_change"
6
- require_relative "changes/mapping_change"
7
-
8
3
  module Expressir
9
4
  # Module for EXPRESS schema change tracking and management
10
5
  module Changes
11
6
  end
12
7
  end
8
+
9
+ require_relative "changes/schema_change"
10
+ require_relative "changes/mapping_change"
@@ -1,37 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base"
4
- require "nokogiri"
4
+ require_relative "../eengine/compare_report"
5
5
 
6
6
  module Expressir
7
7
  module Commands
8
8
  # Command to import eengine comparison XML to EXPRESS Changes YAML
9
9
  class ChangesImportEengine < Base
10
- def self.call(input_file, output_file, schema_name, version, **options)
11
- new.call(input_file, output_file, schema_name, version, **options)
10
+ # Parse XML string and convert to SchemaChange
11
+ #
12
+ # @param xml_content [String] Eengine XML content
13
+ # @param schema_name [String] Schema name
14
+ # @param version [String] Version identifier
15
+ # @param options [Hash] Additional options
16
+ # @return [Expressir::Changes::SchemaChange]
17
+ def self.from_xml(xml_content, schema_name, version, **options)
18
+ require "expressir/changes"
19
+
20
+ # Parse into CompareReport using Lutaml::Model
21
+ compare_report = Expressir::Eengine::CompareReport.from_xml(xml_content)
22
+
23
+ # Convert to SchemaChange
24
+ convert_to_schema_change(compare_report, schema_name, version,
25
+ xml_content: xml_content, **options)
12
26
  end
13
27
 
14
- def call(input_file, output_file, schema_name, version, **options)
28
+ # File-based workflow (backward compatible)
29
+ def self.call(input_file, output_file, schema_name, version, **options)
15
30
  require "expressir/changes"
16
31
 
17
- # Parse the eengine XML
18
- xml_doc = File.open(input_file) { |f| Nokogiri::XML(f) }
19
-
20
- # Extract changes from XML
21
- changes = extract_changes(xml_doc)
22
- description = generate_description(xml_doc)
32
+ xml_content = File.read(input_file)
23
33
 
24
- # Load or create change schema
25
- change_schema = if output_file && File.exist?(output_file) && File.size(output_file).positive?
26
- Expressir::Changes::SchemaChange.from_file(output_file)
27
- else
28
- Expressir::Changes::SchemaChange.create_new(schema_name)
29
- end
34
+ # Load existing schema if output file exists
35
+ existing_schema = if output_file && File.exist?(output_file) && File.size(output_file).positive?
36
+ Expressir::Changes::SchemaChange.from_file(output_file)
37
+ end
30
38
 
31
- # Add or update edition
32
- change_schema.add_or_update_edition(version, description, changes)
39
+ change_schema = from_xml(xml_content, schema_name, version,
40
+ existing_schema: existing_schema, **options)
33
41
 
34
- # Save to file
35
42
  if output_file
36
43
  change_schema.to_file(output_file)
37
44
  puts "Change YAML file written to: #{output_file}" if options[:verbose]
@@ -42,65 +49,126 @@ module Expressir
42
49
  change_schema
43
50
  end
44
51
 
45
- private
52
+ class << self
53
+ private
46
54
 
47
- def extract_changes(xml_doc)
48
- {
49
- additions: extract_added_objects(xml_doc),
50
- modifications: extract_modified_objects(xml_doc),
51
- removals: extract_removed_objects(xml_doc),
52
- }
53
- end
55
+ def convert_to_schema_change(compare_report, schema_name, version,
56
+ **options)
57
+ require "expressir/changes"
58
+
59
+ # Extract changes from CompareReport
60
+ changes = {
61
+ additions: extract_items(compare_report.additions,
62
+ options[:xml_content]),
63
+ modifications: extract_items(compare_report.modifications,
64
+ options[:xml_content]),
65
+ deletions: extract_items(compare_report.deletions,
66
+ options[:xml_content]),
67
+ }
68
+
69
+ # Use existing schema or create new one
70
+ change_schema = options[:existing_schema] ||
71
+ Expressir::Changes::SchemaChange.new(schema: schema_name)
54
72
 
55
- def extract_modified_objects(xml_doc)
56
- xml_doc.xpath("//schema.modifications/modified.object").map do |node|
57
- Expressir::Changes::ItemChange.new(
58
- type: node["type"],
59
- name: node["name"],
60
- )
73
+ # No edition-level description from eengine (only item-level)
74
+ change_schema.add_or_update_edition(version, nil, changes)
75
+
76
+ change_schema
61
77
  end
62
- end
63
78
 
64
- def extract_added_objects(xml_doc)
65
- xml_doc.xpath("//schema.additions/added.object").map do |node|
66
- Expressir::Changes::ItemChange.new(
67
- type: node["type"],
68
- name: node["name"],
69
- )
79
+ def extract_items(changes_section, xml_content)
80
+ return [] unless changes_section&.modified_objects
81
+
82
+ # Extract descriptions from XML as arrays
83
+ descriptions = extract_descriptions_from_xml(xml_content)
84
+
85
+ changes_section.modified_objects.map do |obj|
86
+ Expressir::Changes::ItemChange.new(
87
+ type: obj.type,
88
+ name: obj.name,
89
+ interfaced_items: obj.interfaced_items,
90
+ description: descriptions[obj.name],
91
+ )
92
+ end
70
93
  end
71
- end
72
94
 
73
- def extract_removed_objects(xml_doc)
74
- xml_doc.xpath("//schema.removals/removed.object").map do |node|
75
- Expressir::Changes::ItemChange.new(
76
- type: node["type"],
77
- name: node["name"],
78
- )
95
+ def extract_descriptions_from_xml(xml_content)
96
+ return {} unless xml_content
97
+
98
+ require "nokogiri"
99
+ doc = Nokogiri::XML(xml_content)
100
+
101
+ doc.xpath("//modified.object").each_with_object({}) do |node, result|
102
+ name = node["name"]
103
+ desc_node = node.at_xpath("description")
104
+ next unless desc_node
105
+
106
+ html = desc_node.inner_html.strip
107
+ next if html.empty?
108
+
109
+ # Extract <li> elements or use text content
110
+ li_elements = Nokogiri::HTML.fragment(html).css("li")
111
+ result[name] = if li_elements.any?
112
+ li_elements.map do |li|
113
+ li.text.strip
114
+ end.reject(&:empty?)
115
+ else
116
+ [Nokogiri::HTML.fragment(html).text.strip]
117
+ end
118
+ end
79
119
  end
80
- end
81
120
 
82
- def generate_description(xml_doc)
83
- parts = []
121
+ def extract_description(compare_report)
122
+ parts = []
84
123
 
85
- # Get descriptions from modifications
86
- xml_doc.xpath("//schema.modifications/modified.object/description").each do |desc|
87
- text = desc.text.strip
88
- parts << text unless text.empty?
89
- end
124
+ [compare_report.modifications, compare_report.additions,
125
+ compare_report.deletions].each do |section|
126
+ next unless section&.modified_objects
90
127
 
91
- # Get descriptions from additions
92
- xml_doc.xpath("//schema.additions/added.object/description").each do |desc|
93
- text = desc.text.strip
94
- parts << text unless text.empty?
128
+ section.modified_objects.each do |obj|
129
+ next unless obj.description
130
+
131
+ description_text = normalize_description(obj.description)
132
+ next if description_text.strip.empty?
133
+
134
+ parts << convert_html_to_asciidoc(description_text.strip)
135
+ end
136
+ end
137
+
138
+ parts.empty? ? nil : parts.join("\n\n")
95
139
  end
96
140
 
97
- # Get descriptions from removals
98
- xml_doc.xpath("//schema.removals/removed.object/description").each do |desc|
99
- text = desc.text.strip
100
- parts << text unless text.empty?
141
+ def normalize_description(description)
142
+ # Handle both String and Array (when XML has nested elements)
143
+ case description
144
+ when String
145
+ description
146
+ when Array
147
+ # Join array elements, handling nested structures
148
+ description.map { |elem| normalize_description(elem) }.join("\n")
149
+ when Hash
150
+ # Handle hash elements (from XML parsing)
151
+ if description.key?("__text__")
152
+ description["__text__"]
153
+ else
154
+ description.values.map { |v| normalize_description(v) }.join("\n")
155
+ end
156
+ else
157
+ description.to_s
158
+ end
101
159
  end
102
160
 
103
- parts.join("\n\n")
161
+ def convert_html_to_asciidoc(text)
162
+ # Convert <ul><li>...</li></ul> to AsciiDoc list format
163
+ text = text.gsub(%r{<ul>\s*}i, "")
164
+ text = text.gsub(%r{\s*</ul>}i, "")
165
+ text = text.gsub(%r{<li>(.*?)</li>}im) do
166
+ "* #{Regexp.last_match(1).strip}"
167
+ end
168
+
169
+ # Clean up any extra whitespace
170
+ text.strip
171
+ end
104
172
  end
105
173
  end
106
174
  end
@@ -31,7 +31,7 @@ module Expressir
31
31
 
32
32
  say "✓ File is valid" if options[:verbose]
33
33
  say " Schema: #{schema_change.schema}" if options[:verbose]
34
- say " Editions: #{schema_change.edition_change.length}" if options[:verbose]
34
+ say " Editions: #{schema_change.editions.length}" if options[:verbose]
35
35
 
36
36
  # Normalize if requested
37
37
  if options[:normalize]
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require_relative "changes_section"
5
+ require_relative "modified_object"
6
+
7
+ module Expressir
8
+ module Eengine
9
+ # Represents an Eengine ARM comparison XML report
10
+ class ArmCompareReport < Lutaml::Model::Serializable
11
+ attribute :modifications, ChangesSection
12
+ attribute :additions, ChangesSection
13
+ attribute :deletions, ChangesSection
14
+
15
+ xml do
16
+ root "arm.changes"
17
+ map_element "arm.modifications", to: :modifications
18
+ map_element "arm.additions", to: :additions
19
+ map_element "arm.deletions", to: :deletions
20
+ end
21
+
22
+ def mode
23
+ "arm"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require_relative "modified_object"
5
+
6
+ module Expressir
7
+ module Eengine
8
+ # Represents a section of changes (modifications, additions, or deletions)
9
+ # in an Eengine comparison report
10
+ class ChangesSection < Lutaml::Model::Serializable
11
+ attribute :modified_objects, ModifiedObject, collection: true
12
+
13
+ xml do
14
+ root "changes.section"
15
+ map_element "modified.object", to: :modified_objects
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ Lutaml::Model::Config.configure do |config|
6
+ require "lutaml/model/xml_adapter/nokogiri_adapter"
7
+ config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
8
+ end
9
+
10
+ require_relative "changes_section"
11
+ require_relative "modified_object"
12
+ require_relative "arm_compare_report"
13
+ require_relative "mim_compare_report"
14
+
15
+ module Expressir
16
+ module Eengine
17
+ # Represents an Eengine comparison XML report
18
+ # Supports three modes: ARM, MIM, and Schema
19
+ class CompareReport < Lutaml::Model::Serializable
20
+ attribute :modifications, ChangesSection
21
+ attribute :additions, ChangesSection
22
+ attribute :deletions, ChangesSection
23
+
24
+ xml do
25
+ root "schema.changes"
26
+ map_element "schema.modifications", to: :modifications
27
+ map_element "schema.additions", to: :additions
28
+ map_element "schema.deletions", to: :deletions
29
+ end
30
+
31
+ class << self
32
+ # Parse XML and return appropriate report class based on mode
33
+ #
34
+ # @param xml_content [String] XML content
35
+ # @return [CompareReport, ArmCompareReport, MimCompareReport]
36
+ def from_xml(xml_content)
37
+ mode = detect_mode(xml_content)
38
+
39
+ case mode
40
+ when "arm"
41
+ ArmCompareReport.from_xml(xml_content)
42
+ when "mim"
43
+ MimCompareReport.from_xml(xml_content)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ # Load a CompareReport from an XML file
50
+ #
51
+ # @param path [String] Path to the XML file
52
+ # @return [CompareReport] The loaded comparison report
53
+ def from_file(path)
54
+ from_xml(File.read(path))
55
+ end
56
+
57
+ private
58
+
59
+ # Detect XML mode from content
60
+ #
61
+ # @param xml_content [String] XML content
62
+ # @return [String] "arm", "mim", or "schema"
63
+ def detect_mode(xml_content)
64
+ if xml_content.include?("<arm.changes")
65
+ "arm"
66
+ elsif xml_content.include?("<mim.changes")
67
+ "mim"
68
+ else
69
+ "schema"
70
+ end
71
+ end
72
+ end
73
+
74
+ # Detect XML mode from the report
75
+ # @return [String] "arm", "mim", or "schema"
76
+ def mode
77
+ "schema"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require_relative "changes_section"
5
+ require_relative "modified_object"
6
+
7
+ module Expressir
8
+ module Eengine
9
+ # Represents an Eengine MIM comparison XML report
10
+ class MimCompareReport < Lutaml::Model::Serializable
11
+ attribute :modifications, ChangesSection
12
+ attribute :additions, ChangesSection
13
+ attribute :deletions, ChangesSection
14
+
15
+ xml do
16
+ root "mim.changes"
17
+ map_element "mim.modifications", to: :modifications
18
+ map_element "mim.additions", to: :additions
19
+ map_element "mim.deletions", to: :deletions
20
+ end
21
+
22
+ def mode
23
+ "mim"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Expressir
6
+ module Eengine
7
+ # Represents a modified EXPRESS object in an Eengine comparison report
8
+ class ModifiedObject < Lutaml::Model::Serializable
9
+ attribute :type, :string
10
+ attribute :name, :string
11
+ attribute :interfaced_items, :string
12
+ attribute :description, :string
13
+
14
+ xml do
15
+ root "modified.object"
16
+ map_attribute "type", to: :type
17
+ map_attribute "name", to: :name
18
+ map_attribute "interfaced.items", to: :interfaced_items
19
+ map_element "description", to: :description
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Expressir
2
- VERSION = "2.1.27".freeze
2
+ VERSION = "2.1.29".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.27
4
+ version: 2.1.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-12 00:00:00.000000000 Z
11
+ date: 2025-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: moxml
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: parslet
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +202,11 @@ files:
188
202
  - lib/expressir/commands/version.rb
189
203
  - lib/expressir/config.rb
190
204
  - lib/expressir/coverage.rb
205
+ - lib/expressir/eengine/arm_compare_report.rb
206
+ - lib/expressir/eengine/changes_section.rb
207
+ - lib/expressir/eengine/compare_report.rb
208
+ - lib/expressir/eengine/mim_compare_report.rb
209
+ - lib/expressir/eengine/modified_object.rb
191
210
  - lib/expressir/express/cache.rb
192
211
  - lib/expressir/express/error.rb
193
212
  - lib/expressir/express/formatter.rb