expressir 2.1.29 → 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 (111) 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 +209 -55
  10. data/Gemfile +2 -1
  11. data/README.adoc +650 -83
  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/changes/schema_change.rb +32 -22
  79. data/lib/expressir/changes/{edition_change.rb → version_change.rb} +3 -3
  80. data/lib/expressir/cli.rb +12 -4
  81. data/lib/expressir/commands/changes_import_eengine.rb +2 -2
  82. data/lib/expressir/commands/changes_validate.rb +1 -1
  83. data/lib/expressir/commands/manifest.rb +427 -0
  84. data/lib/expressir/commands/package.rb +1274 -0
  85. data/lib/expressir/commands/validate.rb +70 -37
  86. data/lib/expressir/commands/validate_ascii.rb +607 -0
  87. data/lib/expressir/commands/validate_load.rb +88 -0
  88. data/lib/expressir/express/formatter.rb +5 -1
  89. data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
  90. data/lib/expressir/express/parser.rb +33 -0
  91. data/lib/expressir/manifest/resolver.rb +213 -0
  92. data/lib/expressir/manifest/validator.rb +195 -0
  93. data/lib/expressir/model/declarations/entity.rb +6 -0
  94. data/lib/expressir/model/dependency_resolver.rb +270 -0
  95. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  96. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  97. data/lib/expressir/model/indexes/type_index.rb +149 -0
  98. data/lib/expressir/model/interface_validator.rb +384 -0
  99. data/lib/expressir/model/repository.rb +400 -5
  100. data/lib/expressir/model/repository_validator.rb +295 -0
  101. data/lib/expressir/model/search_engine.rb +525 -0
  102. data/lib/expressir/model.rb +4 -94
  103. data/lib/expressir/package/builder.rb +200 -0
  104. data/lib/expressir/package/metadata.rb +81 -0
  105. data/lib/expressir/package/reader.rb +165 -0
  106. data/lib/expressir/schema_manifest.rb +11 -1
  107. data/lib/expressir/version.rb +1 -1
  108. data/lib/expressir.rb +16 -3
  109. metadata +115 -5
  110. data/docs/benchmarking.adoc +0 -107
  111. data/docs/liquid_drops.adoc +0 -1547
@@ -0,0 +1,681 @@
1
+ ---
2
+ title: Validating Changes Files
3
+ parent: Changes
4
+ grand_parent: Guides
5
+ nav_order: 2
6
+ ---
7
+
8
+ = Validating Changes Files
9
+
10
+ == Purpose
11
+
12
+ Validation ensures that EXPRESS Changes files are well-formed, complete, and
13
+ follow the correct format. This guide covers validation, normalization, and
14
+ troubleshooting common issues.
15
+
16
+ == References
17
+
18
+ * link:index.html[Changes Overview] - Introduction to Changes files
19
+ * link:changes-format.html[Changes Format] - Complete format specification
20
+ * link:programmatic-usage.html[Programmatic Usage] - Ruby API for validation
21
+
22
+ == Concepts
23
+
24
+ validation:: Checking that a Changes file is syntactically correct and follows
25
+ the required structure
26
+
27
+ normalization:: Converting a Changes file to a standard format through
28
+ round-trip serialization
29
+
30
+ in-place validation:: Updating the original file with normalized content
31
+
32
+ round-trip serialization:: Loading a file and saving it back, which ensures
33
+ consistent formatting
34
+
35
+ == CLI validation
36
+
37
+ === Basic validation
38
+
39
+ Check if a Changes file is valid:
40
+
41
+ [source,bash]
42
+ ----
43
+ expressir changes validate schema.changes.yaml
44
+ ----
45
+
46
+ This performs the following checks:
47
+
48
+ * YAML syntax is valid
49
+ * File structure matches the Changes schema
50
+ * Required fields are present (`schema`, version-level `version`)
51
+ * Item changes have required fields (`type`, `name`)
52
+ * Change types are valid EXPRESS construct types
53
+
54
+ .Successful validation output
55
+ [example]
56
+ ====
57
+ [source,bash]
58
+ ----
59
+ $ expressir changes validate action_schema.changes.yaml
60
+ ✓ File is valid
61
+ ----
62
+ ====
63
+
64
+ === Verbose validation
65
+
66
+ Get detailed information about the file being validated:
67
+
68
+ [source,bash]
69
+ ----
70
+ expressir changes validate schema.changes.yaml --verbose
71
+ ----
72
+
73
+ .Verbose output
74
+ [example]
75
+ ====
76
+ [source,bash]
77
+ ----
78
+ $ expressir changes validate action_schema.changes.yaml --verbose
79
+ Validating action_schema.changes.yaml...
80
+ ✓ File is valid
81
+ Schema: action_schema
82
+ Versions: 3
83
+ ----
84
+ ====
85
+
86
+ === Validation with normalization
87
+
88
+ Normalize a file by loading and re-serializing it:
89
+
90
+ [source,bash]
91
+ ----
92
+ # Output to stdout
93
+ expressir changes validate schema.changes.yaml --normalize
94
+
95
+ # Save to new file
96
+ expressir changes validate schema.changes.yaml --normalize \
97
+ --output normalized.yaml
98
+
99
+ # Update file in place
100
+ expressir changes validate schema.changes.yaml --normalize --in-place
101
+ ----
102
+
103
+ Normalization ensures:
104
+
105
+ * Consistent field ordering
106
+ * Proper YAML formatting
107
+ * Standard indentation (2 spaces)
108
+ * Sorted keys where applicable
109
+ * Schema hint comment added
110
+
111
+ .Normalization example
112
+ [example]
113
+ ====
114
+ [source,bash]
115
+ ----
116
+ # Before
117
+ $ cat messy.changes.yaml
118
+ schema: action_schema
119
+ versions:
120
+ - version: 2
121
+ additions: [{type: ENTITY, name: new_entity}]
122
+
123
+ # Normalize
124
+ $ expressir changes validate messy.changes.yaml --normalize \
125
+ --output clean.changes.yaml
126
+
127
+ # After
128
+ $ cat clean.changes.yaml
129
+ # yaml-language-server: $schema=https://www.expresslang.org/schemas/changes/v1/schema_changes.yaml
130
+ schema: action_schema
131
+ versions:
132
+ - version: 2
133
+ additions:
134
+ - type: ENTITY
135
+ name: new_entity
136
+ ----
137
+ ====
138
+
139
+ == Validation options
140
+
141
+ [options="header"]
142
+ |===
143
+ | Option | Description | Example
144
+
145
+ | `--normalize`
146
+ | Normalize through round-trip serialization
147
+ | `--normalize`
148
+
149
+ | `--in-place`
150
+ | Update file in place (requires `--normalize`)
151
+ | `--normalize --in-place`
152
+
153
+ | `--output PATH`
154
+ | Save normalized output to file
155
+ | `--normalize --output out.yaml`
156
+
157
+ | `--verbose`
158
+ | Show detailed validation information
159
+ | `--verbose`
160
+ |===
161
+
162
+ NOTE: The `--in-place` option requires `--normalize` and cannot be used with
163
+ `--output`.
164
+
165
+ == Validation checks
166
+
167
+ === YAML syntax validation
168
+
169
+ The validator checks for valid YAML syntax:
170
+
171
+ .Invalid YAML example
172
+ [example]
173
+ ====
174
+ [source,yaml]
175
+ ----
176
+ # Invalid: missing closing quote
177
+ schema: action_schema
178
+ versions:
179
+ - version: 2
180
+ description: "This is unclosed
181
+ ----
182
+
183
+ [source,bash]
184
+ ----
185
+ $ expressir changes validate bad.yaml
186
+ Error: Invalid YAML syntax: (<unknown>): found unexpected end of stream
187
+ ----
188
+ ====
189
+
190
+ === Structure validation
191
+
192
+ Validates the file follows the Changes schema structure:
193
+
194
+ .Invalid structure example
195
+ [example]
196
+ ====
197
+ [source,yaml]
198
+ ----
199
+ # Invalid: missing required 'schema' field
200
+ versions:
201
+ - version: 2
202
+ ----
203
+
204
+ [source,bash]
205
+ ----
206
+ $ expressir changes validate bad.yaml
207
+ Error: Validation failed: schema cannot be nil
208
+ ----
209
+ ====
210
+
211
+ === Field presence validation
212
+
213
+ Checks that required fields are present:
214
+
215
+ .Missing required fields
216
+ [example]
217
+ ====
218
+ [source,yaml]
219
+ ----
220
+ schema: action_schema
221
+ versions:
222
+ - version: 2
223
+ additions:
224
+ - type: ENTITY
225
+ # Missing required 'name' field
226
+ ----
227
+
228
+ [source,bash]
229
+ ----
230
+ $ expressir changes validate bad.yaml
231
+ Error: Validation failed: Item change missing required field 'name'
232
+ ----
233
+ ====
234
+
235
+ === Type validation
236
+
237
+ Validates that change types are valid EXPRESS constructs:
238
+
239
+ .Invalid type example
240
+ [example]
241
+ ====
242
+ [source,yaml]
243
+ ----
244
+ schema: action_schema
245
+ versions:
246
+ - version: 2
247
+ additions:
248
+ - type: INVALID_TYPE
249
+ name: something
250
+ ----
251
+
252
+ [source,bash]
253
+ ----
254
+ $ expressir changes validate bad.yaml
255
+ Error: Validation failed: Invalid type 'INVALID_TYPE'
256
+ ----
257
+ ====
258
+
259
+ Valid types are: `ENTITY`, `TYPE`, `FUNCTION`, `PROCEDURE`, `RULE`,
260
+ `CONSTANT`, `SUBTYPE_CONSTRAINT`, `USE_FROM`, `REFERENCE_FROM`
261
+
262
+ == API validation
263
+
264
+ === Basic validation
265
+
266
+ Load and validate a Changes file programmatically:
267
+
268
+ [source,ruby]
269
+ ----
270
+ require "expressir/changes"
271
+
272
+ begin
273
+ # Load file (validates automatically)
274
+ changes = Expressir::Changes::SchemaChange.from_file(
275
+ "schema.changes.yaml"
276
+ )
277
+
278
+ puts "File is valid"
279
+ puts "Schema: #{changes.schema}"
280
+ puts "Versions: #{changes.versions&.size || 0}"
281
+
282
+ rescue Psych::SyntaxError => e
283
+ puts "YAML syntax error: #{e.message}"
284
+ rescue StandardError => e
285
+ puts "Validation error: #{e.message}"
286
+ end
287
+ ----
288
+
289
+ === Validation with normalization
290
+
291
+ Normalize a file programmatically:
292
+
293
+ [source,ruby]
294
+ ----
295
+ require "expressir/changes"
296
+
297
+ # Load file
298
+ changes = Expressir::Changes::SchemaChange.from_file("schema.changes.yaml")
299
+
300
+ # Normalize by saving (adds schema hint, formats consistently)
301
+ changes.to_file("normalized.changes.yaml")
302
+
303
+ puts "File normalized"
304
+ ----
305
+
306
+ === In-place normalization
307
+
308
+ Update a file in place:
309
+
310
+ [source,ruby]
311
+ ----
312
+ require "expressir/changes"
313
+
314
+ path = "schema.changes.yaml"
315
+
316
+ # Load and save to same file
317
+ changes = Expressir::Changes::SchemaChange.from_file(path)
318
+ changes.to_file(path)
319
+
320
+ puts "File normalized in place"
321
+ ----
322
+
323
+ === Batch validation
324
+
325
+ Validate multiple files:
326
+
327
+ [source,ruby]
328
+ ----
329
+ require "expressir/changes"
330
+
331
+ files = Dir.glob("**/*.changes.yaml")
332
+ errors = []
333
+
334
+ files.each do |file|
335
+ begin
336
+ Expressir::Changes::SchemaChange.from_file(file)
337
+ puts "✓ #{file}"
338
+ rescue StandardError => e
339
+ puts "✗ #{file}"
340
+ errors << { file: file, error: e.message }
341
+ end
342
+ end
343
+
344
+ if errors.any?
345
+ puts "\nErrors found:"
346
+ errors.each do |err|
347
+ puts " #{err[:file]}: #{err[:error]}"
348
+ end
349
+ end
350
+ ----
351
+
352
+ == Common errors
353
+
354
+ === File not found
355
+
356
+ **Error**: `File not found: schema.changes.yaml`
357
+
358
+ **Cause**: File path is incorrect
359
+
360
+ **Solution**: Check file path and current directory
361
+
362
+ [source,bash]
363
+ ----
364
+ # Check file exists
365
+ ls schema.changes.yaml
366
+
367
+ # Use absolute path
368
+ expressir changes validate /full/path/to/schema.changes.yaml
369
+ ----
370
+
371
+ === Invalid YAML syntax
372
+
373
+ **Error**: `Invalid YAML syntax: found unexpected end of stream`
374
+
375
+ **Causes**:
376
+ * Unclosed quotes
377
+ * Incorrect indentation
378
+ * Invalid YAML structure
379
+
380
+ **Solution**: Check YAML syntax carefully
381
+
382
+ [source,yaml]
383
+ ----
384
+ # Bad: unclosed quote
385
+ description: "This is broken
386
+
387
+ # Good: closed quote
388
+ description: "This is correct"
389
+
390
+ # Bad: inconsistent indentation
391
+ versions:
392
+ - version: 2
393
+ additions: # Wrong indent
394
+
395
+ # Good: consistent indentation
396
+ versions:
397
+ - version: 2
398
+ additions:
399
+ ----
400
+
401
+ === Missing required fields
402
+
403
+ **Error**: `Validation failed: schema cannot be nil`
404
+
405
+ **Cause**: Missing required `schema` field
406
+
407
+ **Solution**: Add the schema field
408
+
409
+ [source,yaml]
410
+ ----
411
+ # Add schema field
412
+ schema: my_schema_name
413
+ versions:
414
+ - version: 2
415
+ ----
416
+
417
+ **Error**: `Item change missing required field 'name'`
418
+
419
+ **Cause**: Item change missing `name` field
420
+
421
+ **Solution**: Add name to all item changes
422
+
423
+ [source,yaml]
424
+ ----
425
+ additions:
426
+ # Bad: missing name
427
+ - type: ENTITY
428
+
429
+ # Good: includes name
430
+ - type: ENTITY
431
+ name: entity_name
432
+ ----
433
+
434
+ === Invalid change type
435
+
436
+ **Error**: `Invalid type 'INVALID_TYPE'`
437
+
438
+ **Cause**: Using an invalid EXPRESS construct type
439
+
440
+ **Solution**: Use valid types only
441
+
442
+ [source,yaml]
443
+ ----
444
+ # Bad
445
+ - type: INVALID_TYPE
446
+ name: something
447
+
448
+ # Good
449
+ - type: ENTITY
450
+ name: something
451
+ ----
452
+
453
+ Valid types: `ENTITY`, `TYPE`, `FUNCTION`, `PROCEDURE`, `RULE`, `CONSTANT`,
454
+ `SUBTYPE_CONSTRAINT`, `USE_FROM`, `REFERENCE_FROM`
455
+
456
+ === Conflicting options
457
+
458
+ **Error**: `--in-place requires --normalize flag`
459
+
460
+ **Cause**: Using `--in-place` without `--normalize`
461
+
462
+ **Solution**: Include `--normalize`
463
+
464
+ [source,bash]
465
+ ----
466
+ # Bad
467
+ expressir changes validate file.yaml --in-place
468
+
469
+ # Good
470
+ expressir changes validate file.yaml --normalize --in-place
471
+ ----
472
+
473
+ **Error**: `Cannot use both --in-place and --output`
474
+
475
+ **Cause**: Using both `--in-place` and `--output` options
476
+
477
+ **Solution**: Choose one output method
478
+
479
+ [source,bash]
480
+ ----
481
+ # Bad
482
+ expressir changes validate file.yaml --normalize --in-place --output out.yaml
483
+
484
+ # Good: in-place
485
+ expressir changes validate file.yaml --normalize --in-place
486
+
487
+ # Good: to file
488
+ expressir changes validate file.yaml --normalize --output out.yaml
489
+ ----
490
+
491
+ == Best practices
492
+
493
+ === Validate before committing
494
+
495
+ Always validate Changes files before committing to version control:
496
+
497
+ [source,bash]
498
+ ----
499
+ # Pre-commit check
500
+ expressir changes validate *.changes.yaml
501
+
502
+ # Validation passes? Commit
503
+ git add *.changes.yaml
504
+ git commit -m "Update changes files"
505
+ ----
506
+
507
+ === Use normalization for consistency
508
+
509
+ Normalize files to ensure consistent formatting across the team:
510
+
511
+ [source,bash]
512
+ ----
513
+ # Normalize all changes files
514
+ for file in *.changes.yaml; do
515
+ expressir changes validate "$file" --normalize --in-place
516
+ done
517
+ ----
518
+
519
+ === Automate validation in CI/CD
520
+
521
+ Add validation to your CI pipeline:
522
+
523
+ [source,yaml]
524
+ ----
525
+ # .github/workflows/validate.yml
526
+ name: Validate Changes Files
527
+
528
+ on: [push, pull_request]
529
+
530
+ jobs:
531
+ validate:
532
+ runs-on: ubuntu-latest
533
+ steps:
534
+ - uses: actions/checkout@v2
535
+
536
+ - name: Setup Ruby
537
+ uses: ruby/setup-ruby@v1
538
+ with:
539
+ ruby-version: '3.0'
540
+
541
+ - name: Install Expressir
542
+ run: gem install expressir
543
+
544
+ - name: Validate Changes Files
545
+ run: |
546
+ exitcode=0
547
+ for file in **/*.changes.yaml; do
548
+ echo "Validating $file..."
549
+ expressir changes validate "$file" || exitcode=1
550
+ done
551
+ exit $exitcode
552
+ ----
553
+
554
+ === Test with small files first
555
+
556
+ When learning validation, test with simple files:
557
+
558
+ [source,yaml]
559
+ ----
560
+ # Minimal valid file for testing
561
+ schema: test_schema
562
+ versions:
563
+ - version: 1
564
+ additions:
565
+ - type: ENTITY
566
+ name: test_entity
567
+ ----
568
+
569
+ === Keep backups before in-place updates
570
+
571
+ Before using `--in-place`, ensure you have backups:
572
+
573
+ [source,bash]
574
+ ----
575
+ # Create backup
576
+ cp schema.changes.yaml schema.changes.yaml.backup
577
+
578
+ # Normalize in place
579
+ expressir changes validate schema.changes.yaml --normalize --in-place
580
+
581
+ # If something goes wrong, restore
582
+ # cp schema.changes.yaml.backup schema.changes.yaml
583
+ ----
584
+
585
+ === Use version control
586
+
587
+ Always use version control for Changes files:
588
+
589
+ [source,bash]
590
+ ----
591
+ # Review changes before normalizing
592
+ git diff schema.changes.yaml
593
+
594
+ # Normalize
595
+ expressir changes validate schema.changes.yaml --normalize --in-place
596
+
597
+ # Review normalized changes
598
+ git diff schema.changes.yaml
599
+
600
+ # Commit if satisfied
601
+ git add schema.changes.yaml
602
+ git commit -m "Normalize changes file"
603
+ ----
604
+
605
+ == Validation workflow
606
+
607
+ A typical validation workflow:
608
+
609
+ [source]
610
+ ----
611
+ 1. Edit changes file
612
+ 2. Validate syntax and structure
613
+ 3. Fix any errors
614
+ 4. Normalize for consistency
615
+ 5. Review normalized output
616
+ 6. Commit to version control
617
+ ----
618
+
619
+ .Complete workflow example
620
+ [example]
621
+ ====
622
+ [source,bash]
623
+ ----
624
+ # 1. Edit file
625
+ vim schema.changes.yaml
626
+
627
+ # 2. Validate
628
+ expressir changes validate schema.changes.yaml --verbose
629
+
630
+ # 3. Fix any errors (if needed)
631
+ vim schema.changes.yaml
632
+
633
+ # 4. Normalize
634
+ expressir changes validate schema.changes.yaml --normalize \
635
+ --output normalized.yaml
636
+
637
+ # 5. Review
638
+ diff schema.changes.yaml normalized.yaml
639
+
640
+ # 6. Apply normalization
641
+ mv normalized.yaml schema.changes.yaml
642
+
643
+ # 7. Verify
644
+ expressir changes validate schema.changes.yaml --verbose
645
+
646
+ # 8. Commit
647
+ git add schema.changes.yaml
648
+ git commit -m "Update changes file"
649
+ ----
650
+ ====
651
+
652
+ == Next steps
653
+
654
+ After validating your Changes files:
655
+
656
+ * link:importing-eengine.html[Import from Express Engine] - Import XML reports
657
+ * link:programmatic-usage.html[Programmatic Usage] - Work with Changes via API
658
+ * link:changes-format.html[Changes Format] - Review format specification
659
+
660
+ == Summary
661
+
662
+ Validation ensures Changes files are correct and consistently formatted:
663
+
664
+ * CLI validation with `expressir changes validate`
665
+ * Multiple output options: stdout, file, in-place
666
+ * Normalization ensures consistent formatting
667
+ * Comprehensive error messages for troubleshooting
668
+ * Both CLI and API validation available
669
+ * Integration with CI/CD workflows
670
+ * Schema hint automatically added for editor support
671
+
672
+ Key takeaways:
673
+
674
+ * Always validate before committing
675
+ * Use normalization for team consistency
676
+ * Automate validation in CI/CD
677
+ * Keep backups before in-place updates
678
+ * Review normalized changes before applying
679
+ * Use version control for all Changes files
680
+ * Fix errors systematically using error messages
681
+ * Test validation with simple files first