expressir 2.1.30 → 2.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +98 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.github/workflows/validate_schemas.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +244 -39
- data/Gemfile +2 -1
- data/README.adoc +621 -54
- data/docs/Gemfile +12 -0
- data/docs/_config.yml +141 -0
- data/docs/_guides/changes/changes-format.adoc +778 -0
- data/docs/_guides/changes/importing-eengine.adoc +898 -0
- data/docs/_guides/changes/index.adoc +396 -0
- data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
- data/docs/_guides/changes/validating-changes.adoc +681 -0
- data/docs/_guides/cli/benchmark-performance.adoc +834 -0
- data/docs/_guides/cli/coverage-analysis.adoc +921 -0
- data/docs/_guides/cli/format-schemas.adoc +547 -0
- data/docs/_guides/cli/index.adoc +8 -0
- data/docs/_guides/cli/managing-changes.adoc +927 -0
- data/docs/_guides/cli/validate-ascii.adoc +645 -0
- data/docs/_guides/cli/validate-schemas.adoc +534 -0
- data/docs/_guides/index.adoc +165 -0
- data/docs/_guides/ler/creating-packages.adoc +664 -0
- data/docs/_guides/ler/index.adoc +305 -0
- data/docs/_guides/ler/loading-packages.adoc +707 -0
- data/docs/_guides/ler/package-formats.adoc +748 -0
- data/docs/_guides/ler/querying-packages.adoc +826 -0
- data/docs/_guides/ler/validating-packages.adoc +750 -0
- data/docs/_guides/liquid/basic-templates.adoc +813 -0
- data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
- data/docs/_guides/liquid/drops-reference.adoc +829 -0
- data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
- data/docs/_guides/liquid/index.adoc +468 -0
- data/docs/_guides/manifests/creating-manifests.adoc +483 -0
- data/docs/_guides/manifests/index.adoc +307 -0
- data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
- data/docs/_guides/manifests/validating-manifests.adoc +713 -0
- data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
- data/docs/_guides/ruby-api/index.adoc +257 -0
- data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
- data/docs/_guides/ruby-api/search-engine.adoc +609 -0
- data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
- data/docs/_pages/data-model.adoc +665 -0
- data/docs/_pages/express-language.adoc +506 -0
- data/docs/_pages/getting-started.adoc +414 -0
- data/docs/_pages/index.adoc +116 -0
- data/docs/_pages/introduction.adoc +256 -0
- data/docs/_pages/ler-packages.adoc +837 -0
- data/docs/_pages/parsers.adoc +683 -0
- data/docs/_pages/schema-manifests.adoc +431 -0
- data/docs/_references/index.adoc +228 -0
- data/docs/_tutorials/creating-ler-package.adoc +735 -0
- data/docs/_tutorials/documentation-coverage.adoc +795 -0
- data/docs/_tutorials/index.adoc +221 -0
- data/docs/_tutorials/liquid-templates.adoc +806 -0
- data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
- data/docs/_tutorials/querying-schemas.adoc +751 -0
- data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
- data/docs/index.adoc +242 -0
- data/docs/lychee.toml +84 -0
- data/examples/demo_ler_usage.sh +86 -0
- data/examples/ler/README.md +111 -0
- data/examples/ler/simple_example.ler +0 -0
- data/examples/ler/simple_schema.exp +33 -0
- data/examples/ler_build.rb +75 -0
- data/examples/ler_cli.rb +79 -0
- data/examples/ler_demo_complete.rb +276 -0
- data/examples/ler_query.rb +91 -0
- data/examples/ler_query_examples.rb +305 -0
- data/examples/ler_stats.rb +81 -0
- data/examples/phase3_demo.rb +159 -0
- data/examples/query_demo_simple.rb +131 -0
- data/expressir.gemspec +2 -0
- data/lib/expressir/cli.rb +12 -4
- data/lib/expressir/commands/manifest.rb +427 -0
- data/lib/expressir/commands/package.rb +1274 -0
- data/lib/expressir/commands/validate.rb +70 -37
- data/lib/expressir/commands/validate_ascii.rb +607 -0
- data/lib/expressir/commands/validate_load.rb +88 -0
- data/lib/expressir/express/formatter.rb +5 -1
- data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
- data/lib/expressir/express/parser.rb +33 -0
- data/lib/expressir/manifest/resolver.rb +213 -0
- data/lib/expressir/manifest/validator.rb +195 -0
- data/lib/expressir/model/declarations/entity.rb +6 -0
- data/lib/expressir/model/dependency_resolver.rb +270 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/reference_index.rb +148 -0
- data/lib/expressir/model/indexes/type_index.rb +149 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/repository.rb +400 -5
- data/lib/expressir/model/repository_validator.rb +295 -0
- data/lib/expressir/model/search_engine.rb +525 -0
- data/lib/expressir/model.rb +4 -94
- data/lib/expressir/package/builder.rb +200 -0
- data/lib/expressir/package/metadata.rb +81 -0
- data/lib/expressir/package/reader.rb +165 -0
- data/lib/expressir/schema_manifest.rb +11 -1
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +15 -2
- metadata +114 -4
- data/docs/benchmarking.adoc +0 -107
- data/docs/liquid_drops.adoc +0 -1547
|
@@ -0,0 +1,898 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Importing from Express Engine
|
|
3
|
+
parent: Changes
|
|
4
|
+
grand_parent: Overview
|
|
5
|
+
nav_order: 3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Importing from Express Engine
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
Express Engine (eengine) is a commercial tool that can compare EXPRESS schema
|
|
13
|
+
versions and generate detailed XML comparison reports. Expressir can import
|
|
14
|
+
these reports to create or update EXPRESS Changes files automatically.
|
|
15
|
+
|
|
16
|
+
== References
|
|
17
|
+
|
|
18
|
+
* link:index.html[Changes Overview] - Introduction to Changes files
|
|
19
|
+
* link:changes-format.html[Changes Format] - YAML format specification
|
|
20
|
+
* link:validating-changes.html[Validating Changes] - Validation guide
|
|
21
|
+
* link:programmatic-usage.html[Programmatic Usage] - Ruby API for import
|
|
22
|
+
|
|
23
|
+
== Concepts
|
|
24
|
+
|
|
25
|
+
Express Engine:: Commercial EXPRESS schema comparison tool that generates XML
|
|
26
|
+
reports showing differences between schema versions
|
|
27
|
+
|
|
28
|
+
comparison report:: XML document describing additions, modifications, and
|
|
29
|
+
deletions between two schema versions
|
|
30
|
+
|
|
31
|
+
automatic mode detection:: Expressir automatically detects whether XML uses
|
|
32
|
+
Schema, ARM, or MIM mode
|
|
33
|
+
|
|
34
|
+
incremental import:: Adding new versions to existing Changes files without
|
|
35
|
+
replacing previous versions
|
|
36
|
+
|
|
37
|
+
interfaced_items:: Field tracking which items are imported via `USE_FROM` or
|
|
38
|
+
`REFERENCE_FROM` statements
|
|
39
|
+
|
|
40
|
+
== Express Engine XML format
|
|
41
|
+
|
|
42
|
+
=== What is Express Engine?
|
|
43
|
+
|
|
44
|
+
Express Engine (eengine) is a commercial tool developed for working with
|
|
45
|
+
EXPRESS schemas. One of its key features is comparing two versions of a schema
|
|
46
|
+
and generating a detailed XML report of the differences.
|
|
47
|
+
|
|
48
|
+
Expressir is compatible with **Express Engine v5.2.7** XML output format.
|
|
49
|
+
|
|
50
|
+
=== Three XML modes
|
|
51
|
+
|
|
52
|
+
Express Engine generates comparison reports in three different modes, each with
|
|
53
|
+
a distinct XML structure:
|
|
54
|
+
|
|
55
|
+
Schema mode:: Standard schema comparison
|
|
56
|
+
+
|
|
57
|
+
[source,xml]
|
|
58
|
+
----
|
|
59
|
+
<schema.changes schema_name="action_schema">
|
|
60
|
+
<schema.modifications>
|
|
61
|
+
<modified.object type="ENTITY" name="action"/>
|
|
62
|
+
</schema.modifications>
|
|
63
|
+
<schema.additions>
|
|
64
|
+
<modified.object type="FUNCTION" name="new_function"/>
|
|
65
|
+
</schema.additions>
|
|
66
|
+
<schema.deletions>
|
|
67
|
+
<modified.object type="CONSTANT" name="old_constant"/>
|
|
68
|
+
</schema.deletions>
|
|
69
|
+
</schema.changes>
|
|
70
|
+
----
|
|
71
|
+
|
|
72
|
+
ARM mode:: Application Reference Model comparison
|
|
73
|
+
+
|
|
74
|
+
[source,xml]
|
|
75
|
+
----
|
|
76
|
+
<arm.changes schema_name="action_arm">
|
|
77
|
+
<arm.modifications>
|
|
78
|
+
<modified.object type="ENTITY" name="arm_entity"/>
|
|
79
|
+
</arm.modifications>
|
|
80
|
+
<arm.additions>
|
|
81
|
+
<modified.object type="TYPE" name="new_arm_type"/>
|
|
82
|
+
</arm.additions>
|
|
83
|
+
<arm.deletions>
|
|
84
|
+
<modified.object type="FUNCTION" name="old_arm_function"/>
|
|
85
|
+
</arm.deletions>
|
|
86
|
+
</arm.changes>
|
|
87
|
+
----
|
|
88
|
+
|
|
89
|
+
MIM mode:: Module Implementation Model comparison
|
|
90
|
+
+
|
|
91
|
+
[source,xml]
|
|
92
|
+
----
|
|
93
|
+
<mim.changes schema_name="action_mim">
|
|
94
|
+
<mim.modifications>
|
|
95
|
+
<modified.object type="ENTITY" name="mim_entity"/>
|
|
96
|
+
</mim.modifications>
|
|
97
|
+
<mim.additions>
|
|
98
|
+
<modified.object type="TYPE" name="new_mim_type"/>
|
|
99
|
+
</mim.additions>
|
|
100
|
+
<mim.deletions>
|
|
101
|
+
<modified.object type="FUNCTION" name="old_mim_function"/>
|
|
102
|
+
</mim.deletions>
|
|
103
|
+
</mim.changes>
|
|
104
|
+
----
|
|
105
|
+
|
|
106
|
+
=== Automatic mode detection
|
|
107
|
+
|
|
108
|
+
Expressir automatically detects which mode is used by examining the XML root
|
|
109
|
+
element:
|
|
110
|
+
|
|
111
|
+
* `<schema.changes>` → Schema mode
|
|
112
|
+
* `<arm.changes>` → ARM mode
|
|
113
|
+
* `<mim.changes>` → MIM mode
|
|
114
|
+
|
|
115
|
+
You don't need to specify the mode manually.
|
|
116
|
+
|
|
117
|
+
=== XML structure elements
|
|
118
|
+
|
|
119
|
+
Each XML comparison report contains:
|
|
120
|
+
|
|
121
|
+
modified.object:: Individual change item with attributes:
|
|
122
|
+
* `type` - EXPRESS construct type (ENTITY, FUNCTION, etc.)
|
|
123
|
+
* `name` - Name of the changed item
|
|
124
|
+
* `interfaced.items` - For USE_FROM/REFERENCE_FROM (optional)
|
|
125
|
+
|
|
126
|
+
description:: Optional nested element with HTML-formatted change description
|
|
127
|
+
|
|
128
|
+
.XML with descriptions
|
|
129
|
+
[example]
|
|
130
|
+
====
|
|
131
|
+
[source,xml]
|
|
132
|
+
----
|
|
133
|
+
<schema.changes schema_name="action_schema">
|
|
134
|
+
<schema.modifications>
|
|
135
|
+
<modified.object type="ENTITY" name="action">
|
|
136
|
+
<description>
|
|
137
|
+
<ul>
|
|
138
|
+
<li>Added new attribute 'status'</li>
|
|
139
|
+
<li>Modified WHERE rules</li>
|
|
140
|
+
</ul>
|
|
141
|
+
</description>
|
|
142
|
+
</modified.object>
|
|
143
|
+
</schema.modifications>
|
|
144
|
+
</schema.changes>
|
|
145
|
+
----
|
|
146
|
+
|
|
147
|
+
This converts to:
|
|
148
|
+
|
|
149
|
+
[source,yaml]
|
|
150
|
+
----
|
|
151
|
+
modifications:
|
|
152
|
+
- type: ENTITY
|
|
153
|
+
name: action
|
|
154
|
+
description:
|
|
155
|
+
- Added new attribute 'status'
|
|
156
|
+
- Modified WHERE rules
|
|
157
|
+
----
|
|
158
|
+
====
|
|
159
|
+
|
|
160
|
+
== CLI import
|
|
161
|
+
|
|
162
|
+
=== Basic import syntax
|
|
163
|
+
|
|
164
|
+
[source,bash]
|
|
165
|
+
----
|
|
166
|
+
expressir changes import-eengine INPUT_XML SCHEMA_NAME VERSION [options]
|
|
167
|
+
----
|
|
168
|
+
|
|
169
|
+
Where:
|
|
170
|
+
|
|
171
|
+
`INPUT_XML`:: Path to Express Engine comparison XML file
|
|
172
|
+
`SCHEMA_NAME`:: Name of the schema being tracked
|
|
173
|
+
`VERSION`:: Version number for these changes
|
|
174
|
+
|
|
175
|
+
=== Import to stdout
|
|
176
|
+
|
|
177
|
+
Import and display YAML on stdout:
|
|
178
|
+
|
|
179
|
+
[source,bash]
|
|
180
|
+
----
|
|
181
|
+
expressir changes import-eengine comparison.xml action_schema "2"
|
|
182
|
+
----
|
|
183
|
+
|
|
184
|
+
.Output example
|
|
185
|
+
[example]
|
|
186
|
+
====
|
|
187
|
+
[source,yaml]
|
|
188
|
+
----
|
|
189
|
+
schema: action_schema
|
|
190
|
+
versions:
|
|
191
|
+
- version: 2
|
|
192
|
+
additions:
|
|
193
|
+
- type: ENTITY
|
|
194
|
+
name: new_entity
|
|
195
|
+
modifications:
|
|
196
|
+
- type: FUNCTION
|
|
197
|
+
name: updated_function
|
|
198
|
+
----
|
|
199
|
+
====
|
|
200
|
+
|
|
201
|
+
=== Import to file
|
|
202
|
+
|
|
203
|
+
Save imported changes to a YAML file:
|
|
204
|
+
|
|
205
|
+
[source,bash]
|
|
206
|
+
----
|
|
207
|
+
expressir changes import-eengine comparison.xml action_schema "2" \
|
|
208
|
+
-o action_schema.changes.yaml
|
|
209
|
+
----
|
|
210
|
+
|
|
211
|
+
Or using long format:
|
|
212
|
+
|
|
213
|
+
[source,bash]
|
|
214
|
+
----
|
|
215
|
+
expressir changes import-eengine comparison.xml action_schema "2" \
|
|
216
|
+
--output action_schema.changes.yaml
|
|
217
|
+
----
|
|
218
|
+
|
|
219
|
+
=== Verbose output
|
|
220
|
+
|
|
221
|
+
Show detailed information during import:
|
|
222
|
+
|
|
223
|
+
[source,bash]
|
|
224
|
+
----
|
|
225
|
+
expressir changes import-eengine comparison.xml action_schema "2" \
|
|
226
|
+
-o output.yaml --verbose
|
|
227
|
+
----
|
|
228
|
+
|
|
229
|
+
.Verbose output example
|
|
230
|
+
[example]
|
|
231
|
+
====
|
|
232
|
+
[source,bash]
|
|
233
|
+
----
|
|
234
|
+
$ expressir changes import-eengine comparison.xml action_schema "2" \
|
|
235
|
+
-o output.yaml --verbose
|
|
236
|
+
Detected mode: schema
|
|
237
|
+
Found 5 additions
|
|
238
|
+
Found 3 modifications
|
|
239
|
+
Found 1 deletion
|
|
240
|
+
Change YAML file written to: output.yaml
|
|
241
|
+
----
|
|
242
|
+
====
|
|
243
|
+
|
|
244
|
+
=== Import options
|
|
245
|
+
|
|
246
|
+
[options="header"]
|
|
247
|
+
|===
|
|
248
|
+
| Option | Short | Description | Example
|
|
249
|
+
|
|
250
|
+
| `--output PATH`
|
|
251
|
+
| `-o PATH`
|
|
252
|
+
| Output YAML file path
|
|
253
|
+
| `-o output.yaml`
|
|
254
|
+
|
|
255
|
+
| `--verbose`
|
|
256
|
+
| N/A
|
|
257
|
+
| Show detailed output
|
|
258
|
+
| `--verbose`
|
|
259
|
+
|===
|
|
260
|
+
|
|
261
|
+
== Building change history
|
|
262
|
+
|
|
263
|
+
=== Incremental version building
|
|
264
|
+
|
|
265
|
+
When the output file already exists, the import command intelligently merges
|
|
266
|
+
the new version with existing versions:
|
|
267
|
+
|
|
268
|
+
Same version:: Replaces the existing version with that version number
|
|
269
|
+
+
|
|
270
|
+
[source,bash]
|
|
271
|
+
----
|
|
272
|
+
# First import (creates file)
|
|
273
|
+
expressir changes import-eengine v2.xml schema "2" -o changes.yaml
|
|
274
|
+
|
|
275
|
+
# Reimport same version (replaces version 2)
|
|
276
|
+
expressir changes import-eengine v2_updated.xml schema "2" -o changes.yaml
|
|
277
|
+
----
|
|
278
|
+
|
|
279
|
+
New version:: Adds the new version to the file
|
|
280
|
+
+
|
|
281
|
+
[source,bash]
|
|
282
|
+
----
|
|
283
|
+
# First import (creates file with version 2)
|
|
284
|
+
expressir changes import-eengine v2.xml schema "2" -o changes.yaml
|
|
285
|
+
|
|
286
|
+
# Import version 3 (appends to existing file)
|
|
287
|
+
expressir changes import-eengine v3.xml schema "3" -o changes.yaml
|
|
288
|
+
----
|
|
289
|
+
|
|
290
|
+
=== Multi-version import workflow
|
|
291
|
+
|
|
292
|
+
Build a complete change history incrementally:
|
|
293
|
+
|
|
294
|
+
.Importing multiple versions
|
|
295
|
+
[example]
|
|
296
|
+
====
|
|
297
|
+
[source,bash]
|
|
298
|
+
----
|
|
299
|
+
# Import version 2
|
|
300
|
+
expressir changes import-eengine v2_comparison.xml action_schema "2" \
|
|
301
|
+
-o action_schema.changes.yaml
|
|
302
|
+
|
|
303
|
+
# Import version 3 (appends)
|
|
304
|
+
expressir changes import-eengine v3_comparison.xml action_schema "3" \
|
|
305
|
+
-o action_schema.changes.yaml
|
|
306
|
+
|
|
307
|
+
# Import version 4 (appends)
|
|
308
|
+
expressir changes import-eengine v4_comparison.xml action_schema "4" \
|
|
309
|
+
-o action_schema.changes.yaml
|
|
310
|
+
|
|
311
|
+
# Verify complete history
|
|
312
|
+
cat action_schema.changes.yaml
|
|
313
|
+
----
|
|
314
|
+
|
|
315
|
+
Results in:
|
|
316
|
+
|
|
317
|
+
[source,yaml]
|
|
318
|
+
----
|
|
319
|
+
schema: action_schema
|
|
320
|
+
versions:
|
|
321
|
+
- version: 2
|
|
322
|
+
additions: [...]
|
|
323
|
+
modifications: [...]
|
|
324
|
+
- version: 3
|
|
325
|
+
additions: [...]
|
|
326
|
+
modifications: [...]
|
|
327
|
+
- version: 4
|
|
328
|
+
additions: [...]
|
|
329
|
+
modifications: [...]
|
|
330
|
+
----
|
|
331
|
+
====
|
|
332
|
+
|
|
333
|
+
=== Overwriting existing versions
|
|
334
|
+
|
|
335
|
+
If you reimport the same version, it replaces the existing one:
|
|
336
|
+
|
|
337
|
+
[source,bash]
|
|
338
|
+
----
|
|
339
|
+
# Initial import
|
|
340
|
+
expressir changes import-eengine v2.xml schema "2" -o changes.yaml
|
|
341
|
+
|
|
342
|
+
# Update version 2 (replaces existing version 2)
|
|
343
|
+
expressir changes import-eengine v2_revised.xml schema "2" -o changes.yaml
|
|
344
|
+
----
|
|
345
|
+
|
|
346
|
+
This is useful when:
|
|
347
|
+
|
|
348
|
+
* Express Engine comparison was incorrect
|
|
349
|
+
* Need to update descriptions
|
|
350
|
+
* XML format changed
|
|
351
|
+
|
|
352
|
+
== Interface changes
|
|
353
|
+
|
|
354
|
+
=== Understanding interfaced_items
|
|
355
|
+
|
|
356
|
+
The `interfaced.items` attribute in Express Engine XML specifies which items
|
|
357
|
+
are being imported or referenced from another schema via `USE_FROM` or
|
|
358
|
+
`REFERENCE_FROM` statements.
|
|
359
|
+
|
|
360
|
+
.XML with interface changes
|
|
361
|
+
[example]
|
|
362
|
+
====
|
|
363
|
+
[source,xml]
|
|
364
|
+
----
|
|
365
|
+
<schema.changes schema_name="aic_csg">
|
|
366
|
+
<schema.additions>
|
|
367
|
+
<modified.object type="USE_FROM" name="geometric_model_schema"
|
|
368
|
+
interfaced.items="convex_hexahedron" />
|
|
369
|
+
|
|
370
|
+
<modified.object type="USE_FROM" name="geometric_model_schema"
|
|
371
|
+
interfaced.items="cyclide_segment_solid" />
|
|
372
|
+
|
|
373
|
+
<modified.object type="REFERENCE_FROM" name="measure_schema"
|
|
374
|
+
interfaced.items="length_measure" />
|
|
375
|
+
</schema.additions>
|
|
376
|
+
</schema.changes>
|
|
377
|
+
----
|
|
378
|
+
|
|
379
|
+
Converts to:
|
|
380
|
+
|
|
381
|
+
[source,yaml]
|
|
382
|
+
----
|
|
383
|
+
schema: aic_csg
|
|
384
|
+
versions:
|
|
385
|
+
- version: 2
|
|
386
|
+
additions:
|
|
387
|
+
- type: USE_FROM
|
|
388
|
+
name: geometric_model_schema
|
|
389
|
+
interfaced_items: convex_hexahedron
|
|
390
|
+
- type: USE_FROM
|
|
391
|
+
name: geometric_model_schema
|
|
392
|
+
interfaced_items: cyclide_segment_solid
|
|
393
|
+
- type: REFERENCE_FROM
|
|
394
|
+
name: measure_schema
|
|
395
|
+
interfaced_items: length_measure
|
|
396
|
+
----
|
|
397
|
+
====
|
|
398
|
+
|
|
399
|
+
=== Separate entries per item
|
|
400
|
+
|
|
401
|
+
Express Engine creates separate `<modified.object>` entries for each imported
|
|
402
|
+
item, even from the same schema. Expressir preserves this structure:
|
|
403
|
+
|
|
404
|
+
[source,xml]
|
|
405
|
+
----
|
|
406
|
+
<!-- Separate entries for each item -->
|
|
407
|
+
<modified.object type="USE_FROM" name="schema_a"
|
|
408
|
+
interfaced.items="item1" />
|
|
409
|
+
<modified.object type="USE_FROM" name="schema_a"
|
|
410
|
+
interfaced.items="item2" />
|
|
411
|
+
----
|
|
412
|
+
|
|
413
|
+
This ensures clarity about which specific items changed.
|
|
414
|
+
|
|
415
|
+
== Description handling
|
|
416
|
+
|
|
417
|
+
=== HTML to array conversion
|
|
418
|
+
|
|
419
|
+
Express Engine descriptions can contain HTML formatting. Expressir automatically
|
|
420
|
+
converts HTML lists to YAML arrays:
|
|
421
|
+
|
|
422
|
+
.HTML list in XML
|
|
423
|
+
[example]
|
|
424
|
+
====
|
|
425
|
+
[source,xml]
|
|
426
|
+
----
|
|
427
|
+
<modified.object type="ENTITY" name="action">
|
|
428
|
+
<description>
|
|
429
|
+
<ul>
|
|
430
|
+
<li>Added new attribute 'priority'</li>
|
|
431
|
+
<li>Modified WHERE rule WR1</li>
|
|
432
|
+
<li>Updated documentation</li>
|
|
433
|
+
</ul>
|
|
434
|
+
</description>
|
|
435
|
+
</modified.object>
|
|
436
|
+
----
|
|
437
|
+
|
|
438
|
+
Converts to:
|
|
439
|
+
|
|
440
|
+
[source,yaml]
|
|
441
|
+
----
|
|
442
|
+
- type: ENTITY
|
|
443
|
+
name: action
|
|
444
|
+
description:
|
|
445
|
+
- Added new attribute 'priority'
|
|
446
|
+
- Modified WHERE rule WR1
|
|
447
|
+
- Updated documentation
|
|
448
|
+
----
|
|
449
|
+
====
|
|
450
|
+
|
|
451
|
+
=== Plain text descriptions
|
|
452
|
+
|
|
453
|
+
Non-list descriptions are preserved as single-item arrays:
|
|
454
|
+
|
|
455
|
+
[source,xml]
|
|
456
|
+
----
|
|
457
|
+
<modified.object type="FUNCTION" name="validate">
|
|
458
|
+
<description>Updated validation logic</description>
|
|
459
|
+
</modified.object>
|
|
460
|
+
----
|
|
461
|
+
|
|
462
|
+
Converts to:
|
|
463
|
+
|
|
464
|
+
[source,yaml]
|
|
465
|
+
----
|
|
466
|
+
- type: FUNCTION
|
|
467
|
+
name: validate
|
|
468
|
+
description:
|
|
469
|
+
- Updated validation logic
|
|
470
|
+
----
|
|
471
|
+
|
|
472
|
+
=== Missing descriptions
|
|
473
|
+
|
|
474
|
+
Items without descriptions in the XML will not have a `description` field in
|
|
475
|
+
the YAML:
|
|
476
|
+
|
|
477
|
+
[source,xml]
|
|
478
|
+
----
|
|
479
|
+
<modified.object type="TYPE" name="status_type" />
|
|
480
|
+
----
|
|
481
|
+
|
|
482
|
+
Converts to:
|
|
483
|
+
|
|
484
|
+
[source,yaml]
|
|
485
|
+
----
|
|
486
|
+
- type: TYPE
|
|
487
|
+
name: status_type
|
|
488
|
+
----
|
|
489
|
+
|
|
490
|
+
== API import
|
|
491
|
+
|
|
492
|
+
=== From XML string
|
|
493
|
+
|
|
494
|
+
Import Express Engine XML directly from a string:
|
|
495
|
+
|
|
496
|
+
[source,ruby]
|
|
497
|
+
----
|
|
498
|
+
require "expressir/commands/changes_import_eengine"
|
|
499
|
+
|
|
500
|
+
xml_content = File.read("comparison.xml")
|
|
501
|
+
|
|
502
|
+
# Parse and convert to SchemaChange
|
|
503
|
+
changes = Expressir::Commands::ChangesImportEengine.from_xml(
|
|
504
|
+
xml_content,
|
|
505
|
+
"action_schema", # Schema name
|
|
506
|
+
"2" # Version
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
# Access imported data
|
|
510
|
+
puts "Schema: #{changes.schema}"
|
|
511
|
+
changes.versions.first.additions.each do |item|
|
|
512
|
+
puts "Added #{item.type}: #{item.name}"
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Save to file
|
|
516
|
+
changes.to_file("output.changes.yaml")
|
|
517
|
+
----
|
|
518
|
+
|
|
519
|
+
=== From XML file
|
|
520
|
+
|
|
521
|
+
Import directly from a file (backward compatible method):
|
|
522
|
+
|
|
523
|
+
[source,ruby]
|
|
524
|
+
----
|
|
525
|
+
require "expressir/commands/changes_import_eengine"
|
|
526
|
+
|
|
527
|
+
# Import and save
|
|
528
|
+
Expressir::Commands::ChangesImportEengine.call(
|
|
529
|
+
"comparison.xml", # Input XML file
|
|
530
|
+
"output.changes.yaml", # Output YAML file
|
|
531
|
+
"action_schema", # Schema name
|
|
532
|
+
"2", # Version
|
|
533
|
+
verbose: true # Show progress
|
|
534
|
+
)
|
|
535
|
+
----
|
|
536
|
+
|
|
537
|
+
=== Appending to existing file
|
|
538
|
+
|
|
539
|
+
Add a new version to an existing Changes file:
|
|
540
|
+
|
|
541
|
+
[source,ruby]
|
|
542
|
+
----
|
|
543
|
+
require "expressir/changes"
|
|
544
|
+
require "expressir/commands/changes_import_eengine"
|
|
545
|
+
|
|
546
|
+
# Load existing changes
|
|
547
|
+
existing = if File.exist?("schema.changes.yaml")
|
|
548
|
+
Expressir::Changes::SchemaChange.from_file("schema.changes.yaml")
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# Import new version
|
|
552
|
+
xml_content = File.read("v3_comparison.xml")
|
|
553
|
+
updated = Expressir::Commands::ChangesImportEengine.from_xml(
|
|
554
|
+
xml_content,
|
|
555
|
+
"action_schema",
|
|
556
|
+
"3",
|
|
557
|
+
existing_schema: existing # Pass existing to append
|
|
558
|
+
)
|
|
559
|
+
|
|
560
|
+
# Save combined result
|
|
561
|
+
updated.to_file("schema.changes.yaml")
|
|
562
|
+
----
|
|
563
|
+
|
|
564
|
+
=== Processing multiple versions
|
|
565
|
+
|
|
566
|
+
Automate importing multiple versions:
|
|
567
|
+
|
|
568
|
+
[source,ruby]
|
|
569
|
+
----
|
|
570
|
+
require "expressir/commands/changes_import_eengine"
|
|
571
|
+
|
|
572
|
+
schema_name = "action_schema"
|
|
573
|
+
output_file = "#{schema_name}.changes.yaml"
|
|
574
|
+
|
|
575
|
+
# Import versions 2-5
|
|
576
|
+
(2..5).each do |version|
|
|
577
|
+
xml_file = "v#{version}_comparison.xml"
|
|
578
|
+
|
|
579
|
+
if File.exist?(xml_file)
|
|
580
|
+
puts "Importing version #{version}..."
|
|
581
|
+
|
|
582
|
+
Expressir::Commands::ChangesImportEengine.call(
|
|
583
|
+
xml_file,
|
|
584
|
+
output_file,
|
|
585
|
+
schema_name,
|
|
586
|
+
version.to_s,
|
|
587
|
+
verbose: true
|
|
588
|
+
)
|
|
589
|
+
else
|
|
590
|
+
puts "Warning: #{xml_file} not found, skipping"
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
puts "Import complete: #{output_file}"
|
|
595
|
+
----
|
|
596
|
+
|
|
597
|
+
== Troubleshooting
|
|
598
|
+
|
|
599
|
+
=== Invalid XML errors
|
|
600
|
+
|
|
601
|
+
**Error**: `Invalid XML format`
|
|
602
|
+
|
|
603
|
+
**Causes**:
|
|
604
|
+
* Malformed XML syntax
|
|
605
|
+
* Incorrect encoding
|
|
606
|
+
* Truncated file
|
|
607
|
+
|
|
608
|
+
**Solutions**:
|
|
609
|
+
|
|
610
|
+
[source,bash]
|
|
611
|
+
----
|
|
612
|
+
# Validate XML syntax
|
|
613
|
+
xmllint comparison.xml
|
|
614
|
+
|
|
615
|
+
# Check encoding
|
|
616
|
+
file comparison.xml
|
|
617
|
+
|
|
618
|
+
# Verify file is complete
|
|
619
|
+
tail comparison.xml # Should see closing tags
|
|
620
|
+
----
|
|
621
|
+
|
|
622
|
+
=== Mode detection issues
|
|
623
|
+
|
|
624
|
+
**Error**: `Unable to detect XML mode`
|
|
625
|
+
|
|
626
|
+
**Cause**: XML doesn't match any expected root element
|
|
627
|
+
|
|
628
|
+
**Solution**: Ensure XML starts with one of:
|
|
629
|
+
* `<schema.changes>`
|
|
630
|
+
* `<arm.changes>`
|
|
631
|
+
* `<mim.changes>`
|
|
632
|
+
|
|
633
|
+
[source,bash]
|
|
634
|
+
----
|
|
635
|
+
# Check root element
|
|
636
|
+
head -n 5 comparison.xml
|
|
637
|
+
----
|
|
638
|
+
|
|
639
|
+
=== Missing interfaced_items
|
|
640
|
+
|
|
641
|
+
**Issue**: `USE_FROM` or `REFERENCE_FROM` items missing `interfaced_items`
|
|
642
|
+
|
|
643
|
+
**Cause**: Express Engine XML missing `interfaced.items` attribute
|
|
644
|
+
|
|
645
|
+
**Impact**: Import succeeds but `interfaced_items` field will be empty
|
|
646
|
+
|
|
647
|
+
**Solution**: Manually add `interfaced_items` to YAML after import:
|
|
648
|
+
|
|
649
|
+
[source,yaml]
|
|
650
|
+
----
|
|
651
|
+
# After import, manually add:
|
|
652
|
+
- type: USE_FROM
|
|
653
|
+
name: geometry_schema
|
|
654
|
+
interfaced_items: point # Add this manually
|
|
655
|
+
----
|
|
656
|
+
|
|
657
|
+
=== File permission errors
|
|
658
|
+
|
|
659
|
+
**Error**: `Permission denied`
|
|
660
|
+
|
|
661
|
+
**Cause**: No write permission for output file or directory
|
|
662
|
+
|
|
663
|
+
**Solutions**:
|
|
664
|
+
|
|
665
|
+
[source,bash]
|
|
666
|
+
----
|
|
667
|
+
# Check permissions
|
|
668
|
+
ls -la output_directory/
|
|
669
|
+
|
|
670
|
+
# Fix permissions
|
|
671
|
+
chmod +w output_directory/
|
|
672
|
+
|
|
673
|
+
# Or save to different location
|
|
674
|
+
expressir changes import-eengine comparison.xml schema "2" \
|
|
675
|
+
-o ~/tmp/output.yaml
|
|
676
|
+
----
|
|
677
|
+
|
|
678
|
+
=== Version conflicts
|
|
679
|
+
|
|
680
|
+
**Issue**: Existing version has different content
|
|
681
|
+
|
|
682
|
+
**Behavior**: Import replaces existing version with same number
|
|
683
|
+
|
|
684
|
+
**Solution**: If you need to preserve both:
|
|
685
|
+
|
|
686
|
+
[source,bash]
|
|
687
|
+
----
|
|
688
|
+
# Save current version
|
|
689
|
+
cp schema.changes.yaml schema.changes.yaml.v2.backup
|
|
690
|
+
|
|
691
|
+
# Import new version 2 (replaces)
|
|
692
|
+
expressir changes import-eengine new_v2.xml schema "2" \
|
|
693
|
+
-o schema.changes.yaml
|
|
694
|
+
|
|
695
|
+
# Compare differences
|
|
696
|
+
diff schema.changes.yaml.v2.backup schema.changes.yaml
|
|
697
|
+
----
|
|
698
|
+
|
|
699
|
+
== Complete workflow examples
|
|
700
|
+
|
|
701
|
+
=== Simple import workflow
|
|
702
|
+
|
|
703
|
+
[source,bash]
|
|
704
|
+
----
|
|
705
|
+
# 1. Get Express Engine comparison XML
|
|
706
|
+
# (Generated by Express Engine comparing v1 to v2)
|
|
707
|
+
|
|
708
|
+
# 2. Import to YAML
|
|
709
|
+
expressir changes import-eengine v2_comparison.xml action_schema "2" \
|
|
710
|
+
-o action_schema.changes.yaml
|
|
711
|
+
|
|
712
|
+
# 3. Validate
|
|
713
|
+
expressir changes validate action_schema.changes.yaml --verbose
|
|
714
|
+
|
|
715
|
+
# 4. Review
|
|
716
|
+
cat action_schema.changes.yaml
|
|
717
|
+
|
|
718
|
+
# 5. Commit
|
|
719
|
+
git add action_schema.changes.yaml
|
|
720
|
+
git commit -m "Import version 2 changes from Express Engine"
|
|
721
|
+
----
|
|
722
|
+
|
|
723
|
+
=== Multi-version workflow
|
|
724
|
+
|
|
725
|
+
[source,bash]
|
|
726
|
+
----
|
|
727
|
+
# Import versions 2-4 incrementally
|
|
728
|
+
for version in 2 3 4; do
|
|
729
|
+
echo "Importing version $version..."
|
|
730
|
+
expressir changes import-eengine \
|
|
731
|
+
"v${version}_comparison.xml" \
|
|
732
|
+
action_schema \
|
|
733
|
+
"$version" \
|
|
734
|
+
-o action_schema.changes.yaml \
|
|
735
|
+
--verbose
|
|
736
|
+
done
|
|
737
|
+
|
|
738
|
+
# Validate final result
|
|
739
|
+
expressir changes validate action_schema.changes.yaml --verbose
|
|
740
|
+
|
|
741
|
+
# Review complete history
|
|
742
|
+
cat action_schema.changes.yaml
|
|
743
|
+
----
|
|
744
|
+
|
|
745
|
+
=== Automated CI workflow
|
|
746
|
+
|
|
747
|
+
[source,bash]
|
|
748
|
+
----
|
|
749
|
+
#!/bin/bash
|
|
750
|
+
# import-changes.sh - Automated import script
|
|
751
|
+
|
|
752
|
+
SCHEMA_NAME="action_schema"
|
|
753
|
+
XML_DIR="eengine_reports"
|
|
754
|
+
OUTPUT_FILE="${SCHEMA_NAME}.changes.yaml"
|
|
755
|
+
|
|
756
|
+
# Find all comparison XMLs
|
|
757
|
+
for xml in ${XML_DIR}/v*_comparison.xml; do
|
|
758
|
+
# Extract version from filename (e.g., v2_comparison.xml -> 2)
|
|
759
|
+
version=$(basename "$xml" | sed 's/v\([0-9]*\)_comparison.xml/\1/')
|
|
760
|
+
|
|
761
|
+
echo "Importing version $version from $xml..."
|
|
762
|
+
expressir changes import-eengine \
|
|
763
|
+
"$xml" \
|
|
764
|
+
"$SCHEMA_NAME" \
|
|
765
|
+
"$version" \
|
|
766
|
+
-o "$OUTPUT_FILE" \
|
|
767
|
+
--verbose || exit 1
|
|
768
|
+
done
|
|
769
|
+
|
|
770
|
+
# Validate result
|
|
771
|
+
echo "Validating result..."
|
|
772
|
+
expressir changes validate "$OUTPUT_FILE" --verbose || exit 1
|
|
773
|
+
|
|
774
|
+
# Normalize for consistency
|
|
775
|
+
echo "Normalizing..."
|
|
776
|
+
expressir changes validate "$OUTPUT_FILE" --normalize --in-place
|
|
777
|
+
|
|
778
|
+
echo "Import complete: $OUTPUT_FILE"
|
|
779
|
+
----
|
|
780
|
+
|
|
781
|
+
== Best practices
|
|
782
|
+
|
|
783
|
+
=== Keep Express Engine XMLs
|
|
784
|
+
|
|
785
|
+
Archive Express Engine comparison XMLs for reference:
|
|
786
|
+
|
|
787
|
+
[source]
|
|
788
|
+
----
|
|
789
|
+
project/
|
|
790
|
+
├── schemas/
|
|
791
|
+
│ └── action_schema.exp
|
|
792
|
+
├── changes/
|
|
793
|
+
│ └── action_schema.changes.yaml
|
|
794
|
+
└── eengine_reports/
|
|
795
|
+
├── v2_comparison.xml
|
|
796
|
+
├── v3_comparison.xml
|
|
797
|
+
└── v4_comparison.xml
|
|
798
|
+
----
|
|
799
|
+
|
|
800
|
+
=== Import in order
|
|
801
|
+
|
|
802
|
+
Import versions chronologically:
|
|
803
|
+
|
|
804
|
+
[source,bash]
|
|
805
|
+
----
|
|
806
|
+
# Good: chronological order
|
|
807
|
+
expressir changes import-eengine v2.xml schema "2" -o changes.yaml
|
|
808
|
+
expressir changes import-eengine v3.xml schema "3" -o changes.yaml
|
|
809
|
+
expressir changes import-eengine v4.xml schema "4" -o changes.yaml
|
|
810
|
+
|
|
811
|
+
# Avoid: out of order (though technically works)
|
|
812
|
+
expressir changes import-eengine v4.xml schema "4" -o changes.yaml
|
|
813
|
+
expressir changes import-eengine v2.xml schema "2" -o changes.yaml
|
|
814
|
+
----
|
|
815
|
+
|
|
816
|
+
=== Validate after import
|
|
817
|
+
|
|
818
|
+
Always validate imported files:
|
|
819
|
+
|
|
820
|
+
[source,bash]
|
|
821
|
+
----
|
|
822
|
+
expressir changes import-eengine comparison.xml schema "2" -o changes.yaml
|
|
823
|
+
expressir changes validate changes.yaml --verbose
|
|
824
|
+
----
|
|
825
|
+
|
|
826
|
+
=== Review before committing
|
|
827
|
+
|
|
828
|
+
Review imported changes before committing:
|
|
829
|
+
|
|
830
|
+
[source,bash]
|
|
831
|
+
----
|
|
832
|
+
# Import
|
|
833
|
+
expressir changes import-eengine comparison.xml schema "2" -o changes.yaml
|
|
834
|
+
|
|
835
|
+
# Review
|
|
836
|
+
cat changes.yaml
|
|
837
|
+
|
|
838
|
+
# Verify specific changes
|
|
839
|
+
grep -A 5 "additions:" changes.yaml
|
|
840
|
+
|
|
841
|
+
# Commit if satisfied
|
|
842
|
+
git add changes.yaml
|
|
843
|
+
git commit -m "Import version 2 from Express Engine"
|
|
844
|
+
----
|
|
845
|
+
|
|
846
|
+
=== Enhance descriptions
|
|
847
|
+
|
|
848
|
+
Express Engine descriptions may be minimal. Consider enhancing them:
|
|
849
|
+
|
|
850
|
+
[source,yaml]
|
|
851
|
+
----
|
|
852
|
+
# After import - minimal Express Engine description
|
|
853
|
+
- type: ENTITY
|
|
854
|
+
name: action
|
|
855
|
+
description:
|
|
856
|
+
- Modified
|
|
857
|
+
|
|
858
|
+
# Enhance with details
|
|
859
|
+
- type: ENTITY
|
|
860
|
+
name: action
|
|
861
|
+
description:
|
|
862
|
+
- Added new attribute 'priority'
|
|
863
|
+
- Modified WHERE rule WR1 to allow null status
|
|
864
|
+
- Updated subtype relationship to action_base
|
|
865
|
+
----
|
|
866
|
+
|
|
867
|
+
== Next steps
|
|
868
|
+
|
|
869
|
+
After importing from Express Engine:
|
|
870
|
+
|
|
871
|
+
* link:validating-changes.html[Validate Changes] - Validate imported files
|
|
872
|
+
* link:changes-format.html[Changes Format] - Understand the YAML structure
|
|
873
|
+
* link:programmatic-usage.html[Programmatic Usage] - Work with changes via API
|
|
874
|
+
|
|
875
|
+
== Summary
|
|
876
|
+
|
|
877
|
+
Importing from Express Engine automates change tracking:
|
|
878
|
+
|
|
879
|
+
* Three XML modes automatically detected (Schema, ARM, MIM)
|
|
880
|
+
* Simple CLI command for import
|
|
881
|
+
* Incremental version building support
|
|
882
|
+
* Automatic interface change handling via `interfaced_items`
|
|
883
|
+
* HTML description conversion to YAML arrays
|
|
884
|
+
* Both CLI and API import methods
|
|
885
|
+
* Smart versioning (replace same, append new)
|
|
886
|
+
* Compatible with Express Engine v5.2.7 format
|
|
887
|
+
|
|
888
|
+
Key takeaways:
|
|
889
|
+
|
|
890
|
+
* Express Engine comparison XMLs convert to Changes YAML
|
|
891
|
+
* Mode detection is automatic
|
|
892
|
+
* Build change history incrementally across versions
|
|
893
|
+
* Interface changes preserve `interfaced_items` information
|
|
894
|
+
* Always validate after import
|
|
895
|
+
* Keep Express Engine XMLs for reference
|
|
896
|
+
* Import in chronological order
|
|
897
|
+
* Review and enhance descriptions as needed
|
|
898
|
+
* Automate import in CI/CD workflows
|