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,837 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: LER Packages
|
|
3
|
+
nav_order: 7
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
== LutaML EXPRESS Repository (LER) Packages
|
|
7
|
+
|
|
8
|
+
=== Purpose
|
|
9
|
+
|
|
10
|
+
This page introduces LutaML EXPRESS Repository (LER) packages, a high-performance format for distributing pre-parsed and indexed EXPRESS schemas. LER packages solve critical challenges in managing complex, multi-schema EXPRESS applications by bundling everything into a single, optimized file.
|
|
11
|
+
|
|
12
|
+
=== References
|
|
13
|
+
|
|
14
|
+
* link:parsers.html[Parsers] - How schemas are parsed for LER
|
|
15
|
+
* link:data-model.html[Data Model] - What LER packages contain
|
|
16
|
+
* link:../guides/ler/[LER Guides] - Detailed usage guides
|
|
17
|
+
* link:../tutorials/creating-ler-package.html[Tutorial: Creating LER Packages]
|
|
18
|
+
|
|
19
|
+
=== Concepts
|
|
20
|
+
|
|
21
|
+
LER:: LutaML EXPRESS Repository - a distributable, pre-indexed EXPRESS schema repository format
|
|
22
|
+
Package:: Single `.ler` file containing schemas, dependencies, and indexes
|
|
23
|
+
Pre-built Index:: Entity and type lookup tables created during packaging for instant queries
|
|
24
|
+
Dependency Resolution:: Automatic discovery and inclusion of all referenced schemas via USE FROM and REFERENCE FROM
|
|
25
|
+
Serialization:: Converting parsed schemas to optimized binary or text formats
|
|
26
|
+
|
|
27
|
+
=== What are LER Packages?
|
|
28
|
+
|
|
29
|
+
LER is a `.ler` file format that bundles EXPRESS schemas and their dependencies into a single, self-contained package with pre-built indexes for fast access.
|
|
30
|
+
|
|
31
|
+
==== Key Components
|
|
32
|
+
|
|
33
|
+
**Schemas**::
|
|
34
|
+
All EXPRESS schemas, either as original files or pre-serialized Ruby objects
|
|
35
|
+
|
|
36
|
+
**Indexes**::
|
|
37
|
+
Pre-built entity, type, and reference indexes for instant lookups
|
|
38
|
+
|
|
39
|
+
**Metadata**::
|
|
40
|
+
Package name, version, configuration, and statistics
|
|
41
|
+
|
|
42
|
+
**Manifest**::
|
|
43
|
+
Schema list with paths and identifiers
|
|
44
|
+
|
|
45
|
+
==== The LER Concept
|
|
46
|
+
|
|
47
|
+
Traditional workflow:
|
|
48
|
+
|
|
49
|
+
[source]
|
|
50
|
+
----
|
|
51
|
+
┌─────────────┐ ┌──────────┐ ┌────────────┐
|
|
52
|
+
│ 41 .exp │────>│ Parse │────>│ Repository │
|
|
53
|
+
│ files │ │ 10-15s │ │ │
|
|
54
|
+
└─────────────┘ └──────────┘ └────────────┘
|
|
55
|
+
Every time!
|
|
56
|
+
----
|
|
57
|
+
|
|
58
|
+
LER workflow:
|
|
59
|
+
|
|
60
|
+
[source]
|
|
61
|
+
----
|
|
62
|
+
┌─────────────┐ ┌──────────┐ ┌────────────┐
|
|
63
|
+
│ activity │────>│ Load │────>│ Repository │
|
|
64
|
+
│ .ler │ │ <500ms │ │ + Indexes │
|
|
65
|
+
└─────────────┘ └──────────┘ └────────────┘
|
|
66
|
+
Once packaged, instant loading!
|
|
67
|
+
----
|
|
68
|
+
|
|
69
|
+
=== Benefits and Use Cases
|
|
70
|
+
|
|
71
|
+
==== Single-File Distribution
|
|
72
|
+
|
|
73
|
+
**Problem**: Distributing 40+ EXPRESS files with complex dependencies
|
|
74
|
+
|
|
75
|
+
**Solution**: One `.ler` file contains everything
|
|
76
|
+
|
|
77
|
+
[source,bash]
|
|
78
|
+
----
|
|
79
|
+
# Instead of distributing:
|
|
80
|
+
schemas/
|
|
81
|
+
├── action_schema.exp
|
|
82
|
+
├── approval_schema.exp
|
|
83
|
+
├── ... (40+ more files)
|
|
84
|
+
|
|
85
|
+
# Distribute one file:
|
|
86
|
+
application.ler # Everything included!
|
|
87
|
+
----
|
|
88
|
+
|
|
89
|
+
==== Instant Loading
|
|
90
|
+
|
|
91
|
+
**Problem**: Parsing 40+ schemas takes 10-15 seconds every time
|
|
92
|
+
|
|
93
|
+
**Solution**: Pre-serialize and cache the parsed result
|
|
94
|
+
|
|
95
|
+
**Performance**:
|
|
96
|
+
|
|
97
|
+
* Traditional parsing: 10-15 seconds
|
|
98
|
+
* LER loading: <500ms (20x+ faster)
|
|
99
|
+
* Entity/type lookups: <1ms
|
|
100
|
+
|
|
101
|
+
==== Pre-built Indexes
|
|
102
|
+
|
|
103
|
+
**Problem**: Finding entities/types requires traversing all schemas
|
|
104
|
+
|
|
105
|
+
**Solution**: Build indexes during packaging
|
|
106
|
+
|
|
107
|
+
[source,ruby]
|
|
108
|
+
----
|
|
109
|
+
# Without index: O(n) search through all schemas
|
|
110
|
+
schemas.each do |schema|
|
|
111
|
+
schema.entities.find { |e| e.id == "action" }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# With LER index: O(1) hash lookup
|
|
115
|
+
entity = repo.find_entity(qualified_name: "action_schema.action") # Instant!
|
|
116
|
+
----
|
|
117
|
+
|
|
118
|
+
==== Automatic Dependency Resolution
|
|
119
|
+
|
|
120
|
+
**Problem**: Manually tracking USE FROM and REFERENCE FROM dependencies
|
|
121
|
+
|
|
122
|
+
**Solution**: LER builder recursively discovers all dependencies
|
|
123
|
+
|
|
124
|
+
[source,bash]
|
|
125
|
+
----
|
|
126
|
+
# Build from single root schema
|
|
127
|
+
expressir package build activity/mim.exp activity.ler
|
|
128
|
+
|
|
129
|
+
# Automatically includes:
|
|
130
|
+
# activity/mim.exp (root)
|
|
131
|
+
# ├─ action_schema
|
|
132
|
+
# ├─ management_resources_schema
|
|
133
|
+
# │ ├─ application_context_schema
|
|
134
|
+
# │ └─ date_time_schema
|
|
135
|
+
# └─ ... (40+ total schemas discovered!)
|
|
136
|
+
----
|
|
137
|
+
|
|
138
|
+
==== Self-Contained Packages
|
|
139
|
+
|
|
140
|
+
**Problem**: Production deployment requires all schema files
|
|
141
|
+
|
|
142
|
+
**Solution**: Everything embedded in the package
|
|
143
|
+
|
|
144
|
+
* No external file dependencies
|
|
145
|
+
* Works offline
|
|
146
|
+
* Version-locked schemas
|
|
147
|
+
* Reproducible builds
|
|
148
|
+
|
|
149
|
+
=== When to Use LER Packages
|
|
150
|
+
|
|
151
|
+
**Production deployment**::
|
|
152
|
+
Eliminate parsing overhead in production applications
|
|
153
|
+
|
|
154
|
+
**Schema distribution**::
|
|
155
|
+
Publish schemas as single downloadable files
|
|
156
|
+
|
|
157
|
+
**Large schema sets**::
|
|
158
|
+
Especially beneficial with 10+ interdependent schemas
|
|
159
|
+
|
|
160
|
+
**Repeated access**::
|
|
161
|
+
Applications that load schemas frequently
|
|
162
|
+
|
|
163
|
+
**API services**::
|
|
164
|
+
Web services that query schemas for documentation or validation
|
|
165
|
+
|
|
166
|
+
**Development tools**::
|
|
167
|
+
IDE plugins, validators, documentation generators
|
|
168
|
+
|
|
169
|
+
=== When NOT to Use LER Packages
|
|
170
|
+
|
|
171
|
+
**Single schema files**::
|
|
172
|
+
Minimal benefit for standalone schemas
|
|
173
|
+
|
|
174
|
+
**Actively changing schemas**::
|
|
175
|
+
Constantly rebuilding packages during development
|
|
176
|
+
|
|
177
|
+
**Schema exploration**::
|
|
178
|
+
When you need to read original EXPRESS text
|
|
179
|
+
|
|
180
|
+
**Debugging**::
|
|
181
|
+
Original .exp files are clearer for troubleshooting
|
|
182
|
+
|
|
183
|
+
=== Package Structure
|
|
184
|
+
|
|
185
|
+
LER packages are ZIP archives containing structured data:
|
|
186
|
+
|
|
187
|
+
[source]
|
|
188
|
+
----
|
|
189
|
+
activity.ler (ZIP archive)
|
|
190
|
+
├── metadata.yaml # Package metadata
|
|
191
|
+
├── repository.marshal # Serialized schemas (if resolved)
|
|
192
|
+
├── express_files/ # Original EXPRESS files (if included)
|
|
193
|
+
│ ├── Activity_mim.exp
|
|
194
|
+
│ ├── action_schema.exp
|
|
195
|
+
│ └── ... (more files)
|
|
196
|
+
├── entity_index.marshal # Pre-built entity index
|
|
197
|
+
├── type_index.marshal # Pre-built type index
|
|
198
|
+
├── reference_index.marshal # Pre-built reference index
|
|
199
|
+
└── manifest.yaml # Schema manifest
|
|
200
|
+
----
|
|
201
|
+
|
|
202
|
+
==== Metadata
|
|
203
|
+
|
|
204
|
+
Package information and configuration:
|
|
205
|
+
|
|
206
|
+
[source,yaml]
|
|
207
|
+
----
|
|
208
|
+
name: "ISO 10303 Activity Module"
|
|
209
|
+
version: "1.0.0"
|
|
210
|
+
description: "Activity module with dependencies"
|
|
211
|
+
created_at: "2025-10-29T03:36:00Z"
|
|
212
|
+
express_mode: "include_all"
|
|
213
|
+
resolution_mode: "resolved"
|
|
214
|
+
serialization_format: "marshal"
|
|
215
|
+
----
|
|
216
|
+
|
|
217
|
+
==== Repository
|
|
218
|
+
|
|
219
|
+
Pre-serialized schema data (if resolution_mode is "resolved"):
|
|
220
|
+
|
|
221
|
+
* All parsed schemas as Ruby objects
|
|
222
|
+
* Fully resolved references
|
|
223
|
+
* Ready to deserialize instantly
|
|
224
|
+
|
|
225
|
+
==== Indexes
|
|
226
|
+
|
|
227
|
+
Pre-built lookup tables:
|
|
228
|
+
|
|
229
|
+
* **Entity index**: Qualified name → Entity object
|
|
230
|
+
* **Type index**: Qualified name → Type object
|
|
231
|
+
* **Reference index**: Source → Target mappings
|
|
232
|
+
|
|
233
|
+
==== Express Files
|
|
234
|
+
|
|
235
|
+
Original EXPRESS files (if express_mode is "include_all"):
|
|
236
|
+
|
|
237
|
+
* Preserves original text
|
|
238
|
+
* Enables regeneration
|
|
239
|
+
* Useful for documentation
|
|
240
|
+
|
|
241
|
+
=== Configuration Options
|
|
242
|
+
|
|
243
|
+
LER packages are highly configurable through three independent axes:
|
|
244
|
+
|
|
245
|
+
==== Express Mode
|
|
246
|
+
|
|
247
|
+
**include_all** (default)::
|
|
248
|
+
Bundle all EXPRESS files into package
|
|
249
|
+
+
|
|
250
|
+
* Self-contained
|
|
251
|
+
* Larger package size
|
|
252
|
+
* Can regenerate schemas
|
|
253
|
+
|
|
254
|
+
**allow_external**::
|
|
255
|
+
Reference external EXPRESS files
|
|
256
|
+
+
|
|
257
|
+
* Smaller package
|
|
258
|
+
* Requires file access
|
|
259
|
+
* Not portable
|
|
260
|
+
|
|
261
|
+
==== Resolution Mode
|
|
262
|
+
|
|
263
|
+
**resolved** (default)::
|
|
264
|
+
Pre-serialize parsed schemas
|
|
265
|
+
+
|
|
266
|
+
* Instant loading
|
|
267
|
+
* Larger package
|
|
268
|
+
* No parsing needed
|
|
269
|
+
|
|
270
|
+
**bare**::
|
|
271
|
+
Store only EXPRESS files, parse on load
|
|
272
|
+
+
|
|
273
|
+
* Smaller package
|
|
274
|
+
* Slower loading
|
|
275
|
+
* Always fresh parse
|
|
276
|
+
|
|
277
|
+
==== Serialization Format
|
|
278
|
+
|
|
279
|
+
**marshal** (default, recommended)::
|
|
280
|
+
Ruby's native binary format
|
|
281
|
+
+
|
|
282
|
+
* Fastest loading
|
|
283
|
+
* Smallest size
|
|
284
|
+
* Ruby-only
|
|
285
|
+
|
|
286
|
+
**yaml**::
|
|
287
|
+
Human-readable text format
|
|
288
|
+
+
|
|
289
|
+
* Cross-platform
|
|
290
|
+
* Debuggable
|
|
291
|
+
* Larger size
|
|
292
|
+
|
|
293
|
+
**json**::
|
|
294
|
+
Standard JSON format
|
|
295
|
+
+
|
|
296
|
+
* Cross-platform
|
|
297
|
+
* Language-agnostic
|
|
298
|
+
* Moderate size
|
|
299
|
+
|
|
300
|
+
=== Performance Comparison
|
|
301
|
+
|
|
302
|
+
Real-world performance with ISO 10303 Activity module (41 schemas, 925 entities):
|
|
303
|
+
|
|
304
|
+
[options="header"]
|
|
305
|
+
|===
|
|
306
|
+
| Operation | Traditional | LER | Improvement
|
|
307
|
+
| Initial load | 10-15 seconds | <500ms | 20-30x faster
|
|
308
|
+
| Entity lookup | ~50ms | <1ms | 50x faster
|
|
309
|
+
| Type lookup | ~50ms | <1ms | 50x faster
|
|
310
|
+
| Statistics | ~100ms | <10ms | 10x faster
|
|
311
|
+
|===
|
|
312
|
+
|
|
313
|
+
==== Memory Usage
|
|
314
|
+
|
|
315
|
+
**Traditional approach**:
|
|
316
|
+
|
|
317
|
+
* Parse all files: ~100MB peak memory
|
|
318
|
+
* Build indexes: +20MB
|
|
319
|
+
* Total: ~120MB
|
|
320
|
+
|
|
321
|
+
**LER approach**:
|
|
322
|
+
|
|
323
|
+
* Load pre-serialized: ~80MB (marshal format)
|
|
324
|
+
* Indexes included: +0MB (already built)
|
|
325
|
+
* Total: 80MB
|
|
326
|
+
|
|
327
|
+
=== Creating Packages
|
|
328
|
+
|
|
329
|
+
==== Simple Package Creation
|
|
330
|
+
|
|
331
|
+
[source,bash]
|
|
332
|
+
----
|
|
333
|
+
# Build from single schema with automatic dependency resolution
|
|
334
|
+
expressir package build myschema.exp output.ler \
|
|
335
|
+
--name "My Schema Package" \
|
|
336
|
+
--version "1.0.0" \
|
|
337
|
+
--validate
|
|
338
|
+
----
|
|
339
|
+
|
|
340
|
+
This command:
|
|
341
|
+
|
|
342
|
+
1. Parses `myschema.exp`
|
|
343
|
+
2. Discovers all dependencies via USE FROM/REFERENCE FROM
|
|
344
|
+
3. Recursively resolves and parses dependencies
|
|
345
|
+
4. Builds indexes
|
|
346
|
+
5. Creates `output.ler` package
|
|
347
|
+
|
|
348
|
+
==== Manifest-Based Package Building
|
|
349
|
+
|
|
350
|
+
For complex schemas with unresolved dependencies or when you need reproducible builds, use schema manifests.
|
|
351
|
+
|
|
352
|
+
See the link:schema-manifests.html[Schema Manifests] documentation for complete details on the manifest file format and workflow.
|
|
353
|
+
|
|
354
|
+
===== What are Manifests?
|
|
355
|
+
|
|
356
|
+
Manifests are YAML files that explicitly list all schemas to include in a package. They provide:
|
|
357
|
+
|
|
358
|
+
* **Fine-grained control** over schema resolution
|
|
359
|
+
* **Reproducible builds** with version-locked schema paths
|
|
360
|
+
* **Pre-validation** of missing dependencies
|
|
361
|
+
* **Documentation** of schema relationships
|
|
362
|
+
* **Circular dependency handling** with explicit schema lists
|
|
363
|
+
|
|
364
|
+
For detailed information about creating, validating, and using manifests, see link:schema-manifests.html[Schema Manifests].
|
|
365
|
+
|
|
366
|
+
===== When to Use Manifests
|
|
367
|
+
|
|
368
|
+
**Complex dependency hierarchies**::
|
|
369
|
+
Schemas in non-standard locations or with circular references
|
|
370
|
+
|
|
371
|
+
**Missing schemas**::
|
|
372
|
+
When auto-resolution can't find all dependencies
|
|
373
|
+
|
|
374
|
+
**Reproducible builds**::
|
|
375
|
+
Lock exact schema versions and paths
|
|
376
|
+
|
|
377
|
+
**Documentation**::
|
|
378
|
+
Explicitly document which schemas are included
|
|
379
|
+
|
|
380
|
+
**Debugging**::
|
|
381
|
+
See exactly what will be packaged before building
|
|
382
|
+
|
|
383
|
+
===== Manifest Structure
|
|
384
|
+
|
|
385
|
+
Manifests are YAML files with this structure:
|
|
386
|
+
|
|
387
|
+
[source,yaml]
|
|
388
|
+
----
|
|
389
|
+
name: Package Name
|
|
390
|
+
version: 1.0.0
|
|
391
|
+
created_at: '2025-12-04T05:40:40Z'
|
|
392
|
+
root_schemas:
|
|
393
|
+
- /full/path/to/root.exp
|
|
394
|
+
base_dirs:
|
|
395
|
+
- /search/directory
|
|
396
|
+
schemas:
|
|
397
|
+
- name: resolved_schema
|
|
398
|
+
path: /full/path/to/schema.exp
|
|
399
|
+
dependencies:
|
|
400
|
+
- schema_name: other_schema
|
|
401
|
+
kind: USE
|
|
402
|
+
- name: unresolved_schema # No path specified
|
|
403
|
+
----
|
|
404
|
+
|
|
405
|
+
**Key points**:
|
|
406
|
+
|
|
407
|
+
* Unresolved schemas appear without a `path` field
|
|
408
|
+
* User manually adds `path:` to resolve them
|
|
409
|
+
* Dependencies are documented but not required for building
|
|
410
|
+
|
|
411
|
+
===== Creating Manifests
|
|
412
|
+
|
|
413
|
+
Use the `expressir manifest create` command to generate a manifest from root schemas.
|
|
414
|
+
|
|
415
|
+
See link:schema-manifests.html#creating-a-manifest-from-a-root-schema[Creating a manifest from a root schema] for complete details.
|
|
416
|
+
|
|
417
|
+
[source,bash]
|
|
418
|
+
----
|
|
419
|
+
expressir manifest create ROOT_SCHEMA -o OUTPUT.yaml [OPTIONS]
|
|
420
|
+
----
|
|
421
|
+
|
|
422
|
+
.Example: Creating a manifest
|
|
423
|
+
[example]
|
|
424
|
+
====
|
|
425
|
+
[source,bash]
|
|
426
|
+
----
|
|
427
|
+
expressir manifest create schemas/activity/mim.exp \
|
|
428
|
+
-o activity_manifest.yaml \
|
|
429
|
+
--base-dirs ~/iso-10303/schemas \
|
|
430
|
+
--name "Activity Module" \
|
|
431
|
+
--verbose
|
|
432
|
+
----
|
|
433
|
+
|
|
434
|
+
Output shows resolved and unresolved schemas:
|
|
435
|
+
----
|
|
436
|
+
Creating manifest from 1 root schema(s)...
|
|
437
|
+
Base directories:
|
|
438
|
+
- /Users/user/iso-10303/schemas
|
|
439
|
+
Resolving dependencies...
|
|
440
|
+
WARNING: Could not find schema 'Activity_method_mim' referenced from mim
|
|
441
|
+
Circular reference detected: measure_schema (valid schema-level circular dependency, skipping)
|
|
442
|
+
✓ Manifest created: activity_manifest.yaml
|
|
443
|
+
Resolved schemas: 41
|
|
444
|
+
|
|
445
|
+
⚠ Unresolved schemas (3):
|
|
446
|
+
- Activity_method_mim
|
|
447
|
+
- the
|
|
448
|
+
- main
|
|
449
|
+
|
|
450
|
+
Please edit activity_manifest.yaml and set 'path:' for unresolved schemas
|
|
451
|
+
Then validate with: expressir manifest validate activity_manifest.yaml
|
|
452
|
+
----
|
|
453
|
+
====
|
|
454
|
+
|
|
455
|
+
===== Editing Manifests
|
|
456
|
+
|
|
457
|
+
Add `path:` for unresolved schemas:
|
|
458
|
+
|
|
459
|
+
[source,yaml]
|
|
460
|
+
----
|
|
461
|
+
schemas:
|
|
462
|
+
action_schema:
|
|
463
|
+
path: /path/to/action_schema.exp
|
|
464
|
+
Activity_method_mim: # <1>
|
|
465
|
+
path: /path/to/activity_method/mim.exp # <2>
|
|
466
|
+
the: # <3>
|
|
467
|
+
main: # <3>
|
|
468
|
+
----
|
|
469
|
+
<1> Schema was unresolved (had no path)
|
|
470
|
+
<2> User added path to resolve it
|
|
471
|
+
<3> Still unresolved (will trigger warnings)
|
|
472
|
+
|
|
473
|
+
===== Validating Manifests
|
|
474
|
+
|
|
475
|
+
Validate manifests before building packages to catch errors early.
|
|
476
|
+
|
|
477
|
+
See link:schema-manifests.html#validating-a-manifest[Validating a manifest] for complete validation options and examples.
|
|
478
|
+
|
|
479
|
+
[source,bash]
|
|
480
|
+
----
|
|
481
|
+
expressir manifest validate MANIFEST.yaml [OPTIONS]
|
|
482
|
+
----
|
|
483
|
+
|
|
484
|
+
.Example: Basic validation
|
|
485
|
+
[example]
|
|
486
|
+
====
|
|
487
|
+
[source,bash]
|
|
488
|
+
----
|
|
489
|
+
expressir manifest validate activity_manifest.yaml --verbose
|
|
490
|
+
----
|
|
491
|
+
|
|
492
|
+
Output:
|
|
493
|
+
----
|
|
494
|
+
Validating manifest: activity_manifest.yaml...
|
|
495
|
+
✓ Manifest is valid
|
|
496
|
+
Total schemas: 42
|
|
497
|
+
Resolved schemas: 41
|
|
498
|
+
Unresolved schemas: 1
|
|
499
|
+
|
|
500
|
+
Warnings (1):
|
|
501
|
+
- Schema 'the' has no path specified - please provide path
|
|
502
|
+
----
|
|
503
|
+
====
|
|
504
|
+
|
|
505
|
+
.Example: Validation with referential integrity
|
|
506
|
+
[example]
|
|
507
|
+
====
|
|
508
|
+
[source,bash]
|
|
509
|
+
----
|
|
510
|
+
expressir manifest validate activity_manifest.yaml --check-references --verbose
|
|
511
|
+
----
|
|
512
|
+
|
|
513
|
+
Output with all references resolved:
|
|
514
|
+
----
|
|
515
|
+
Validating manifest: activity_manifest.yaml...
|
|
516
|
+
Checking referential integrity...
|
|
517
|
+
✓ Manifest is valid
|
|
518
|
+
Total schemas: 42
|
|
519
|
+
Resolved schemas: 41
|
|
520
|
+
|
|
521
|
+
All references resolved successfully!
|
|
522
|
+
----
|
|
523
|
+
|
|
524
|
+
Output with unresolved references:
|
|
525
|
+
----
|
|
526
|
+
Validating manifest: activity_manifest.yaml...
|
|
527
|
+
Checking referential integrity...
|
|
528
|
+
✗ Manifest validation failed
|
|
529
|
+
|
|
530
|
+
Errors (2):
|
|
531
|
+
- Cannot resolve USE FROM geometric_model_schema in action_schema
|
|
532
|
+
- Cannot resolve REFERENCE FROM measure_schema in activity_schema
|
|
533
|
+
----
|
|
534
|
+
====
|
|
535
|
+
|
|
536
|
+
===== Building from Manifests
|
|
537
|
+
|
|
538
|
+
[source,bash]
|
|
539
|
+
----
|
|
540
|
+
expressir package build --manifest MANIFEST.yaml OUTPUT.ler [OPTIONS]
|
|
541
|
+
----
|
|
542
|
+
|
|
543
|
+
.Example: Building from a manifest
|
|
544
|
+
[example]
|
|
545
|
+
====
|
|
546
|
+
[source,bash]
|
|
547
|
+
----
|
|
548
|
+
expressir package build \
|
|
549
|
+
--manifest activity_manifest.yaml \
|
|
550
|
+
activity.ler \
|
|
551
|
+
--name "Activity Module" \
|
|
552
|
+
--validate
|
|
553
|
+
----
|
|
554
|
+
|
|
555
|
+
Output:
|
|
556
|
+
----
|
|
557
|
+
Building LER package from manifest activity_manifest.yaml...
|
|
558
|
+
Warnings:
|
|
559
|
+
- Schema 'the' has no path specified - please provide path
|
|
560
|
+
- Schema 'main' has no path specified - please provide path
|
|
561
|
+
Using 42 schema(s) from manifest
|
|
562
|
+
Building repository...
|
|
563
|
+
Creating package...
|
|
564
|
+
✓ Package created: activity.ler
|
|
565
|
+
Schemas: 42
|
|
566
|
+
----
|
|
567
|
+
====
|
|
568
|
+
|
|
569
|
+
===== Complete Manifest Workflow
|
|
570
|
+
|
|
571
|
+
.Step-by-step manifest workflow
|
|
572
|
+
[example]
|
|
573
|
+
====
|
|
574
|
+
[source,bash]
|
|
575
|
+
----
|
|
576
|
+
# Step 1: Create initial manifest
|
|
577
|
+
expressir manifest create schemas/activity/mim.exp \
|
|
578
|
+
-o activity_manifest.yaml \
|
|
579
|
+
--base-dirs ~/iso-10303/schemas \
|
|
580
|
+
--name "Activity Module" \
|
|
581
|
+
--verbose
|
|
582
|
+
|
|
583
|
+
# Step 2: Edit manifest to add missing schema paths
|
|
584
|
+
# (Use your text editor to add path: for unresolved schemas)
|
|
585
|
+
|
|
586
|
+
# Step 3: Validate the edited manifest
|
|
587
|
+
expressir manifest validate activity_manifest.yaml --verbose
|
|
588
|
+
|
|
589
|
+
# Step 4: Build package from manifest
|
|
590
|
+
expressir package build \
|
|
591
|
+
--manifest activity_manifest.yaml \
|
|
592
|
+
activity.ler \
|
|
593
|
+
--validate
|
|
594
|
+
----
|
|
595
|
+
====
|
|
596
|
+
|
|
597
|
+
===== Manifest vs Auto-Resolution
|
|
598
|
+
|
|
599
|
+
.Comparison of approaches
|
|
600
|
+
[cols="1,2,2"]
|
|
601
|
+
|===
|
|
602
|
+
| Feature | Manifest | Auto-Resolution
|
|
603
|
+
|
|
604
|
+
| **Control**
|
|
605
|
+
| Full manual control over schemas
|
|
606
|
+
| Automatic dependency discovery
|
|
607
|
+
|
|
608
|
+
| **Reproducibility**
|
|
609
|
+
| Guaranteed identical builds
|
|
610
|
+
| May vary with file system changes
|
|
611
|
+
|
|
612
|
+
| **Setup**
|
|
613
|
+
| Requires manifest creation step
|
|
614
|
+
| Works immediately
|
|
615
|
+
|
|
616
|
+
| **Missing schemas**
|
|
617
|
+
| Pre-check with validation
|
|
618
|
+
| Fails during build
|
|
619
|
+
|
|
620
|
+
| **Circular deps**
|
|
621
|
+
| Explicitly listed and resolved
|
|
622
|
+
| Handled automatically
|
|
623
|
+
|
|
624
|
+
| **Debugging**
|
|
625
|
+
| Easy to see what's included
|
|
626
|
+
| Requires --verbose flag
|
|
627
|
+
|
|
628
|
+
| **Use case**
|
|
629
|
+
| Complex projects, production
|
|
630
|
+
| Simple projects, development
|
|
631
|
+
|===
|
|
632
|
+
|
|
633
|
+
**Recommendation**: Use manifests for production builds and complex schemas. Use auto-resolution for development and simple projects.
|
|
634
|
+
|
|
635
|
+
===== Handling Circular Dependencies
|
|
636
|
+
|
|
637
|
+
EXPRESS allows schema-level circular dependencies (e.g., `measure_schema` and `representation_schema` referencing each other). The manifest system handles these correctly:
|
|
638
|
+
|
|
639
|
+
[source]
|
|
640
|
+
----
|
|
641
|
+
Looking for: measure_schema.exp
|
|
642
|
+
├─ Finds: representation_schema.exp (depends on measure_schema)
|
|
643
|
+
│ └─ Circular reference detected: measure_schema (skipping, valid)
|
|
644
|
+
└─ Both schemas included in manifest
|
|
645
|
+
----
|
|
646
|
+
|
|
647
|
+
The `--verbose` flag shows these circular references:
|
|
648
|
+
----
|
|
649
|
+
Circular reference detected: measure_schema (valid schema-level circular dependency, skipping)
|
|
650
|
+
----
|
|
651
|
+
|
|
652
|
+
This is **not an error** - it's normal EXPRESS behavior and both schemas will be included.
|
|
653
|
+
|
|
654
|
+
=== Using a Package
|
|
655
|
+
|
|
656
|
+
==== Via CLI
|
|
657
|
+
|
|
658
|
+
[source,bash]
|
|
659
|
+
----
|
|
660
|
+
# Get package information
|
|
661
|
+
expressir package info output.ler
|
|
662
|
+
|
|
663
|
+
# List all entities
|
|
664
|
+
expressir package list output.ler
|
|
665
|
+
|
|
666
|
+
# Search for specific entity
|
|
667
|
+
expressir package search output.ler "action"
|
|
668
|
+
|
|
669
|
+
# Validate package
|
|
670
|
+
expressir package validate output.ler
|
|
671
|
+
----
|
|
672
|
+
|
|
673
|
+
==== Via Ruby API
|
|
674
|
+
|
|
675
|
+
[source,ruby]
|
|
676
|
+
----
|
|
677
|
+
# Load package
|
|
678
|
+
repo = Expressir::Model::Repository.from_package('output.ler')
|
|
679
|
+
|
|
680
|
+
# Instant access to schemas
|
|
681
|
+
puts "Loaded #{repo.schemas.size} schemas"
|
|
682
|
+
|
|
683
|
+
# Fast entity lookup
|
|
684
|
+
entity = repo.find_entity(qualified_name: "schema.entity")
|
|
685
|
+
|
|
686
|
+
# Get statistics
|
|
687
|
+
stats = repo.statistics
|
|
688
|
+
puts "Total entities: #{stats[:total_entities]}"
|
|
689
|
+
----
|
|
690
|
+
|
|
691
|
+
=== Best Practices
|
|
692
|
+
|
|
693
|
+
**Version your packages**::
|
|
694
|
+
Include meaningful version numbers in metadata
|
|
695
|
+
|
|
696
|
+
**Validate before packaging**::
|
|
697
|
+
Use `--validate` flag to catch errors early
|
|
698
|
+
|
|
699
|
+
**Choose appropriate format**::
|
|
700
|
+
Use `marshal` for production, `yaml` for debugging
|
|
701
|
+
|
|
702
|
+
**Include metadata**::
|
|
703
|
+
Add name, version, and description for tracking
|
|
704
|
+
|
|
705
|
+
**Document dependencies**::
|
|
706
|
+
Note which schemas are intentionally external
|
|
707
|
+
|
|
708
|
+
**Test packages**::
|
|
709
|
+
Verify packages load correctly in target environment
|
|
710
|
+
|
|
711
|
+
=== Common Use Cases
|
|
712
|
+
|
|
713
|
+
==== Application Distribution
|
|
714
|
+
|
|
715
|
+
Package schemas with your application:
|
|
716
|
+
|
|
717
|
+
[source,ruby]
|
|
718
|
+
----
|
|
719
|
+
# In your application
|
|
720
|
+
SCHEMA_PACKAGE = File.expand_path('../data/schemas.ler', __dir__)
|
|
721
|
+
@repo = Expressir::Model::Repository.from_package(SCHEMA_PACKAGE)
|
|
722
|
+
----
|
|
723
|
+
|
|
724
|
+
==== Schema Registry
|
|
725
|
+
|
|
726
|
+
Build a registry of standard schemas:
|
|
727
|
+
|
|
728
|
+
[source]
|
|
729
|
+
----
|
|
730
|
+
registry/
|
|
731
|
+
├── iso-10303-41.ler
|
|
732
|
+
├── iso-10303-42.ler
|
|
733
|
+
├── iso-10303-203.ler
|
|
734
|
+
└── iso-10303-214.ler
|
|
735
|
+
----
|
|
736
|
+
|
|
737
|
+
==== Documentation Generation
|
|
738
|
+
|
|
739
|
+
Pre-package schemas for documentation tools:
|
|
740
|
+
|
|
741
|
+
[source,bash]
|
|
742
|
+
----
|
|
743
|
+
# Build documentation package
|
|
744
|
+
expressir package build standard.exp docs.ler
|
|
745
|
+
|
|
746
|
+
# Use in documentation generator
|
|
747
|
+
ruby generate_docs.rb --package docs.ler --output docs/
|
|
748
|
+
----
|
|
749
|
+
|
|
750
|
+
==== API Services
|
|
751
|
+
|
|
752
|
+
Serve schema information via API:
|
|
753
|
+
|
|
754
|
+
[source,ruby]
|
|
755
|
+
----
|
|
756
|
+
# Load once at startup
|
|
757
|
+
SCHEMAS = Expressir::Model::Repository.from_package('api.ler')
|
|
758
|
+
|
|
759
|
+
# Fast queries in requests
|
|
760
|
+
get '/entities/:name' do
|
|
761
|
+
entity = SCHEMAS.find_entity(qualified_name: params[:name])
|
|
762
|
+
entity.to_json
|
|
763
|
+
end
|
|
764
|
+
----
|
|
765
|
+
|
|
766
|
+
=== Troubleshooting
|
|
767
|
+
|
|
768
|
+
==== Package Won't Load
|
|
769
|
+
|
|
770
|
+
**Symptom**: Error loading `.ler` file
|
|
771
|
+
|
|
772
|
+
**Causes**:
|
|
773
|
+
|
|
774
|
+
* Corrupted ZIP file
|
|
775
|
+
* Incompatible Expressir version
|
|
776
|
+
* Missing dependencies
|
|
777
|
+
|
|
778
|
+
**Solutions**:
|
|
779
|
+
|
|
780
|
+
* Validate package: `expressir package validate file.ler`
|
|
781
|
+
* Rebuild package with current Expressir version
|
|
782
|
+
* Check file integrity
|
|
783
|
+
|
|
784
|
+
==== Slow Loading
|
|
785
|
+
|
|
786
|
+
**Symptom**: Package loads slower than expected
|
|
787
|
+
|
|
788
|
+
**Causes**:
|
|
789
|
+
|
|
790
|
+
* Using `bare` resolution mode
|
|
791
|
+
* Using `yaml` or `json` format
|
|
792
|
+
* Very large package (100+ schemas)
|
|
793
|
+
|
|
794
|
+
**Solutions**:
|
|
795
|
+
|
|
796
|
+
* Use `resolved` mode and `marshal` format
|
|
797
|
+
* Split into multiple packages
|
|
798
|
+
* Ensure solid-state storage
|
|
799
|
+
|
|
800
|
+
==== Missing Schemas
|
|
801
|
+
|
|
802
|
+
**Symptom**: Can't find expected schemas in package
|
|
803
|
+
|
|
804
|
+
**Causes**:
|
|
805
|
+
|
|
806
|
+
* Schema not referenced in dependency chain
|
|
807
|
+
* Incorrect base path during build
|
|
808
|
+
* Schema file not found during build
|
|
809
|
+
|
|
810
|
+
**Solutions**:
|
|
811
|
+
|
|
812
|
+
* Check build output for warnings
|
|
813
|
+
* Verify schema paths
|
|
814
|
+
* Use `--verbose` flag
|
|
815
|
+
|
|
816
|
+
=== Next Steps
|
|
817
|
+
|
|
818
|
+
Now that you understand LER packages:
|
|
819
|
+
|
|
820
|
+
**Create your first package**::
|
|
821
|
+
link:../tutorials/creating-ler-package.html[Follow the tutorial]
|
|
822
|
+
|
|
823
|
+
**Learn all CLI commands**::
|
|
824
|
+
link:../guides/ler/[Explore LER guides]
|
|
825
|
+
|
|
826
|
+
**Use in applications**::
|
|
827
|
+
link:../guides/ruby-api/[Read Ruby API documentation]
|
|
828
|
+
|
|
829
|
+
**Optimize performance**::
|
|
830
|
+
link:../guides/cli/benchmark-performance.html[Benchmark your packages]
|
|
831
|
+
|
|
832
|
+
=== Bibliography
|
|
833
|
+
|
|
834
|
+
* link:../guides/ler/[LER Guides] - Comprehensive usage guides
|
|
835
|
+
* link:../references/ler-format.html[LER Format Specification] - Technical details
|
|
836
|
+
* link:parsers.html[Parsers] - Understanding what gets packaged
|
|
837
|
+
* link:data-model.html[Data Model] - Understanding package contents
|