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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +98 -0
  3. data/.github/workflows/links.yml +100 -0
  4. data/.github/workflows/rake.yml +4 -0
  5. data/.github/workflows/release.yml +5 -0
  6. data/.github/workflows/validate_schemas.yml +1 -1
  7. data/.gitignore +3 -0
  8. data/.rubocop.yml +1 -1
  9. data/.rubocop_todo.yml +244 -39
  10. data/Gemfile +2 -1
  11. data/README.adoc +621 -54
  12. data/docs/Gemfile +12 -0
  13. data/docs/_config.yml +141 -0
  14. data/docs/_guides/changes/changes-format.adoc +778 -0
  15. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  16. data/docs/_guides/changes/index.adoc +396 -0
  17. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  18. data/docs/_guides/changes/validating-changes.adoc +681 -0
  19. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  20. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  21. data/docs/_guides/cli/format-schemas.adoc +547 -0
  22. data/docs/_guides/cli/index.adoc +8 -0
  23. data/docs/_guides/cli/managing-changes.adoc +927 -0
  24. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  25. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  26. data/docs/_guides/index.adoc +165 -0
  27. data/docs/_guides/ler/creating-packages.adoc +664 -0
  28. data/docs/_guides/ler/index.adoc +305 -0
  29. data/docs/_guides/ler/loading-packages.adoc +707 -0
  30. data/docs/_guides/ler/package-formats.adoc +748 -0
  31. data/docs/_guides/ler/querying-packages.adoc +826 -0
  32. data/docs/_guides/ler/validating-packages.adoc +750 -0
  33. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  34. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  35. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  36. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  37. data/docs/_guides/liquid/index.adoc +468 -0
  38. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  39. data/docs/_guides/manifests/index.adoc +307 -0
  40. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  41. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  42. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  43. data/docs/_guides/ruby-api/index.adoc +257 -0
  44. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  45. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  46. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  47. data/docs/_pages/data-model.adoc +665 -0
  48. data/docs/_pages/express-language.adoc +506 -0
  49. data/docs/_pages/getting-started.adoc +414 -0
  50. data/docs/_pages/index.adoc +116 -0
  51. data/docs/_pages/introduction.adoc +256 -0
  52. data/docs/_pages/ler-packages.adoc +837 -0
  53. data/docs/_pages/parsers.adoc +683 -0
  54. data/docs/_pages/schema-manifests.adoc +431 -0
  55. data/docs/_references/index.adoc +228 -0
  56. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  57. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  58. data/docs/_tutorials/index.adoc +221 -0
  59. data/docs/_tutorials/liquid-templates.adoc +806 -0
  60. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  61. data/docs/_tutorials/querying-schemas.adoc +751 -0
  62. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  63. data/docs/index.adoc +242 -0
  64. data/docs/lychee.toml +84 -0
  65. data/examples/demo_ler_usage.sh +86 -0
  66. data/examples/ler/README.md +111 -0
  67. data/examples/ler/simple_example.ler +0 -0
  68. data/examples/ler/simple_schema.exp +33 -0
  69. data/examples/ler_build.rb +75 -0
  70. data/examples/ler_cli.rb +79 -0
  71. data/examples/ler_demo_complete.rb +276 -0
  72. data/examples/ler_query.rb +91 -0
  73. data/examples/ler_query_examples.rb +305 -0
  74. data/examples/ler_stats.rb +81 -0
  75. data/examples/phase3_demo.rb +159 -0
  76. data/examples/query_demo_simple.rb +131 -0
  77. data/expressir.gemspec +2 -0
  78. data/lib/expressir/cli.rb +12 -4
  79. data/lib/expressir/commands/manifest.rb +427 -0
  80. data/lib/expressir/commands/package.rb +1274 -0
  81. data/lib/expressir/commands/validate.rb +70 -37
  82. data/lib/expressir/commands/validate_ascii.rb +607 -0
  83. data/lib/expressir/commands/validate_load.rb +88 -0
  84. data/lib/expressir/express/formatter.rb +5 -1
  85. data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
  86. data/lib/expressir/express/parser.rb +33 -0
  87. data/lib/expressir/manifest/resolver.rb +213 -0
  88. data/lib/expressir/manifest/validator.rb +195 -0
  89. data/lib/expressir/model/declarations/entity.rb +6 -0
  90. data/lib/expressir/model/dependency_resolver.rb +270 -0
  91. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  92. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  93. data/lib/expressir/model/indexes/type_index.rb +149 -0
  94. data/lib/expressir/model/interface_validator.rb +384 -0
  95. data/lib/expressir/model/repository.rb +400 -5
  96. data/lib/expressir/model/repository_validator.rb +295 -0
  97. data/lib/expressir/model/search_engine.rb +525 -0
  98. data/lib/expressir/model.rb +4 -94
  99. data/lib/expressir/package/builder.rb +200 -0
  100. data/lib/expressir/package/metadata.rb +81 -0
  101. data/lib/expressir/package/reader.rb +165 -0
  102. data/lib/expressir/schema_manifest.rb +11 -1
  103. data/lib/expressir/version.rb +1 -1
  104. data/lib/expressir.rb +15 -2
  105. metadata +114 -4
  106. data/docs/benchmarking.adoc +0 -107
  107. data/docs/liquid_drops.adoc +0 -1547
@@ -0,0 +1,927 @@
1
+ ---
2
+ title: Managing Changes
3
+ parent: CLI Guides
4
+ grand_parent: Guides
5
+ nav_order: 6
6
+ ---
7
+
8
+ == Managing Changes
9
+
10
+ === Purpose
11
+
12
+ The [`changes`](../../../lib/expressir/commands/changes.rb:1) subcommands manage EXPRESS Changes files that track schema modifications across versions. These commands help validate change files and import changes from Express Engine comparison reports.
13
+
14
+ === References
15
+
16
+ * link:../../pages/express-language.html[EXPRESS Language Documentation]
17
+ * link:../../tutorials/creating-ler-package.html[Tutorial: Creating LER Package]
18
+ * link:validate-schemas.html[Validate Schemas]
19
+
20
+ === Concepts
21
+
22
+ EXPRESS Changes:: YAML format for tracking schema modifications across versions (ELF 5005)
23
+ Schema version:: A specific iteration of a schema with tracked changes
24
+ Change types:: Additions, modifications, deletions, and mapping changes
25
+ Express Engine (eengine):: Legacy tool that produces XML comparison reports
26
+ Round-trip serialization:: Loading and saving to normalize file formatting
27
+ Version management:: Adding or updating versions in a changes file
28
+
29
+ === Available Commands
30
+
31
+ ==== Validate Changes File
32
+
33
+ [source,bash]
34
+ ----
35
+ expressir changes validate schema.changes.yaml
36
+ ----
37
+
38
+ ==== Import from Express Engine XML
39
+
40
+ [source,bash]
41
+ ----
42
+ expressir changes import-eengine comparison.xml schema_name "2"
43
+ ----
44
+
45
+ === Validate Command
46
+
47
+ ==== Purpose
48
+
49
+ The `changes validate` command validates EXPRESS Changes YAML files and optionally normalizes them through round-trip serialization.
50
+
51
+ ==== Basic Usage
52
+
53
+ [source,bash]
54
+ ----
55
+ # Validate a changes file
56
+ expressir changes validate schema.changes.yaml
57
+
58
+ # With verbose output
59
+ expressir changes validate schema.changes.yaml --verbose
60
+ ----
61
+
62
+ Output on success:
63
+ [source]
64
+ ----
65
+ ✓ File is valid
66
+ Schema: action_schema
67
+ Versions: 3
68
+ ----
69
+
70
+ ==== Command Options
71
+
72
+ [options="header"]
73
+ |===
74
+ | Option | Description | Default
75
+
76
+ | `--normalize`
77
+ | Normalize file through round-trip serialization
78
+ | false
79
+
80
+ | `--in-place`
81
+ | Update file in place (requires `--normalize`)
82
+ | false
83
+
84
+ | `--output PATH`
85
+ | Output file path for normalized output
86
+ | stdout
87
+
88
+ | `--verbose`
89
+ | Show verbose output with validation details
90
+ | false
91
+
92
+ | `--help`, `-h`
93
+ | Display help message
94
+ | -
95
+ |===
96
+
97
+ ==== Validation Checks
98
+
99
+ The validate command performs:
100
+
101
+ 1. **YAML syntax validation**: Ensures valid YAML structure
102
+ 2. **Schema structure validation**: Verifies SchemaChange model structure
103
+ 3. **Required fields check**: Ensures all mandatory fields are present
104
+ 4. **Change item validation**: Validates change types and attributes
105
+
106
+ ==== Normalize Option
107
+
108
+ Normalize files for consistent formatting:
109
+
110
+ [source,bash]
111
+ ----
112
+ # Output to stdout
113
+ expressir changes validate schema.changes.yaml --normalize
114
+
115
+ # Save to new file
116
+ expressir changes validate schema.changes.yaml --normalize --output normalized.yaml
117
+
118
+ # Update in place
119
+ expressir changes validate schema.changes.yaml --normalize --in-place
120
+ ----
121
+
122
+ **Benefits of normalization:**
123
+
124
+ * Consistent YAML formatting
125
+ * Standardized field ordering
126
+ * Removal of formatting inconsistencies
127
+ * Easier version control diffs
128
+
129
+ ==== Validation Examples
130
+
131
+ **Valid changes file:**
132
+
133
+ [source,bash]
134
+ ----
135
+ $ expressir changes validate action_schema.changes.yaml --verbose
136
+ Validating action_schema.changes.yaml...
137
+ ✓ File is valid
138
+ Schema: action_schema
139
+ Versions: 2
140
+ ----
141
+
142
+ **Invalid YAML syntax:**
143
+
144
+ [source,bash]
145
+ ----
146
+ $ expressir changes validate invalid.yaml
147
+ Invalid YAML syntax: mapping values are not allowed in this context
148
+ ----
149
+
150
+ **Missing required fields:**
151
+
152
+ [source,bash]
153
+ ----
154
+ $ expressir changes validate incomplete.yaml
155
+ Validation failed: Schema name is required
156
+ ----
157
+
158
+ === Import-Eengine Command
159
+
160
+ ==== Purpose
161
+
162
+ The `changes import-eengine` command converts Express Engine comparison XML files to EXPRESS Changes YAML format. This enables migration from legacy Express Engine workflows to modern Expressir-based change tracking.
163
+
164
+ ==== Basic Usage
165
+
166
+ [source,bash]
167
+ ----
168
+ # Import and output to stdout
169
+ expressir changes import-eengine comparison.xml schema_name "2"
170
+
171
+ # Import and save to file
172
+ expressir changes import-eengine comparison.xml schema_name "2" -o output.yaml
173
+
174
+ # With verbose output
175
+ expressir changes import-eengine comparison.xml schema_name "2" -o output.yaml --verbose
176
+ ----
177
+
178
+ ==== Command Syntax
179
+
180
+ [source,bash]
181
+ ----
182
+ expressir changes import-eengine INPUT_XML SCHEMA_NAME VERSION [options]
183
+ ----
184
+
185
+ Where:
186
+
187
+ `INPUT_XML`:: Path to the Express Engine comparison XML file
188
+ `SCHEMA_NAME`:: Name of the schema being tracked (e.g., `action_schema`)
189
+ `VERSION`:: Version number for this set of changes (e.g., `"2"`, `"3"`)
190
+
191
+ ==== Command Options
192
+
193
+ [options="header"]
194
+ |===
195
+ | Option | Description | Default
196
+
197
+ | `-o, --output PATH`
198
+ | Output YAML file path
199
+ | stdout
200
+
201
+ | `--verbose`
202
+ | Show verbose output including parsed items
203
+ | false
204
+
205
+ | `--help`, `-h`
206
+ | Display help message
207
+ | -
208
+ |===
209
+
210
+ ==== Express Engine XML Formats
211
+
212
+ Expressir supports all three Express Engine comparison modes:
213
+
214
+ **Schema Mode**::
215
+ `<schema.changes>` with `<schema.additions>`, `<schema.modifications>`, `<schema.deletions>`
216
+
217
+ **ARM Mode**::
218
+ `<arm.changes>` with `<arm.additions>`, `<arm.modifications>`, `<arm.deletions>`
219
+
220
+ **MIM Mode**::
221
+ `<mim.changes>` with `<mim.additions>`, `<mim.modifications>`, `<mim.deletions>`
222
+
223
+ The import command automatically detects the XML mode.
224
+
225
+ ==== Supported Change Types
226
+
227
+ The import process recognizes all EXPRESS construct types:
228
+
229
+ * `ENTITY` - Entity definitions
230
+ * `TYPE` - Type definitions
231
+ * `FUNCTION` - Function definitions
232
+ * `PROCEDURE` - Procedure definitions
233
+ * `RULE` - Rule definitions
234
+ * `CONSTANT` - Constant definitions
235
+ * `USE_FROM` - Interface imports
236
+ * `REFERENCE_FROM` - Interface references
237
+
238
+ ==== Interface Changes
239
+
240
+ Express Engine tracks interface changes with `interfaced.items`:
241
+
242
+ [source,xml]
243
+ ----
244
+ <schema.changes schema_name="aic_csg">
245
+ <schema.additions>
246
+ <modified.object type="USE_FROM" name="geometric_model_schema"
247
+ interfaced.items="convex_hexahedron" />
248
+ <modified.object type="REFERENCE_FROM" name="measure_schema"
249
+ interfaced.items="length_measure" />
250
+ </schema.additions>
251
+ </schema.changes>
252
+ ----
253
+
254
+ Converts to:
255
+
256
+ [source,yaml]
257
+ ----
258
+ schema: aic_csg
259
+ versions:
260
+ - version: 2
261
+ additions:
262
+ - type: USE_FROM
263
+ name: geometric_model_schema
264
+ interfaced_items: convex_hexahedron
265
+ - type: REFERENCE_FROM
266
+ name: measure_schema
267
+ interfaced_items: length_measure
268
+ ----
269
+
270
+ ==== Version Management
271
+
272
+ **Appending New Versions**::
273
+ When the output file exists, the import command intelligently manages versions:
274
+ +
275
+ * **Same version**: Replaces the existing version
276
+ * **New version**: Appends to the versions list
277
+
278
+ [source,bash]
279
+ ----
280
+ # Version 2 - creates file
281
+ expressir changes import-eengine v2_comparison.xml action_schema "2" -o changes.yaml
282
+
283
+ # Version 3 - appends to file
284
+ expressir changes import-eengine v3_comparison.xml action_schema "3" -o changes.yaml
285
+
286
+ # Version 2 again - replaces version 2
287
+ expressir changes import-eengine v2_updated.xml action_schema "2" -o changes.yaml
288
+ ----
289
+
290
+ === Use Cases
291
+
292
+ ==== Validate Before Committing
293
+
294
+ [source,bash]
295
+ ----
296
+ #!/bin/bash
297
+ # .git/hooks/pre-commit
298
+
299
+ # Get staged changes files
300
+ STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.changes\.yaml$')
301
+
302
+ if [ -z "$STAGED" ]; then
303
+ exit 0
304
+ fi
305
+
306
+ echo "Validating changes files..."
307
+
308
+ for file in $STAGED; do
309
+ if ! expressir changes validate "$file" --verbose; then
310
+ echo "❌ Validation failed for: $file"
311
+ exit 1
312
+ fi
313
+ done
314
+
315
+ echo "✓ All changes files are valid"
316
+ ----
317
+
318
+ ==== Normalize Changes Files
319
+
320
+ Standardize formatting across a project:
321
+
322
+ [source,bash]
323
+ ----
324
+ #!/bin/bash
325
+ # normalize-all-changes.sh
326
+
327
+ echo "Normalizing all changes files..."
328
+
329
+ find schemas -name "*.changes.yaml" | while read file; do
330
+ echo "Normalizing: $file"
331
+ expressir changes validate "$file" --normalize --in-place
332
+ done
333
+
334
+ echo "✓ All changes files normalized"
335
+ ----
336
+
337
+ ==== Import Multiple Versions
338
+
339
+ Build up a complete change history:
340
+
341
+ [source,bash]
342
+ ----
343
+ #!/bin/bash
344
+ # import-all-versions.sh
345
+
346
+ SCHEMA="action_schema"
347
+ OUTPUT="action_schema.changes.yaml"
348
+
349
+ # Import each version incrementally
350
+ for version in 2 3 4 5; do
351
+ XML="eengine_comparisons/v${version}_comparison.xml"
352
+
353
+ if [ -f "$XML" ]; then
354
+ echo "Importing version $version..."
355
+ expressir changes import-eengine "$XML" "$SCHEMA" "$version" \
356
+ -o "$OUTPUT" --verbose
357
+ else
358
+ echo "⚠️ Missing: $XML"
359
+ fi
360
+ done
361
+
362
+ echo "✓ Import complete"
363
+ ----
364
+
365
+ ==== Validation Workflow
366
+
367
+ [source,bash]
368
+ ----
369
+ #!/bin/bash
370
+ # validate-and-normalize.sh
371
+
372
+ FILE="$1"
373
+
374
+ if [ -z "$FILE" ]; then
375
+ echo "Usage: $0 <changes-file>"
376
+ exit 1
377
+ fi
378
+
379
+ echo "Step 1: Validating..."
380
+ if ! expressir changes validate "$FILE" --verbose; then
381
+ echo "❌ Validation failed"
382
+ exit 1
383
+ fi
384
+
385
+ echo ""
386
+ echo "Step 2: Normalizing..."
387
+ expressir changes validate "$FILE" --normalize --in-place
388
+
389
+ echo ""
390
+ echo "Step 3: Re-validating..."
391
+ expressir changes validate "$FILE" --verbose
392
+
393
+ echo ""
394
+ echo "✓ File is valid and normalized"
395
+ ----
396
+
397
+ ==== CI/CD Integration
398
+
399
+ GitHub Actions workflow:
400
+
401
+ [source,yaml]
402
+ ----
403
+ name: Validate Changes Files
404
+
405
+ on: [push, pull_request]
406
+
407
+ jobs:
408
+ validate:
409
+ runs-on: ubuntu-latest
410
+ steps:
411
+ - uses: actions/checkout@v2
412
+
413
+ - name: Install Expressir
414
+ run: gem install expressir
415
+
416
+ - name: Validate Changes Files
417
+ run: |
418
+ FAILED=0
419
+
420
+ for file in schemas/**/*.changes.yaml; do
421
+ echo "Validating: $file"
422
+ if ! expressir changes validate "$file" --verbose; then
423
+ echo "❌ Validation failed for $file"
424
+ FAILED=1
425
+ fi
426
+ done
427
+
428
+ if [ $FAILED -eq 1 ]; then
429
+ exit 1
430
+ fi
431
+
432
+ echo "✓ All changes files valid"
433
+ ----
434
+
435
+ ==== Migration from Express Engine
436
+
437
+ Complete migration workflow:
438
+
439
+ [source,bash]
440
+ ----
441
+ #!/bin/bash
442
+ # migrate-from-eengine.sh
443
+
444
+ EENGINE_DIR="eengine_comparisons"
445
+ OUTPUT_DIR="changes"
446
+
447
+ mkdir -p "$OUTPUT_DIR"
448
+
449
+ # Process each schema's comparison files
450
+ for xml in "$EENGINE_DIR"/*.xml; do
451
+ basename=$(basename "$xml" .xml)
452
+
453
+ # Extract schema name and version from filename
454
+ # Expected format: schema_name_v2_comparison.xml
455
+ if [[ $basename =~ ^(.+)_v([0-9]+)_comparison$ ]]; then
456
+ schema="${BASH_REMATCH[1]}"
457
+ version="${BASH_REMATCH[2]}"
458
+ output="$OUTPUT_DIR/${schema}.changes.yaml"
459
+
460
+ echo "Processing: $schema version $version"
461
+ expressir changes import-eengine "$xml" "$schema" "$version" \
462
+ -o "$output" --verbose
463
+
464
+ else
465
+ echo "⚠️ Skipping: $basename (unexpected format)"
466
+ fi
467
+ done
468
+
469
+ echo ""
470
+ echo "Migration complete. Output in: $OUTPUT_DIR"
471
+ ----
472
+
473
+ ==== Quality Assurance Script
474
+
475
+ [source,bash]
476
+ ----
477
+ #!/bin/bash
478
+ # qa-changes-files.sh
479
+
480
+ echo "Changes Files Quality Assurance"
481
+ echo "==============================="
482
+ echo ""
483
+
484
+ TOTAL=0
485
+ VALID=0
486
+ INVALID=0
487
+
488
+ for file in schemas/**/*.changes.yaml; do
489
+ ((TOTAL++))
490
+ echo "Checking: $file"
491
+
492
+ if expressir changes validate "$file" 2>/dev/null; then
493
+ echo " ✓ Valid"
494
+ ((VALID++))
495
+ else
496
+ echo " ✗ Invalid"
497
+ ((INVALID++))
498
+ fi
499
+ done
500
+
501
+ echo ""
502
+ echo "Summary:"
503
+ echo " Total files: $TOTAL"
504
+ echo " Valid: $VALID"
505
+ echo " Invalid: $INVALID"
506
+
507
+ if [ $INVALID -gt 0 ]; then
508
+ exit 1
509
+ fi
510
+ ----
511
+
512
+ === Changes File Format
513
+
514
+ ==== Structure
515
+
516
+ [source,yaml]
517
+ ----
518
+ schema: action_schema
519
+ versions:
520
+ - version: 2
521
+ description: |-
522
+ Changes in version 2
523
+ additions:
524
+ - type: ENTITY
525
+ name: new_entity
526
+ modifications:
527
+ - type: FUNCTION
528
+ name: modified_function
529
+ deletions:
530
+ - type: TYPE
531
+ name: removed_type
532
+ - version: 3
533
+ description: Additional changes
534
+ additions:
535
+ - type: CONSTANT
536
+ name: new_constant
537
+ ----
538
+
539
+ ==== Version Fields
540
+
541
+ `version`:: (Required) Version identifier (string or number)
542
+ `description`:: (Optional) Description of changes in this version
543
+ `additions`:: (Optional) List of items added
544
+ `modifications`:: (Optional) List of items modified
545
+ `deletions`:: (Optional) List of items deleted
546
+ `mappings`:: (Optional) Mapping changes (for ARM/MIM)
547
+
548
+ ==== Item Fields
549
+
550
+ `type`:: (Required) EXPRESS construct type (ENTITY, TYPE, FUNCTION, etc.)
551
+ `name`:: (Required) Name of the construct
552
+ `description`:: (Optional) Additional details about the change
553
+ `interfaced_items`:: (Optional) For REFERENCE_FROM items
554
+
555
+ === Workflows
556
+
557
+ ==== Development Workflow
558
+
559
+ [source,bash]
560
+ ----
561
+ # 1. Make schema changes
562
+ vim action_schema.exp
563
+
564
+ # 2. Update changes file manually
565
+ vim action_schema.changes.yaml
566
+
567
+ # 3. Validate
568
+ expressir changes validate action_schema.changes.yaml --verbose
569
+
570
+ # 4. Normalize and commit
571
+ expressir changes validate action_schema.changes.yaml --normalize --in-place
572
+ git add action_schema.exp action_schema.changes.yaml
573
+ git commit -m "Update action_schema to version 3"
574
+ ----
575
+
576
+ ==== Express Engine Migration Workflow
577
+
578
+ [source,bash]
579
+ ----
580
+ # 1. Run Express Engine comparison
581
+ # (produces comparison.xml)
582
+
583
+ # 2. Import to changes file
584
+ expressir changes import-eengine comparison.xml action_schema "2" \
585
+ -o action_schema.changes.yaml --verbose
586
+
587
+ # 3. Validate result
588
+ expressir changes validate action_schema.changes.yaml --verbose
589
+
590
+ # 4. Review and adjust if needed
591
+ vim action_schema.changes.yaml
592
+
593
+ # 5. Re-validate and commit
594
+ expressir changes validate action_schema.changes.yaml --verbose
595
+ git add action_schema.changes.yaml
596
+ git commit -m "Import version 2 changes from Express Engine"
597
+ ----
598
+
599
+ ==== Multi-Schema Workflow
600
+
601
+ [source,bash]
602
+ ----
603
+ #!/bin/bash
604
+ # Process multiple schemas
605
+
606
+ SCHEMAS=("action_schema" "approval_schema" "date_time_schema")
607
+ VERSION="2"
608
+
609
+ for schema in "${SCHEMAS[@]}"; do
610
+ echo "Processing: $schema"
611
+
612
+ # Import from Express Engine
613
+ expressir changes import-eengine \
614
+ "eengine/${schema}_v${VERSION}.xml" \
615
+ "$schema" \
616
+ "$VERSION" \
617
+ -o "changes/${schema}.changes.yaml"
618
+
619
+ # Validate
620
+ expressir changes validate "changes/${schema}.changes.yaml" --verbose
621
+
622
+ echo ""
623
+ done
624
+ ----
625
+
626
+ === Best Practices
627
+
628
+ **Validate Regularly**::
629
+ Check changes files in CI/CD pipelines
630
+ +
631
+ [source,bash]
632
+ ----
633
+ # In CI script
634
+ expressir changes validate *.changes.yaml || exit 1
635
+ ----
636
+
637
+ **Normalize for Version Control**::
638
+ Use consistent formatting for cleaner diffs
639
+ +
640
+ [source,bash]
641
+ ----
642
+ # Before committing
643
+ expressir changes validate file.yaml --normalize --in-place
644
+ ----
645
+
646
+ **Track All Versions**::
647
+ Maintain complete change history
648
+ +
649
+ [source,yaml]
650
+ ----
651
+ versions:
652
+ - version: 1
653
+ description: Initial version
654
+ - version: 2
655
+ description: Added features
656
+ - version: 3
657
+ description: Bug fixes
658
+ ----
659
+
660
+ **Use Descriptive Messages**::
661
+ Document why changes were made
662
+ +
663
+ [source,yaml]
664
+ ----
665
+ modifications:
666
+ - type: ENTITY
667
+ name: product
668
+ description: Added version_id attribute to track versions
669
+ ----
670
+
671
+ **Version Incrementally**::
672
+ Import versions one at a time
673
+ +
674
+ [source,bash]
675
+ ----
676
+ # Import version 2
677
+ expressir changes import-eengine v2.xml schema "2" -o changes.yaml
678
+
679
+ # Then import version 3
680
+ expressir changes import-eengine v3.xml schema "3" -o changes.yaml
681
+ ----
682
+
683
+ **Keep Interface Changes**::
684
+ Preserve interfaced_items information
685
+ +
686
+ [source,yaml]
687
+ ----
688
+ additions:
689
+ - type: USE_FROM
690
+ name: geometric_model_schema
691
+ interfaced_items: solid_model
692
+ ----
693
+
694
+ === Troubleshooting
695
+
696
+ ==== Invalid YAML Syntax
697
+
698
+ **Problem**: YAML parsing errors
699
+
700
+ **Solution**: Use a YAML validator or normalize
701
+ [source,bash]
702
+ ----
703
+ # Check with normalize (outputs to stdout)
704
+ expressir changes validate file.yaml --normalize
705
+
706
+ # Fix and save
707
+ expressir changes validate file.yaml --normalize --in-place
708
+ ----
709
+
710
+ ==== Version Conflicts
711
+
712
+ **Problem**: Accidentally overwriting versions
713
+
714
+ **Prevention**: Always specify unique version numbers
715
+ [source,bash]
716
+ ----
717
+ # Check existing versions first
718
+ grep "^- version:" file.yaml
719
+
720
+ # Then import with new version
721
+ expressir changes import-eengine comparison.xml schema "4" -o file.yaml
722
+ ----
723
+
724
+ ==== Express Engine XML Not Found
725
+
726
+ **Problem**: Import command cannot find XML file
727
+
728
+ **Solution**: Check file path and permissions
729
+ [source,bash]
730
+ ----
731
+ # Verify file exists
732
+ ls -la comparison.xml
733
+
734
+ # Use absolute path if needed
735
+ expressir changes import-eengine /full/path/to/comparison.xml schema "2"
736
+ ----
737
+
738
+ ==== Empty Changes Files
739
+
740
+ **Problem**: Import produces no changes
741
+
742
+ **Causes**:
743
+ * Empty Express Engine comparison
744
+ * Incorrect XML format
745
+ * Wrong schema name
746
+
747
+ **Debugging**:
748
+ [source,bash]
749
+ ----
750
+ # Import with verbose output
751
+ expressir changes import-eengine comparison.xml schema "2" \
752
+ -o output.yaml --verbose
753
+
754
+ # Check XML content
755
+ xmllint --format comparison.xml | head -50
756
+ ----
757
+
758
+ ==== Character Encoding Issues
759
+
760
+ **Problem**: Special characters not handled correctly
761
+
762
+ **Solution**: Ensure UTF-8 encoding
763
+ [source,bash]
764
+ ----
765
+ # Check file encoding
766
+ file -I comparison.xml
767
+
768
+ # Convert if needed
769
+ iconv -f ISO-8859-1 -t UTF-8 comparison.xml > comparison_utf8.xml
770
+ ----
771
+
772
+ === Integration Examples
773
+
774
+ ==== Makefile Integration
775
+
776
+ [source,makefile]
777
+ ----
778
+ .PHONY: validate-changes normalize-changes import-changes
779
+
780
+ validate-changes:
781
+ @echo "Validating changes files..."
782
+ @find schemas -name "*.changes.yaml" -exec \
783
+ expressir changes validate {} \;
784
+
785
+ normalize-changes:
786
+ @echo "Normalizing changes files..."
787
+ @find schemas -name "*.changes.yaml" -exec \
788
+ expressir changes validate {} --normalize --in-place \;
789
+
790
+ import-changes:
791
+ @echo "Importing from Express Engine..."
792
+ @./scripts/import-all-changes.sh
793
+ ----
794
+
795
+ ==== Jenkins Pipeline
796
+
797
+ [source,groovy]
798
+ ----
799
+ pipeline {
800
+ agent any
801
+ stages {
802
+ stage('Validate Changes') {
803
+ steps {
804
+ sh 'gem install expressir'
805
+ sh '''
806
+ for file in schemas/**/*.changes.yaml; do
807
+ expressir changes validate "$file" --verbose
808
+ done
809
+ '''
810
+ }
811
+ }
812
+ }
813
+ }
814
+ ----
815
+
816
+ ==== Pre-commit Hook
817
+
818
+ [source,bash]
819
+ ----
820
+ #!/bin/bash
821
+ # .git/hooks/pre-commit
822
+
823
+ # Validate and normalize changes files
824
+ for file in $(git diff --cached --name-only | grep '\.changes\.yaml$'); do
825
+ expressir changes validate "$file" --normalize --in-place
826
+ git add "$file"
827
+ done
828
+ ----
829
+
830
+ === Advanced Usage
831
+
832
+ ==== Batch Processing
833
+
834
+ [source,bash]
835
+ ----
836
+ #!/bin/bash
837
+ # Process all Express Engine outputs
838
+
839
+ for xml in eengine_outputs/*.xml; do
840
+ # Extract schema and version from filename
841
+ basename=$(basename "$xml" .xml)
842
+ schema="${basename%_v*}"
843
+ version="${basename##*_v}"
844
+
845
+ echo "Processing: $schema version $version"
846
+ expressir changes import-eengine "$xml" "$schema" "$version" \
847
+ -o "changes/${schema}.changes.yaml" --verbose
848
+ done
849
+ ----
850
+
851
+ ==== Programmatic Validation
852
+
853
+ [source,ruby]
854
+ ----
855
+ require 'expressir/changes'
856
+
857
+ # Validate programmatically
858
+ begin
859
+ schema_change = Expressir::Changes::SchemaChange.from_file('schema.changes.yaml')
860
+ puts "✓ Valid: #{schema_change.schema}"
861
+ puts " Versions: #{schema_change.versions.size}"
862
+ rescue StandardError => e
863
+ puts "✗ Invalid: #{e.message}"
864
+ exit 1
865
+ end
866
+ ----
867
+
868
+ ==== Custom Workflows
869
+
870
+ [source,bash]
871
+ ----
872
+ #!/bin/bash
873
+ # Custom validation with additional checks
874
+
875
+ FILE="$1"
876
+
877
+ # Standard validation
878
+ expressir changes validate "$FILE" --verbose || exit 1
879
+
880
+ # Additional checks
881
+ echo "Additional checks..."
882
+
883
+ # Check version ordering
884
+ VERSIONS=$(grep "^- version:" "$FILE" | awk '{print $3}')
885
+ SORTED=$(echo "$VERSIONS" | sort -n)
886
+
887
+ if [ "$VERSIONS" != "$SORTED" ]; then
888
+ echo "⚠️ Versions not in ascending order"
889
+ fi
890
+
891
+ # Check for empty sections
892
+ if grep -q "additions: \[\]" "$FILE"; then
893
+ echo "⚠️ Empty additions section found"
894
+ fi
895
+
896
+ echo "✓ All checks complete"
897
+ ----
898
+
899
+ === Next Steps
900
+
901
+ **Related Commands**::
902
+ * link:validate-schemas.html[Validate Schemas] - Schema validation
903
+ * link:format-schemas.html[Format Schemas] - Schema formatting
904
+
905
+ **Advanced Topics**::
906
+ * link:../ruby-api/[Ruby API Guides] - Programmatic change management
907
+ * link:../changes/[Changes Guides] - In-depth changes documentation
908
+
909
+ **Integration**::
910
+ * link:../deployment/ci-cd-setup.html[CI/CD Setup] - Automated workflows
911
+ * Version control integration
912
+ * Change tracking automation
913
+
914
+ === Summary
915
+
916
+ The changes commands:
917
+
918
+ * ✅ Validate EXPRESS Changes YAML files
919
+ * ✅ Normalize files for consistent formatting
920
+ * ✅ Import from Express Engine XML
921
+ * ✅ Support version appending and replacement
922
+ * ✅ Handle interface changes (USE_FROM, REFERENCE_FROM)
923
+ * ✅ Detect all three Express Engine modes
924
+ * ✅ Integrate with CI/CD pipelines
925
+ * ✅ Enable change history tracking
926
+
927
+ Use these commands to maintain accurate schema change records and migrate from legacy Express Engine workflows to modern Expressir-based change tracking.