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.
- 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 +209 -55
- data/Gemfile +2 -1
- data/README.adoc +650 -83
- 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/changes/schema_change.rb +32 -22
- data/lib/expressir/changes/{edition_change.rb → version_change.rb} +3 -3
- data/lib/expressir/cli.rb +12 -4
- data/lib/expressir/commands/changes_import_eengine.rb +2 -2
- data/lib/expressir/commands/changes_validate.rb +1 -1
- 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 +16 -3
- metadata +115 -5
- data/docs/benchmarking.adoc +0 -107
- data/docs/liquid_drops.adoc +0 -1547
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Validating Packages
|
|
3
|
+
parent: LER Packages
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 4
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Validating Packages
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
This guide explains how to validate LER package integrity and repository
|
|
13
|
+
consistency using both the CLI and Ruby API. Validation ensures packages are
|
|
14
|
+
complete, correct, and ready for production use.
|
|
15
|
+
|
|
16
|
+
== References
|
|
17
|
+
|
|
18
|
+
* link:index.html[LER Packages Overview]
|
|
19
|
+
* link:creating-packages.html[Creating Packages]
|
|
20
|
+
* link:loading-packages.html[Loading Packages]
|
|
21
|
+
* link:../ruby-api/working-with-repository.html[Working with Repository]
|
|
22
|
+
|
|
23
|
+
== Concepts
|
|
24
|
+
|
|
25
|
+
Package validation:: Checking package structure, metadata integrity, and
|
|
26
|
+
repository consistency.
|
|
27
|
+
|
|
28
|
+
Repository validator:: The [`RepositoryValidator`](../../lib/expressir/model/repository_validator.rb:11)
|
|
29
|
+
class that performs consistency checks.
|
|
30
|
+
|
|
31
|
+
Schema references:: Validation that all `USE FROM` and `REFERENCE FROM`
|
|
32
|
+
statements point to existing schemas.
|
|
33
|
+
|
|
34
|
+
Interface validation:: Checking that all interface items exist in referenced
|
|
35
|
+
schemas.
|
|
36
|
+
|
|
37
|
+
Completeness checks:: Optional validation for schema completeness (entities,
|
|
38
|
+
types, functions).
|
|
39
|
+
|
|
40
|
+
== Validation types
|
|
41
|
+
|
|
42
|
+
=== Basic validation
|
|
43
|
+
|
|
44
|
+
Always performed:
|
|
45
|
+
|
|
46
|
+
Schema reference validation:: Verifies all referenced schemas exist
|
|
47
|
+
Interface item validation:: Checks interface items exist in target schemas
|
|
48
|
+
Circular dependency detection:: Identifies circular references (valid but noteworthy)
|
|
49
|
+
|
|
50
|
+
=== Optional validation
|
|
51
|
+
|
|
52
|
+
Enabled with flags:
|
|
53
|
+
|
|
54
|
+
Strict mode:: Checks for unused schemas
|
|
55
|
+
Interface validation:: Detailed interface consistency checks
|
|
56
|
+
Completeness checks:: Validates schema completeness
|
|
57
|
+
Duplicate checks:: Finds duplicate interface aliases
|
|
58
|
+
Self-reference checks:: Detects self-referencing interfaces
|
|
59
|
+
|
|
60
|
+
== CLI validation
|
|
61
|
+
|
|
62
|
+
=== Basic validation command
|
|
63
|
+
|
|
64
|
+
Use [`expressir package validate`](../../lib/expressir/commands/package.rb:150)
|
|
65
|
+
to validate packages:
|
|
66
|
+
|
|
67
|
+
[source,bash]
|
|
68
|
+
----
|
|
69
|
+
# Basic validation
|
|
70
|
+
expressir package validate schemas.ler
|
|
71
|
+
|
|
72
|
+
# With verbose output
|
|
73
|
+
expressir package validate schemas.ler --verbose
|
|
74
|
+
----
|
|
75
|
+
|
|
76
|
+
.Success output
|
|
77
|
+
[example]
|
|
78
|
+
====
|
|
79
|
+
[source]
|
|
80
|
+
----
|
|
81
|
+
✓ Package is valid
|
|
82
|
+
----
|
|
83
|
+
====
|
|
84
|
+
|
|
85
|
+
.Error output
|
|
86
|
+
[example]
|
|
87
|
+
====
|
|
88
|
+
[source]
|
|
89
|
+
----
|
|
90
|
+
✗ Validation failed
|
|
91
|
+
|
|
92
|
+
Errors (2):
|
|
93
|
+
1. [missing_schema_reference] Interface references non-existent schema
|
|
94
|
+
Schema: action_schema
|
|
95
|
+
Referenced: missing_schema
|
|
96
|
+
2. [missing_interface_item] Interface item not found
|
|
97
|
+
Schema: action_schema
|
|
98
|
+
Referenced: approval_schema
|
|
99
|
+
Item: missing_entity
|
|
100
|
+
----
|
|
101
|
+
====
|
|
102
|
+
|
|
103
|
+
=== Validation options
|
|
104
|
+
|
|
105
|
+
==== Strict mode
|
|
106
|
+
|
|
107
|
+
Enable strict validation for unused schema warnings:
|
|
108
|
+
|
|
109
|
+
[source,bash]
|
|
110
|
+
----
|
|
111
|
+
expressir package validate schemas.ler --strict
|
|
112
|
+
----
|
|
113
|
+
|
|
114
|
+
Strict mode checks:
|
|
115
|
+
|
|
116
|
+
* Unused schemas (not referenced by others)
|
|
117
|
+
* Isolated schema groups
|
|
118
|
+
* Orphaned schemas
|
|
119
|
+
|
|
120
|
+
==== Interface validation
|
|
121
|
+
|
|
122
|
+
Enable detailed interface checking:
|
|
123
|
+
|
|
124
|
+
[source,bash]
|
|
125
|
+
----
|
|
126
|
+
expressir package validate schemas.ler --check-interfaces
|
|
127
|
+
----
|
|
128
|
+
|
|
129
|
+
Interface checks include:
|
|
130
|
+
|
|
131
|
+
* Interface item existence
|
|
132
|
+
* Interface consistency
|
|
133
|
+
* Cross-schema references
|
|
134
|
+
* Type compatibility
|
|
135
|
+
|
|
136
|
+
==== Completeness validation
|
|
137
|
+
|
|
138
|
+
Check for schema completeness:
|
|
139
|
+
|
|
140
|
+
[source,bash]
|
|
141
|
+
----
|
|
142
|
+
expressir package validate schemas.ler --check-completeness
|
|
143
|
+
----
|
|
144
|
+
|
|
145
|
+
Completeness checks:
|
|
146
|
+
|
|
147
|
+
* Schemas with no entities
|
|
148
|
+
* Schemas with entities but no types
|
|
149
|
+
* Empty schemas
|
|
150
|
+
* Minimal schemas
|
|
151
|
+
|
|
152
|
+
==== Duplicate checking
|
|
153
|
+
|
|
154
|
+
Find duplicate interface aliases:
|
|
155
|
+
|
|
156
|
+
[source,bash]
|
|
157
|
+
----
|
|
158
|
+
expressir package validate schemas.ler --check-duplicates
|
|
159
|
+
----
|
|
160
|
+
|
|
161
|
+
==== Self-reference checking
|
|
162
|
+
|
|
163
|
+
Detect self-referencing interfaces:
|
|
164
|
+
|
|
165
|
+
[source,bash]
|
|
166
|
+
----
|
|
167
|
+
expressir package validate schemas.ler --check-self-references
|
|
168
|
+
----
|
|
169
|
+
|
|
170
|
+
==== Detailed reports
|
|
171
|
+
|
|
172
|
+
Get detailed validation reports:
|
|
173
|
+
|
|
174
|
+
[source,bash]
|
|
175
|
+
----
|
|
176
|
+
expressir package validate schemas.ler \
|
|
177
|
+
--check-interfaces \
|
|
178
|
+
--detailed
|
|
179
|
+
----
|
|
180
|
+
|
|
181
|
+
Detailed reports include:
|
|
182
|
+
|
|
183
|
+
* Fix suggestions for each error
|
|
184
|
+
* Context information
|
|
185
|
+
* Related items
|
|
186
|
+
* Severity levels
|
|
187
|
+
|
|
188
|
+
==== Combined validation
|
|
189
|
+
|
|
190
|
+
Use multiple options together:
|
|
191
|
+
|
|
192
|
+
[source,bash]
|
|
193
|
+
----
|
|
194
|
+
expressir package validate schemas.ler \
|
|
195
|
+
--strict \
|
|
196
|
+
--check-interfaces \
|
|
197
|
+
--check-completeness \
|
|
198
|
+
--check-duplicates \
|
|
199
|
+
--check-self-references \
|
|
200
|
+
--detailed
|
|
201
|
+
----
|
|
202
|
+
|
|
203
|
+
=== Output formats
|
|
204
|
+
|
|
205
|
+
Choose output format:
|
|
206
|
+
|
|
207
|
+
[source,bash]
|
|
208
|
+
----
|
|
209
|
+
# Text format (default)
|
|
210
|
+
expressir package validate schemas.ler
|
|
211
|
+
|
|
212
|
+
# JSON format
|
|
213
|
+
expressir package validate schemas.ler --format json
|
|
214
|
+
|
|
215
|
+
# YAML format
|
|
216
|
+
expressir package validate schemas.ler --format yaml
|
|
217
|
+
----
|
|
218
|
+
|
|
219
|
+
.JSON output example
|
|
220
|
+
[example]
|
|
221
|
+
====
|
|
222
|
+
[source,json]
|
|
223
|
+
----
|
|
224
|
+
{
|
|
225
|
+
"valid?": false,
|
|
226
|
+
"errors": [
|
|
227
|
+
{
|
|
228
|
+
"type": "missing_schema_reference",
|
|
229
|
+
"schema": "action_schema",
|
|
230
|
+
"referenced_schema": "missing_schema",
|
|
231
|
+
"message": "Schema 'action_schema' references non-existent schema 'missing_schema'"
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"warnings": [
|
|
235
|
+
{
|
|
236
|
+
"type": "unused_schema",
|
|
237
|
+
"schema": "utility_schema",
|
|
238
|
+
"message": "Schema 'utility_schema' is not referenced by any other schema"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
----
|
|
243
|
+
====
|
|
244
|
+
|
|
245
|
+
== Ruby API validation
|
|
246
|
+
|
|
247
|
+
=== Basic validation
|
|
248
|
+
|
|
249
|
+
Validate using the repository:
|
|
250
|
+
|
|
251
|
+
[source,ruby]
|
|
252
|
+
----
|
|
253
|
+
require "expressir"
|
|
254
|
+
|
|
255
|
+
# Load package
|
|
256
|
+
repo = Expressir::Model::Repository.from_package("schemas.ler")
|
|
257
|
+
|
|
258
|
+
# Validate
|
|
259
|
+
validation = repo.validate
|
|
260
|
+
|
|
261
|
+
if validation[:valid?]
|
|
262
|
+
puts "✓ Package is valid"
|
|
263
|
+
else
|
|
264
|
+
puts "✗ Validation failed"
|
|
265
|
+
puts "Errors: #{validation[:errors].size}"
|
|
266
|
+
puts "Warnings: #{validation[:warnings].size}"
|
|
267
|
+
end
|
|
268
|
+
----
|
|
269
|
+
|
|
270
|
+
=== Validation with options
|
|
271
|
+
|
|
272
|
+
Enable additional checks:
|
|
273
|
+
|
|
274
|
+
[source,ruby]
|
|
275
|
+
----
|
|
276
|
+
validation = repo.validate(
|
|
277
|
+
strict: true, # Enable strict mode
|
|
278
|
+
check_interfaces: true, # Detailed interface validation
|
|
279
|
+
check_completeness: true, # Check schema completeness
|
|
280
|
+
check_duplicates: true, # Check for duplicate aliases
|
|
281
|
+
check_self_references: true, # Check self-references
|
|
282
|
+
detailed: true # Generate detailed reports
|
|
283
|
+
)
|
|
284
|
+
----
|
|
285
|
+
|
|
286
|
+
=== Handling validation results
|
|
287
|
+
|
|
288
|
+
Process validation results:
|
|
289
|
+
|
|
290
|
+
[source,ruby]
|
|
291
|
+
----
|
|
292
|
+
validation = repo.validate(strict: true, check_interfaces: true)
|
|
293
|
+
|
|
294
|
+
# Check if valid
|
|
295
|
+
if validation[:valid?]
|
|
296
|
+
puts "✓ Validation passed"
|
|
297
|
+
else
|
|
298
|
+
puts "✗ Validation failed with #{validation[:errors].size} errors"
|
|
299
|
+
|
|
300
|
+
# Display errors
|
|
301
|
+
validation[:errors].each_with_index do |error, i|
|
|
302
|
+
puts "\nError #{i + 1}: [#{error[:type]}]"
|
|
303
|
+
puts " Message: #{error[:message]}"
|
|
304
|
+
puts " Schema: #{error[:schema]}" if error[:schema]
|
|
305
|
+
puts " Referenced: #{error[:referenced_schema]}" if error[:referenced_schema]
|
|
306
|
+
puts " Item: #{error[:item]}" if error[:item]
|
|
307
|
+
puts " Fix: #{error[:fix_suggestion]}" if error[:fix_suggestion]
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Display warnings
|
|
312
|
+
if validation[:warnings]&.any?
|
|
313
|
+
puts "\nWarnings (#{validation[:warnings].size}):"
|
|
314
|
+
|
|
315
|
+
validation[:warnings].each_with_index do |warning, i|
|
|
316
|
+
puts "\nWarning #{i + 1}: [#{warning[:type]}]"
|
|
317
|
+
puts " Message: #{warning[:message]}"
|
|
318
|
+
puts " Schema: #{warning[:schema]}" if warning[:schema]
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Display detailed report if available
|
|
323
|
+
if validation[:interface_report]
|
|
324
|
+
puts "\n" + validation[:interface_report]
|
|
325
|
+
end
|
|
326
|
+
----
|
|
327
|
+
|
|
328
|
+
=== Validation in build pipeline
|
|
329
|
+
|
|
330
|
+
Validate before creating package:
|
|
331
|
+
|
|
332
|
+
[source,ruby]
|
|
333
|
+
----
|
|
334
|
+
# Parse schemas
|
|
335
|
+
files = Dir.glob("schemas/**/*.exp")
|
|
336
|
+
repo = Expressir::Express::Parser.from_files(files)
|
|
337
|
+
|
|
338
|
+
# Validate before packaging
|
|
339
|
+
validation = repo.validate(
|
|
340
|
+
strict: true,
|
|
341
|
+
check_interfaces: true,
|
|
342
|
+
check_completeness: true
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
unless validation[:valid?]
|
|
346
|
+
puts "Validation failed - cannot create package"
|
|
347
|
+
validation[:errors].each do |error|
|
|
348
|
+
puts " - #{error[:message]}"
|
|
349
|
+
end
|
|
350
|
+
exit 1
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Create package
|
|
354
|
+
repo.export_to_package(
|
|
355
|
+
"output.ler",
|
|
356
|
+
name: "Validated Package",
|
|
357
|
+
version: "1.0.0"
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
puts "✓ Package created and validated"
|
|
361
|
+
----
|
|
362
|
+
|
|
363
|
+
== Common validation errors
|
|
364
|
+
|
|
365
|
+
=== Missing schema reference
|
|
366
|
+
|
|
367
|
+
.Error
|
|
368
|
+
[example]
|
|
369
|
+
====
|
|
370
|
+
[source]
|
|
371
|
+
----
|
|
372
|
+
Type: missing_schema_reference
|
|
373
|
+
Schema: action_schema
|
|
374
|
+
Referenced: geometric_model_schema
|
|
375
|
+
Message: Schema 'action_schema' references non-existent schema 'geometric_model_schema'
|
|
376
|
+
----
|
|
377
|
+
====
|
|
378
|
+
|
|
379
|
+
.Causes
|
|
380
|
+
[example]
|
|
381
|
+
====
|
|
382
|
+
* Referenced schema not included in package
|
|
383
|
+
* Typo in schema name
|
|
384
|
+
* Schema file not found during build
|
|
385
|
+
* Missing dependency
|
|
386
|
+
====
|
|
387
|
+
|
|
388
|
+
.Solutions
|
|
389
|
+
[example]
|
|
390
|
+
====
|
|
391
|
+
1. Add missing schema to package build
|
|
392
|
+
2. Check spelling of schema references
|
|
393
|
+
3. Verify all dependencies are included
|
|
394
|
+
4. Use dependency resolver to find all schemas
|
|
395
|
+
====
|
|
396
|
+
|
|
397
|
+
=== Missing interface item
|
|
398
|
+
|
|
399
|
+
.Error
|
|
400
|
+
[example]
|
|
401
|
+
====
|
|
402
|
+
[source]
|
|
403
|
+
----
|
|
404
|
+
Type: missing_interface_item
|
|
405
|
+
Schema: action_schema
|
|
406
|
+
Referenced: approval_schema
|
|
407
|
+
Item: approval_status_item
|
|
408
|
+
Message: Interface item 'approval_status_item' not found in schema 'approval_schema'
|
|
409
|
+
----
|
|
410
|
+
====
|
|
411
|
+
|
|
412
|
+
.Causes
|
|
413
|
+
[example]
|
|
414
|
+
====
|
|
415
|
+
* Item renamed or removed in target schema
|
|
416
|
+
* Typo in interface item name
|
|
417
|
+
* Wrong schema referenced
|
|
418
|
+
* Version mismatch between schemas
|
|
419
|
+
====
|
|
420
|
+
|
|
421
|
+
.Solutions
|
|
422
|
+
[example]
|
|
423
|
+
====
|
|
424
|
+
1. Update interface to use correct item name
|
|
425
|
+
2. Add missing item to target schema
|
|
426
|
+
3. Remove obsolete interface item
|
|
427
|
+
4. Sync schema versions
|
|
428
|
+
====
|
|
429
|
+
|
|
430
|
+
=== Circular dependency
|
|
431
|
+
|
|
432
|
+
.Warning
|
|
433
|
+
[example]
|
|
434
|
+
====
|
|
435
|
+
[source]
|
|
436
|
+
----
|
|
437
|
+
Type: circular_dependency
|
|
438
|
+
Cycle: action_schema -> approval_schema -> action_schema
|
|
439
|
+
Message: Circular dependency (valid in EXPRESS): action_schema -> approval_schema -> action_schema
|
|
440
|
+
----
|
|
441
|
+
====
|
|
442
|
+
|
|
443
|
+
.Note
|
|
444
|
+
[example]
|
|
445
|
+
====
|
|
446
|
+
Circular dependencies are valid in EXPRESS but flagged as warnings for
|
|
447
|
+
awareness. Mutual `USE FROM` statements are common and acceptable.
|
|
448
|
+
====
|
|
449
|
+
|
|
450
|
+
=== Unused schema
|
|
451
|
+
|
|
452
|
+
.Warning (strict mode)
|
|
453
|
+
[example]
|
|
454
|
+
====
|
|
455
|
+
[source]
|
|
456
|
+
----
|
|
457
|
+
Type: unused_schema
|
|
458
|
+
Schema: utility_schema
|
|
459
|
+
Message: Schema 'utility_schema' is not referenced by any other schema
|
|
460
|
+
----
|
|
461
|
+
====
|
|
462
|
+
|
|
463
|
+
.Causes
|
|
464
|
+
[example]
|
|
465
|
+
====
|
|
466
|
+
* Schema is entry point (no references expected)
|
|
467
|
+
* Schema is utility library
|
|
468
|
+
* Obsolete schema included accidentally
|
|
469
|
+
* Missing interface statements
|
|
470
|
+
====
|
|
471
|
+
|
|
472
|
+
.Solutions
|
|
473
|
+
[example]
|
|
474
|
+
====
|
|
475
|
+
1. Verify schema is needed
|
|
476
|
+
2. Add as documented entry point
|
|
477
|
+
3. Remove if obsolete
|
|
478
|
+
4. Add missing USE FROM/REFERENCE FROM
|
|
479
|
+
====
|
|
480
|
+
|
|
481
|
+
=== Empty schema
|
|
482
|
+
|
|
483
|
+
.Warning (completeness check)
|
|
484
|
+
[example]
|
|
485
|
+
====
|
|
486
|
+
[source]
|
|
487
|
+
----
|
|
488
|
+
Type: empty_schema
|
|
489
|
+
Schema: placeholder_schema
|
|
490
|
+
Message: Schema 'placeholder_schema' has no entities defined
|
|
491
|
+
----
|
|
492
|
+
====
|
|
493
|
+
|
|
494
|
+
.Causes
|
|
495
|
+
[example]
|
|
496
|
+
====
|
|
497
|
+
* Work-in-progress schema
|
|
498
|
+
* Interface-only schema
|
|
499
|
+
* Template schema
|
|
500
|
+
* Incomplete development
|
|
501
|
+
====
|
|
502
|
+
|
|
503
|
+
== Validation best practices
|
|
504
|
+
|
|
505
|
+
=== Pre-deployment validation
|
|
506
|
+
|
|
507
|
+
Always validate before deploying:
|
|
508
|
+
|
|
509
|
+
[source,ruby]
|
|
510
|
+
----
|
|
511
|
+
def deploy_package(package_path)
|
|
512
|
+
# Load package
|
|
513
|
+
repo = Expressir::Model::Repository.from_package(package_path)
|
|
514
|
+
|
|
515
|
+
# Comprehensive validation
|
|
516
|
+
validation = repo.validate(
|
|
517
|
+
strict: true,
|
|
518
|
+
check_interfaces: true,
|
|
519
|
+
check_completeness: true,
|
|
520
|
+
check_duplicates: true,
|
|
521
|
+
check_self_references: true
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
# Fail fast on errors
|
|
525
|
+
if !validation[:valid?]
|
|
526
|
+
raise "Package validation failed: #{validation[:errors].size} errors"
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
# Log warnings
|
|
530
|
+
if validation[:warnings]&.any?
|
|
531
|
+
puts "Package has #{validation[:warnings].size} warnings"
|
|
532
|
+
validation[:warnings].each do |w|
|
|
533
|
+
puts " - #{w[:message]}"
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
# Deploy package
|
|
538
|
+
deploy_to_production(package_path)
|
|
539
|
+
end
|
|
540
|
+
----
|
|
541
|
+
|
|
542
|
+
=== CI/CD validation
|
|
543
|
+
|
|
544
|
+
Automate validation in CI/CD:
|
|
545
|
+
|
|
546
|
+
[source,yaml]
|
|
547
|
+
----
|
|
548
|
+
# .github/workflows/validate.yml
|
|
549
|
+
name: Validate Package
|
|
550
|
+
|
|
551
|
+
on: [push, pull_request]
|
|
552
|
+
|
|
553
|
+
jobs:
|
|
554
|
+
validate:
|
|
555
|
+
runs-on: ubuntu-latest
|
|
556
|
+
steps:
|
|
557
|
+
- uses: actions/checkout@v2
|
|
558
|
+
|
|
559
|
+
- name: Set up Ruby
|
|
560
|
+
uses: ruby/setup-ruby@v1
|
|
561
|
+
with:
|
|
562
|
+
ruby-version: 3.0
|
|
563
|
+
|
|
564
|
+
- name: Install Expressir
|
|
565
|
+
run: gem install expressir
|
|
566
|
+
|
|
567
|
+
- name: Build package
|
|
568
|
+
run: |
|
|
569
|
+
expressir package build \
|
|
570
|
+
schemas/main.exp \
|
|
571
|
+
output/schemas.ler \
|
|
572
|
+
--validate
|
|
573
|
+
|
|
574
|
+
- name: Validate package
|
|
575
|
+
run: |
|
|
576
|
+
expressir package validate \
|
|
577
|
+
output/schemas.ler \
|
|
578
|
+
--strict \
|
|
579
|
+
--check-interfaces \
|
|
580
|
+
--check-completeness \
|
|
581
|
+
--format json > validation.json
|
|
582
|
+
|
|
583
|
+
- name: Upload validation results
|
|
584
|
+
uses: actions/upload-artifact@v2
|
|
585
|
+
with:
|
|
586
|
+
name: validation-results
|
|
587
|
+
path: validation.json
|
|
588
|
+
----
|
|
589
|
+
|
|
590
|
+
=== Validation gates
|
|
591
|
+
|
|
592
|
+
Implement validation gates:
|
|
593
|
+
|
|
594
|
+
[source,ruby]
|
|
595
|
+
----
|
|
596
|
+
class ValidationGate
|
|
597
|
+
REQUIRED_CHECKS = {
|
|
598
|
+
basic: true,
|
|
599
|
+
interfaces: true,
|
|
600
|
+
completeness: false, # Warning only
|
|
601
|
+
duplicates: true,
|
|
602
|
+
self_references: true
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
def self.validate(package_path)
|
|
606
|
+
repo = Expressir::Model::Repository.from_package(package_path)
|
|
607
|
+
|
|
608
|
+
validation = repo.validate(
|
|
609
|
+
strict: true,
|
|
610
|
+
check_interfaces: REQUIRED_CHECKS[:interfaces],
|
|
611
|
+
check_completeness: REQUIRED_CHECKS[:completeness],
|
|
612
|
+
check_duplicates: REQUIRED_CHECKS[:duplicates],
|
|
613
|
+
check_self_references: REQUIRED_CHECKS[:self_references]
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
# Fail on errors
|
|
617
|
+
if !validation[:valid?]
|
|
618
|
+
log_errors(validation)
|
|
619
|
+
return false
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
# Log but allow warnings
|
|
623
|
+
log_warnings(validation) if validation[:warnings]&.any?
|
|
624
|
+
|
|
625
|
+
true
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
def self.log_errors(validation)
|
|
629
|
+
puts "VALIDATION FAILED"
|
|
630
|
+
validation[:errors].each do |error|
|
|
631
|
+
puts " ✗ #{error[:message]}"
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
def self.log_warnings(validation)
|
|
636
|
+
puts "VALIDATION WARNINGS"
|
|
637
|
+
validation[:warnings].each do |warning|
|
|
638
|
+
puts " ⚠ #{warning[:message]}"
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
end
|
|
642
|
+
----
|
|
643
|
+
|
|
644
|
+
== Fixing validation issues
|
|
645
|
+
|
|
646
|
+
=== Automated fixes
|
|
647
|
+
|
|
648
|
+
Some issues can be fixed automatically:
|
|
649
|
+
|
|
650
|
+
[source,ruby]
|
|
651
|
+
----
|
|
652
|
+
def fix_and_validate(schema_dir, output_package)
|
|
653
|
+
# Parse all schemas
|
|
654
|
+
files = Dir.glob("#{schema_dir}/**/*.exp")
|
|
655
|
+
repo = Expressir::Express::Parser.from_files(files)
|
|
656
|
+
|
|
657
|
+
# Initial validation
|
|
658
|
+
validation = repo.validate(strict: true)
|
|
659
|
+
|
|
660
|
+
if validation[:errors].any?
|
|
661
|
+
puts "Found #{validation[:errors].size} errors"
|
|
662
|
+
|
|
663
|
+
# Attempt automated fixes
|
|
664
|
+
validation[:errors].each do |error|
|
|
665
|
+
case error[:type]
|
|
666
|
+
when :missing_schema_reference
|
|
667
|
+
puts "Cannot auto-fix missing schema: #{error[:referenced_schema]}"
|
|
668
|
+
puts " Add schema manually or update reference"
|
|
669
|
+
|
|
670
|
+
when :missing_interface_item
|
|
671
|
+
puts "Cannot auto-fix missing item: #{error[:item]}"
|
|
672
|
+
puts " Update interface or add item to schema"
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
return false
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# Create package
|
|
680
|
+
repo.export_to_package(output_package)
|
|
681
|
+
true
|
|
682
|
+
end
|
|
683
|
+
----
|
|
684
|
+
|
|
685
|
+
=== Manual review process
|
|
686
|
+
|
|
687
|
+
Create validation report for review:
|
|
688
|
+
|
|
689
|
+
[source,ruby]
|
|
690
|
+
----
|
|
691
|
+
def create_validation_report(package_path, output_file)
|
|
692
|
+
repo = Expressir::Model::Repository.from_package(package_path)
|
|
693
|
+
|
|
694
|
+
validation = repo.validate(
|
|
695
|
+
strict: true,
|
|
696
|
+
check_interfaces: true,
|
|
697
|
+
check_completeness: true,
|
|
698
|
+
detailed: true
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
report = {
|
|
702
|
+
package: package_path,
|
|
703
|
+
validated_at: Time.now.iso8601,
|
|
704
|
+
valid: validation[:valid?],
|
|
705
|
+
summary: {
|
|
706
|
+
errors: validation[:errors].size,
|
|
707
|
+
warnings: validation[:warnings].size
|
|
708
|
+
},
|
|
709
|
+
errors: validation[:errors],
|
|
710
|
+
warnings: validation[:warnings],
|
|
711
|
+
interface_report: validation[:interface_report]
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
File.write(output_file, JSON.pretty_generate(report))
|
|
715
|
+
puts "Validation report written to #{output_file}"
|
|
716
|
+
end
|
|
717
|
+
----
|
|
718
|
+
|
|
719
|
+
== Next steps
|
|
720
|
+
|
|
721
|
+
* link:package-formats.html[Package Formats] - Understanding serialization
|
|
722
|
+
formats
|
|
723
|
+
* link:creating-packages.html[Creating Packages] - Build validated packages
|
|
724
|
+
* link:loading-packages.html[Loading Packages] - Load validated packages
|
|
725
|
+
* link:../ruby-api/working-with-repository.html[Working with Repository] - API
|
|
726
|
+
reference
|
|
727
|
+
|
|
728
|
+
== Summary
|
|
729
|
+
|
|
730
|
+
Key takeaways for validating LER packages:
|
|
731
|
+
|
|
732
|
+
* Always validate packages before deployment
|
|
733
|
+
* Use strict mode for production packages
|
|
734
|
+
* Enable interface validation for completeness
|
|
735
|
+
* Check for common errors: missing schemas and items
|
|
736
|
+
* Automate validation in CI/CD pipelines
|
|
737
|
+
* Log warnings even if validation passes
|
|
738
|
+
* Create validation reports for review
|
|
739
|
+
* Fix errors before creating packages
|
|
740
|
+
|
|
741
|
+
Best practices:
|
|
742
|
+
|
|
743
|
+
* Validate early and often
|
|
744
|
+
* Use comprehensive checks for production
|
|
745
|
+
* Automate validation in build process
|
|
746
|
+
* Log validation results
|
|
747
|
+
* Implement validation gates
|
|
748
|
+
* Review warnings regularly
|
|
749
|
+
* Fix errors at source
|
|
750
|
+
* Document known issues
|