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,748 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Package Formats
|
|
3
|
+
parent: LER Packages
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Package Formats
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
This guide explains the different serialization formats available for LER
|
|
13
|
+
packages and helps you choose the right format for your use case. Understanding
|
|
14
|
+
format trade-offs is essential for optimizing performance and compatibility.
|
|
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:validating-packages.html[Validating Packages]
|
|
22
|
+
|
|
23
|
+
== Concepts
|
|
24
|
+
|
|
25
|
+
Serialization format:: The method used to convert repository objects into
|
|
26
|
+
stored data: `marshal` (binary), `yaml` (text), or `json` (text).
|
|
27
|
+
|
|
28
|
+
Marshal format:: Ruby's native binary serialization format providing maximum
|
|
29
|
+
speed and minimum size.
|
|
30
|
+
|
|
31
|
+
YAML format:: Human-readable text format using YAML syntax for debugging and
|
|
32
|
+
portability.
|
|
33
|
+
|
|
34
|
+
JSON format:: Human-readable text format using JSON syntax for maximum tool
|
|
35
|
+
compatibility.
|
|
36
|
+
|
|
37
|
+
== Available formats
|
|
38
|
+
|
|
39
|
+
LER packages support three serialization formats configured via the
|
|
40
|
+
[`serialization_format`](../../lib/expressir/package/builder.rb:65) option:
|
|
41
|
+
|
|
42
|
+
=== Marshal (default)
|
|
43
|
+
|
|
44
|
+
Binary serialization using Ruby's native [`Marshal`](https://ruby-doc.org/core/Marshal.html)
|
|
45
|
+
format.
|
|
46
|
+
|
|
47
|
+
.Characteristics
|
|
48
|
+
[example]
|
|
49
|
+
====
|
|
50
|
+
* **Speed**: Fastest loading (5-10x faster than YAML)
|
|
51
|
+
* **Size**: Most compact (40-60% of YAML size)
|
|
52
|
+
* **Portability**: Ruby-only (not language-independent)
|
|
53
|
+
* **Readability**: Binary (not human-readable)
|
|
54
|
+
* **Compatibility**: Ruby version dependent
|
|
55
|
+
====
|
|
56
|
+
|
|
57
|
+
.Best for
|
|
58
|
+
[example]
|
|
59
|
+
====
|
|
60
|
+
* Production deployments
|
|
61
|
+
* Performance-critical applications
|
|
62
|
+
* Ruby-only environments
|
|
63
|
+
* Large schema collections
|
|
64
|
+
* Frequent loading scenarios
|
|
65
|
+
====
|
|
66
|
+
|
|
67
|
+
=== YAML
|
|
68
|
+
|
|
69
|
+
Text serialization using YAML (YAML Ain't Markup Language) format.
|
|
70
|
+
|
|
71
|
+
.Characteristics
|
|
72
|
+
[example]
|
|
73
|
+
====
|
|
74
|
+
* **Speed**: Slower than Marshal (~4x slower)
|
|
75
|
+
* **Size**: Larger than Marshal (~2.5x larger)
|
|
76
|
+
* **Portability**: Language-independent text format
|
|
77
|
+
* **Readability**: Human-readable and editable
|
|
78
|
+
* **Compatibility**: Wide tool support
|
|
79
|
+
====
|
|
80
|
+
|
|
81
|
+
.Best for
|
|
82
|
+
[example]
|
|
83
|
+
====
|
|
84
|
+
* Development and debugging
|
|
85
|
+
* Manual inspection required
|
|
86
|
+
* Cross-language compatibility needed
|
|
87
|
+
* Version control friendly format
|
|
88
|
+
* Incremental changes tracking
|
|
89
|
+
====
|
|
90
|
+
|
|
91
|
+
=== JSON
|
|
92
|
+
|
|
93
|
+
Text serialization using JSON (JavaScript Object Notation) format.
|
|
94
|
+
|
|
95
|
+
.Characteristics
|
|
96
|
+
[example]
|
|
97
|
+
====
|
|
98
|
+
* **Speed**: Similar to YAML (~3x slower than Marshal)
|
|
99
|
+
* **Size**: Similar to YAML (~2.3x larger than Marshal)
|
|
100
|
+
* **Portability**: Universal language support
|
|
101
|
+
* **Readability**: Human-readable, parseable by many tools
|
|
102
|
+
* **Compatibility**: Maximum tool ecosystem
|
|
103
|
+
====
|
|
104
|
+
|
|
105
|
+
.Best for
|
|
106
|
+
[example]
|
|
107
|
+
====
|
|
108
|
+
* Web application integration
|
|
109
|
+
* JavaScript/Node.js environments
|
|
110
|
+
* REST API responses
|
|
111
|
+
* Maximum compatibility
|
|
112
|
+
* Tool interoperability
|
|
113
|
+
====
|
|
114
|
+
|
|
115
|
+
== Format comparison
|
|
116
|
+
|
|
117
|
+
=== Performance comparison
|
|
118
|
+
|
|
119
|
+
Based on a 100-schema repository benchmark:
|
|
120
|
+
|
|
121
|
+
[options="header"]
|
|
122
|
+
|===
|
|
123
|
+
| Format | Build Time | Load Time | File Size | Relative Speed
|
|
124
|
+
|
|
125
|
+
| Marshal
|
|
126
|
+
| 12.3s
|
|
127
|
+
| 1.8s
|
|
128
|
+
| 8.2 MB
|
|
129
|
+
| 1.0x (baseline)
|
|
130
|
+
|
|
131
|
+
| JSON
|
|
132
|
+
| 15.7s
|
|
133
|
+
| 5.9s
|
|
134
|
+
| 19.1 MB
|
|
135
|
+
| 0.30x (3.3x slower)
|
|
136
|
+
|
|
137
|
+
| YAML
|
|
138
|
+
| 16.2s
|
|
139
|
+
| 7.4s
|
|
140
|
+
| 20.5 MB
|
|
141
|
+
| 0.24x (4.1x slower)
|
|
142
|
+
|===
|
|
143
|
+
|
|
144
|
+
.Key findings
|
|
145
|
+
[example]
|
|
146
|
+
====
|
|
147
|
+
* Marshal loads 3-4x faster than text formats
|
|
148
|
+
* Marshal produces 55-60% smaller files
|
|
149
|
+
* YAML and JSON have similar performance
|
|
150
|
+
* Build time differences are less significant
|
|
151
|
+
====
|
|
152
|
+
|
|
153
|
+
=== Size comparison
|
|
154
|
+
|
|
155
|
+
Typical size ratios for the same repository:
|
|
156
|
+
|
|
157
|
+
[source]
|
|
158
|
+
----
|
|
159
|
+
Marshal (baseline): 8.2 MB (100%)
|
|
160
|
+
JSON: 19.1 MB (233%)
|
|
161
|
+
YAML: 20.5 MB (250%)
|
|
162
|
+
----
|
|
163
|
+
|
|
164
|
+
After ZIP compression (LER packages are ZIP archives):
|
|
165
|
+
|
|
166
|
+
[source]
|
|
167
|
+
----
|
|
168
|
+
Marshal compressed: 1.2 MB (100%)
|
|
169
|
+
JSON compressed: 2.8 MB (233%)
|
|
170
|
+
YAML compressed: 3.1 MB (258%)
|
|
171
|
+
----
|
|
172
|
+
|
|
173
|
+
.Compression analysis
|
|
174
|
+
[example]
|
|
175
|
+
====
|
|
176
|
+
* All formats benefit from ZIP compression
|
|
177
|
+
* Marshal maintains size advantage even compressed
|
|
178
|
+
* Text formats compress well but start larger
|
|
179
|
+
* Compression reduces absolute differences
|
|
180
|
+
====
|
|
181
|
+
|
|
182
|
+
=== Compatibility comparison
|
|
183
|
+
|
|
184
|
+
[options="header"]
|
|
185
|
+
|===
|
|
186
|
+
| Feature | Marshal | YAML | JSON
|
|
187
|
+
|
|
188
|
+
| Ruby support
|
|
189
|
+
| ✓ Native
|
|
190
|
+
| ✓ Via gem
|
|
191
|
+
| ✓ Via gem
|
|
192
|
+
|
|
193
|
+
| Python support
|
|
194
|
+
| ✗
|
|
195
|
+
| ✓
|
|
196
|
+
| ✓
|
|
197
|
+
|
|
198
|
+
| JavaScript support
|
|
199
|
+
| ✗
|
|
200
|
+
| ✓
|
|
201
|
+
| ✓ Native
|
|
202
|
+
|
|
203
|
+
| Human readable
|
|
204
|
+
| ✗
|
|
205
|
+
| ✓
|
|
206
|
+
| ✓
|
|
207
|
+
|
|
208
|
+
| Diff friendly
|
|
209
|
+
| ✗
|
|
210
|
+
| ✓
|
|
211
|
+
| ✓
|
|
212
|
+
|
|
213
|
+
| Binary safe
|
|
214
|
+
| ✓
|
|
215
|
+
| ✓
|
|
216
|
+
| ✗
|
|
217
|
+
|
|
218
|
+
| Version control
|
|
219
|
+
| Poor
|
|
220
|
+
| Good
|
|
221
|
+
| Good
|
|
222
|
+
|
|
223
|
+
| Tool ecosystem
|
|
224
|
+
| Limited
|
|
225
|
+
| Wide
|
|
226
|
+
| Widest
|
|
227
|
+
|===
|
|
228
|
+
|
|
229
|
+
== Choosing the right format
|
|
230
|
+
|
|
231
|
+
=== Decision tree
|
|
232
|
+
|
|
233
|
+
[source]
|
|
234
|
+
----
|
|
235
|
+
Need maximum performance?
|
|
236
|
+
├─ YES → Use Marshal
|
|
237
|
+
└─ NO
|
|
238
|
+
└─ Need human readability?
|
|
239
|
+
├─ YES → Need JavaScript compatibility?
|
|
240
|
+
│ ├─ YES → Use JSON
|
|
241
|
+
│ └─ NO → Use YAML
|
|
242
|
+
└─ NO → Use Marshal
|
|
243
|
+
----
|
|
244
|
+
|
|
245
|
+
=== By use case
|
|
246
|
+
|
|
247
|
+
==== Production deployment
|
|
248
|
+
|
|
249
|
+
.Recommended: Marshal
|
|
250
|
+
[example]
|
|
251
|
+
====
|
|
252
|
+
[source,bash]
|
|
253
|
+
----
|
|
254
|
+
expressir package build schemas/ production.ler \
|
|
255
|
+
--serialization-format marshal
|
|
256
|
+
----
|
|
257
|
+
|
|
258
|
+
**Rationale**: Performance is critical, human readability not needed.
|
|
259
|
+
====
|
|
260
|
+
|
|
261
|
+
==== Development and debugging
|
|
262
|
+
|
|
263
|
+
.Recommended: YAML
|
|
264
|
+
[example]
|
|
265
|
+
====
|
|
266
|
+
[source,bash]
|
|
267
|
+
----
|
|
268
|
+
expressir package build schemas/ debug.ler \
|
|
269
|
+
--serialization-format yaml
|
|
270
|
+
----
|
|
271
|
+
|
|
272
|
+
**Rationale**: Can inspect and debug serialized content easily.
|
|
273
|
+
====
|
|
274
|
+
|
|
275
|
+
==== Web application integration
|
|
276
|
+
|
|
277
|
+
.Recommended: JSON
|
|
278
|
+
[example]
|
|
279
|
+
====
|
|
280
|
+
[source,bash]
|
|
281
|
+
----
|
|
282
|
+
expressir package build schemas/ webapp.ler \
|
|
283
|
+
--serialization-format json
|
|
284
|
+
----
|
|
285
|
+
|
|
286
|
+
**Rationale**: JavaScript tools can parse JSON directly.
|
|
287
|
+
====
|
|
288
|
+
|
|
289
|
+
==== Cross-language projects
|
|
290
|
+
|
|
291
|
+
.Recommended: JSON or YAML
|
|
292
|
+
[example]
|
|
293
|
+
====
|
|
294
|
+
[source,bash]
|
|
295
|
+
----
|
|
296
|
+
# JSON for maximum compatibility
|
|
297
|
+
expressir package build schemas/ multi-lang.ler \
|
|
298
|
+
--serialization-format json
|
|
299
|
+
|
|
300
|
+
# YAML for better readability
|
|
301
|
+
expressir package build schemas/ multi-lang.ler \
|
|
302
|
+
--serialization-format yaml
|
|
303
|
+
----
|
|
304
|
+
|
|
305
|
+
**Rationale**: Need non-Ruby language support.
|
|
306
|
+
====
|
|
307
|
+
|
|
308
|
+
==== Version control tracking
|
|
309
|
+
|
|
310
|
+
.Recommended: YAML
|
|
311
|
+
[example]
|
|
312
|
+
====
|
|
313
|
+
[source,bash]
|
|
314
|
+
----
|
|
315
|
+
expressir package build schemas/ tracked.ler \
|
|
316
|
+
--serialization-format yaml
|
|
317
|
+
----
|
|
318
|
+
|
|
319
|
+
**Rationale**: YAML diffs are more readable than JSON.
|
|
320
|
+
====
|
|
321
|
+
|
|
322
|
+
==== Large schema collections
|
|
323
|
+
|
|
324
|
+
.Recommended: Marshal
|
|
325
|
+
[example]
|
|
326
|
+
====
|
|
327
|
+
[source,bash]
|
|
328
|
+
----
|
|
329
|
+
expressir package build large-schemas/ large.ler \
|
|
330
|
+
--serialization-format marshal
|
|
331
|
+
----
|
|
332
|
+
|
|
333
|
+
**Rationale**: Size and speed matter for large repositories.
|
|
334
|
+
====
|
|
335
|
+
|
|
336
|
+
== Working with different formats
|
|
337
|
+
|
|
338
|
+
=== Creating packages in each format
|
|
339
|
+
|
|
340
|
+
==== Marshal format
|
|
341
|
+
|
|
342
|
+
[source,ruby]
|
|
343
|
+
----
|
|
344
|
+
repo.export_to_package(
|
|
345
|
+
"output.ler",
|
|
346
|
+
serialization_format: "marshal"
|
|
347
|
+
)
|
|
348
|
+
----
|
|
349
|
+
|
|
350
|
+
==== YAML format
|
|
351
|
+
|
|
352
|
+
[source,ruby]
|
|
353
|
+
----
|
|
354
|
+
repo.export_to_package(
|
|
355
|
+
"output.ler",
|
|
356
|
+
serialization_format: "yaml"
|
|
357
|
+
)
|
|
358
|
+
----
|
|
359
|
+
|
|
360
|
+
==== JSON format
|
|
361
|
+
|
|
362
|
+
[source,ruby]
|
|
363
|
+
----
|
|
364
|
+
repo.export_to_package(
|
|
365
|
+
"output.ler",
|
|
366
|
+
serialization_format: "json"
|
|
367
|
+
)
|
|
368
|
+
----
|
|
369
|
+
|
|
370
|
+
=== Loading packages
|
|
371
|
+
|
|
372
|
+
Loading is automatic - format is detected from metadata:
|
|
373
|
+
|
|
374
|
+
[source,ruby]
|
|
375
|
+
----
|
|
376
|
+
# Works for any format
|
|
377
|
+
repo = Expressir::Model::Repository.from_package("any-format.ler")
|
|
378
|
+
----
|
|
379
|
+
|
|
380
|
+
The [`Package::Reader`](../../lib/expressir/package/reader.rb:63) automatically:
|
|
381
|
+
|
|
382
|
+
1. Reads metadata to determine format
|
|
383
|
+
2. Selects appropriate deserializer
|
|
384
|
+
3. Loads repository correctly
|
|
385
|
+
|
|
386
|
+
=== Inspecting package format
|
|
387
|
+
|
|
388
|
+
Check format before loading:
|
|
389
|
+
|
|
390
|
+
[source,bash]
|
|
391
|
+
----
|
|
392
|
+
expressir package info schemas.ler
|
|
393
|
+
----
|
|
394
|
+
|
|
395
|
+
Output includes:
|
|
396
|
+
|
|
397
|
+
[source]
|
|
398
|
+
----
|
|
399
|
+
Configuration
|
|
400
|
+
--------------------------------------------------
|
|
401
|
+
Serialization format: marshal
|
|
402
|
+
----
|
|
403
|
+
|
|
404
|
+
Or programmatically:
|
|
405
|
+
|
|
406
|
+
[source,ruby]
|
|
407
|
+
----
|
|
408
|
+
require "zip"
|
|
409
|
+
require "yaml"
|
|
410
|
+
|
|
411
|
+
Zip::File.open("schemas.ler") do |zip|
|
|
412
|
+
metadata_entry = zip.find_entry("metadata.yaml")
|
|
413
|
+
metadata = YAML.safe_load(metadata_entry.get_input_stream.read)
|
|
414
|
+
puts "Format: #{metadata['serialization_format']}"
|
|
415
|
+
end
|
|
416
|
+
----
|
|
417
|
+
|
|
418
|
+
== Migration between formats
|
|
419
|
+
|
|
420
|
+
=== Converting existing packages
|
|
421
|
+
|
|
422
|
+
Convert a package to different format:
|
|
423
|
+
|
|
424
|
+
[source,ruby]
|
|
425
|
+
----
|
|
426
|
+
# Load package (any format)
|
|
427
|
+
repo = Expressir::Model::Repository.from_package("old-format.ler")
|
|
428
|
+
|
|
429
|
+
# Export in new format
|
|
430
|
+
repo.export_to_package(
|
|
431
|
+
"new-format.ler",
|
|
432
|
+
serialization_format: "marshal" # or "yaml" or "json"
|
|
433
|
+
)
|
|
434
|
+
----
|
|
435
|
+
|
|
436
|
+
Complete conversion script:
|
|
437
|
+
|
|
438
|
+
[source,ruby]
|
|
439
|
+
----
|
|
440
|
+
#!/usr/bin/env ruby
|
|
441
|
+
require "expressir"
|
|
442
|
+
|
|
443
|
+
def convert_package(input, output, format)
|
|
444
|
+
puts "Converting #{input} to #{format}..."
|
|
445
|
+
|
|
446
|
+
# Load existing package
|
|
447
|
+
repo = Expressir::Model::Repository.from_package(input)
|
|
448
|
+
|
|
449
|
+
# Get original metadata
|
|
450
|
+
metadata = load_metadata(input)
|
|
451
|
+
|
|
452
|
+
# Export in new format
|
|
453
|
+
repo.export_to_package(
|
|
454
|
+
output,
|
|
455
|
+
name: metadata["name"],
|
|
456
|
+
version: metadata["version"],
|
|
457
|
+
description: metadata["description"],
|
|
458
|
+
serialization_format: format
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
# Compare sizes
|
|
462
|
+
old_size = File.size(input)
|
|
463
|
+
new_size = File.size(output)
|
|
464
|
+
reduction = ((old_size - new_size) / old_size.to_f * 100).round(1)
|
|
465
|
+
|
|
466
|
+
puts "✓ Converted successfully"
|
|
467
|
+
puts " Old size: #{old_size} bytes"
|
|
468
|
+
puts " New size: #{new_size} bytes"
|
|
469
|
+
puts " Change: #{reduction}%"
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def load_metadata(package_path)
|
|
473
|
+
require "zip"
|
|
474
|
+
require "yaml"
|
|
475
|
+
|
|
476
|
+
Zip::File.open(package_path) do |zip|
|
|
477
|
+
entry = zip.find_entry("metadata.yaml")
|
|
478
|
+
YAML.safe_load(entry.get_input_stream.read)
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
# Usage
|
|
483
|
+
convert_package("input.ler", "output.ler", "marshal")
|
|
484
|
+
----
|
|
485
|
+
|
|
486
|
+
=== Bulk conversion
|
|
487
|
+
|
|
488
|
+
Convert multiple packages:
|
|
489
|
+
|
|
490
|
+
[source,ruby]
|
|
491
|
+
----
|
|
492
|
+
def bulk_convert(input_dir, output_dir, format)
|
|
493
|
+
Dir.glob("#{input_dir}/**/*.ler").each do |input|
|
|
494
|
+
relative_path = input.sub(input_dir, "")
|
|
495
|
+
output = File.join(output_dir, relative_path)
|
|
496
|
+
|
|
497
|
+
FileUtils.mkdir_p(File.dirname(output))
|
|
498
|
+
|
|
499
|
+
puts "Converting #{relative_path}..."
|
|
500
|
+
convert_package(input, output, format)
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
# Convert all packages to Marshal
|
|
505
|
+
bulk_convert("packages/yaml/", "packages/marshal/", "marshal")
|
|
506
|
+
----
|
|
507
|
+
|
|
508
|
+
== Format-specific optimizations
|
|
509
|
+
|
|
510
|
+
=== Marshal optimization
|
|
511
|
+
|
|
512
|
+
Marshal format is already optimized, but consider:
|
|
513
|
+
|
|
514
|
+
[source,ruby]
|
|
515
|
+
----
|
|
516
|
+
# Ensure indexes are built before export
|
|
517
|
+
repo.build_indexes
|
|
518
|
+
|
|
519
|
+
# This pre-builds indexes in the package
|
|
520
|
+
repo.export_to_package(
|
|
521
|
+
"optimized.ler",
|
|
522
|
+
serialization_format: "marshal"
|
|
523
|
+
)
|
|
524
|
+
----
|
|
525
|
+
|
|
526
|
+
=== YAML optimization
|
|
527
|
+
|
|
528
|
+
Reduce YAML size with minimal formatting:
|
|
529
|
+
|
|
530
|
+
[source,ruby]
|
|
531
|
+
----
|
|
532
|
+
# Note: Expressir doesn't expose YAML options directly
|
|
533
|
+
# The dumper uses default settings
|
|
534
|
+
|
|
535
|
+
# For manual YAML generation:
|
|
536
|
+
require "yaml"
|
|
537
|
+
|
|
538
|
+
yaml_options = {
|
|
539
|
+
line_width: -1, # No line wrapping
|
|
540
|
+
indentation: 2
|
|
541
|
+
}
|
|
542
|
+
----
|
|
543
|
+
|
|
544
|
+
=== JSON optimization
|
|
545
|
+
|
|
546
|
+
JSON is naturally compact, but consider:
|
|
547
|
+
|
|
548
|
+
* Disable pretty printing for production
|
|
549
|
+
* Use compression aggressively
|
|
550
|
+
* Remove optional fields when possible
|
|
551
|
+
|
|
552
|
+
== Compatibility considerations
|
|
553
|
+
|
|
554
|
+
=== Ruby version compatibility
|
|
555
|
+
|
|
556
|
+
Marshal format is Ruby version dependent:
|
|
557
|
+
|
|
558
|
+
[source]
|
|
559
|
+
----
|
|
560
|
+
Ruby 2.7 Marshal → May not load in Ruby 3.2
|
|
561
|
+
Ruby 3.0 Marshal → Loads in Ruby 3.0+
|
|
562
|
+
Ruby 3.2 Marshal → Loads in Ruby 3.2+
|
|
563
|
+
----
|
|
564
|
+
|
|
565
|
+
.Best practice
|
|
566
|
+
[example]
|
|
567
|
+
====
|
|
568
|
+
For cross-version compatibility:
|
|
569
|
+
* Use YAML or JSON for long-term storage
|
|
570
|
+
* Use Marshal for same-version deployment
|
|
571
|
+
* Document Ruby version used to create Marshal packages
|
|
572
|
+
====
|
|
573
|
+
|
|
574
|
+
=== Expressir version compatibility
|
|
575
|
+
|
|
576
|
+
All formats are tied to Expressir version:
|
|
577
|
+
|
|
578
|
+
[source,ruby]
|
|
579
|
+
----
|
|
580
|
+
# Metadata includes version
|
|
581
|
+
{
|
|
582
|
+
"expressir_version": "0.7.0",
|
|
583
|
+
"serialization_format": "marshal"
|
|
584
|
+
}
|
|
585
|
+
----
|
|
586
|
+
|
|
587
|
+
.Compatibility matrix
|
|
588
|
+
[example]
|
|
589
|
+
====
|
|
590
|
+
[options="header"]
|
|
591
|
+
|===
|
|
592
|
+
| Package Version | Expressir 0.6.x | Expressir 0.7.x | Expressir 0.8.x
|
|
593
|
+
|
|
594
|
+
| 0.6.x
|
|
595
|
+
| ✓
|
|
596
|
+
| ✓ (with warnings)
|
|
597
|
+
| ?
|
|
598
|
+
|
|
599
|
+
| 0.7.x
|
|
600
|
+
| ✗
|
|
601
|
+
| ✓
|
|
602
|
+
| ✓ (likely)
|
|
603
|
+
|
|
604
|
+
| 0.8.x
|
|
605
|
+
| ✗
|
|
606
|
+
| ✗
|
|
607
|
+
| ✓
|
|
608
|
+
|===
|
|
609
|
+
====
|
|
610
|
+
|
|
611
|
+
=== Forward compatibility
|
|
612
|
+
|
|
613
|
+
Plan for future versions:
|
|
614
|
+
|
|
615
|
+
[source,ruby]
|
|
616
|
+
----
|
|
617
|
+
# Include version in package name
|
|
618
|
+
filename = "schemas-v#{Expressir::VERSION}.ler"
|
|
619
|
+
|
|
620
|
+
# Or in metadata description
|
|
621
|
+
repo.export_to_package(
|
|
622
|
+
"schemas.ler",
|
|
623
|
+
description: "Built with Expressir #{Expressir::VERSION}"
|
|
624
|
+
)
|
|
625
|
+
----
|
|
626
|
+
|
|
627
|
+
== Best practices
|
|
628
|
+
|
|
629
|
+
=== Format selection checklist
|
|
630
|
+
|
|
631
|
+
When choosing a format, consider:
|
|
632
|
+
|
|
633
|
+
- [ ] Is performance critical? → Marshal
|
|
634
|
+
- [ ] Need human readability? → YAML/JSON
|
|
635
|
+
- [ ] Need cross-language support? → JSON/YAML
|
|
636
|
+
- [ ] Is file size a concern? → Marshal
|
|
637
|
+
- [ ] Version control tracking? → YAML
|
|
638
|
+
- [ ] Web application integration? → JSON
|
|
639
|
+
- [ ] Long-term archival? → YAML/JSON
|
|
640
|
+
- [ ] Same Ruby version guaranteed? → Marshal
|
|
641
|
+
|
|
642
|
+
=== Multi-format strategy
|
|
643
|
+
|
|
644
|
+
Provide multiple formats for different needs:
|
|
645
|
+
|
|
646
|
+
[source,ruby]
|
|
647
|
+
----
|
|
648
|
+
# Build production format
|
|
649
|
+
repo.export_to_package(
|
|
650
|
+
"production/schemas.ler",
|
|
651
|
+
serialization_format: "marshal"
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
# Build debug format
|
|
655
|
+
repo.export_to_package(
|
|
656
|
+
"debug/schemas-debug.ler",
|
|
657
|
+
serialization_format: "yaml"
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
# Build API format
|
|
661
|
+
repo.export_to_package(
|
|
662
|
+
"api/schemas-api.ler",
|
|
663
|
+
serialization_format: "json"
|
|
664
|
+
)
|
|
665
|
+
----
|
|
666
|
+
|
|
667
|
+
=== Documentation
|
|
668
|
+
|
|
669
|
+
Document format choices:
|
|
670
|
+
|
|
671
|
+
[source,ruby]
|
|
672
|
+
----
|
|
673
|
+
repo.export_to_package(
|
|
674
|
+
"schemas.ler",
|
|
675
|
+
name: "Schema Package",
|
|
676
|
+
version: "1.0.0",
|
|
677
|
+
description: <<~DESC
|
|
678
|
+
Format: Marshal (binary)
|
|
679
|
+
Ruby version: #{RUBY_VERSION}
|
|
680
|
+
Expressir version: #{Expressir::VERSION}
|
|
681
|
+
Built: #{Time.now.iso8601}
|
|
682
|
+
Target: Production deployment
|
|
683
|
+
DESC,
|
|
684
|
+
serialization_format: "marshal"
|
|
685
|
+
)
|
|
686
|
+
----
|
|
687
|
+
|
|
688
|
+
== Next steps
|
|
689
|
+
|
|
690
|
+
* link:creating-packages.html[Creating Packages] - Build packages with chosen
|
|
691
|
+
format
|
|
692
|
+
* link:loading-packages.html[Loading Packages] - Load packages of any format
|
|
693
|
+
* link:index.html[LER Packages Overview] - Complete package documentation
|
|
694
|
+
|
|
695
|
+
== Summary
|
|
696
|
+
|
|
697
|
+
Key takeaways for package formats:
|
|
698
|
+
|
|
699
|
+
* Three formats available: Marshal, YAML, JSON
|
|
700
|
+
* Marshal is fastest and smallest (production)
|
|
701
|
+
* YAML is most readable (development)
|
|
702
|
+
* JSON has widest compatibility (integration)
|
|
703
|
+
* Format choice depends on use case
|
|
704
|
+
* Conversion between formats is straightforward
|
|
705
|
+
* Consider Ruby version compatibility with Marshal
|
|
706
|
+
* Use multiple formats for different purposes
|
|
707
|
+
|
|
708
|
+
Format selection summary:
|
|
709
|
+
|
|
710
|
+
[options="header"]
|
|
711
|
+
|===
|
|
712
|
+
| Use Case | Recommended Format | Reason
|
|
713
|
+
|
|
714
|
+
| Production
|
|
715
|
+
| Marshal
|
|
716
|
+
| Performance and size
|
|
717
|
+
|
|
718
|
+
| Development
|
|
719
|
+
| YAML
|
|
720
|
+
| Readability and debugging
|
|
721
|
+
|
|
722
|
+
| Web apps
|
|
723
|
+
| JSON
|
|
724
|
+
| JavaScript compatibility
|
|
725
|
+
|
|
726
|
+
| Archive
|
|
727
|
+
| YAML/JSON
|
|
728
|
+
| Long-term compatibility
|
|
729
|
+
|
|
730
|
+
| Cross-language
|
|
731
|
+
| JSON
|
|
732
|
+
| Universal support
|
|
733
|
+
|
|
734
|
+
| Large repos
|
|
735
|
+
| Marshal
|
|
736
|
+
| Size and speed
|
|
737
|
+
|===
|
|
738
|
+
|
|
739
|
+
Best practices:
|
|
740
|
+
|
|
741
|
+
* Default to Marshal for production
|
|
742
|
+
* Use YAML for development
|
|
743
|
+
* Document format choice and version
|
|
744
|
+
* Test packages after format changes
|
|
745
|
+
* Consider providing multiple formats
|
|
746
|
+
* Plan for version migration
|
|
747
|
+
* Monitor performance impacts
|
|
748
|
+
* Keep format consistent within deployment
|