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,921 @@
1
+ ---
2
+ title: Coverage Analysis
3
+ parent: CLI Guides
4
+ grand_parent: Guides
5
+ nav_order: 5
6
+ ---
7
+
8
+ == Coverage Analysis
9
+
10
+ === Purpose
11
+
12
+ The [`coverage`](../../../lib/expressir/commands/coverage.rb:1) command analyzes EXPRESS schemas to measure documentation coverage. It identifies which entities have remarks (documentation) and generates coverage reports in multiple formats, helping maintain high-quality documentation standards.
13
+
14
+ === References
15
+
16
+ * link:../../tutorials/documentation-coverage.html[Tutorial: Documentation Coverage]
17
+ * link:../../pages/express-language.html[EXPRESS Language Documentation]
18
+ * link:validate-schemas.html[Validate Schemas]
19
+
20
+ === Concepts
21
+
22
+ Documentation coverage:: Percentage of schema elements that have documentation remarks
23
+ Remark:: EXPRESS comment that documents an entity, attribute, or other schema element
24
+ Coverage report:: Detailed analysis showing documented vs undocumented elements
25
+ Entity types:: Categories of EXPRESS elements (ENTITY, TYPE, FUNCTION, etc.)
26
+ Exclusion patterns:: Filtering specific entity types from coverage calculations
27
+ Ignore files:: List of files to exclude from overall coverage statistics
28
+
29
+ === Basic Usage
30
+
31
+ ==== Analyze Single File
32
+
33
+ [source,bash]
34
+ ----
35
+ expressir coverage schema.exp
36
+ ----
37
+
38
+ Output:
39
+ [source]
40
+ ----
41
+ Processing file: schema.exp
42
+
43
+ EXPRESS Documentation Coverage
44
+ ==============================
45
+ [Entity coverage table showing files and undocumented entities]
46
+ [Overall statistics with coverage percentage]
47
+ ----
48
+
49
+ ==== Analyze Directory
50
+
51
+ [source,bash]
52
+ ----
53
+ # Analyze all .exp files in directory
54
+ expressir coverage schemas/
55
+ ----
56
+
57
+ Output shows progress bar and results:
58
+ [source]
59
+ ----
60
+ Processing directory: schemas/
61
+ Found 15 EXPRESS files to process
62
+ Processing files: [====] 100% [15/15]
63
+ [Coverage tables and statistics]
64
+ ----
65
+
66
+ ==== Analyze Schema Manifest
67
+
68
+ [source,bash]
69
+ ----
70
+ # Analyze schemas from YAML manifest
71
+ expressir coverage schemas.yml
72
+ ----
73
+
74
+ === Command Options
75
+
76
+ ==== Available Options
77
+
78
+ [options="header"]
79
+ |===
80
+ | Option | Description | Default
81
+
82
+ | `--format FORMAT`
83
+ | Output format: text, json, or yaml
84
+ | text
85
+
86
+ | `--output PATH`
87
+ | Save output to file (json/yaml only)
88
+ | stdout
89
+
90
+ | `--exclude TYPES`
91
+ | Comma-separated entity types to exclude
92
+ | none
93
+
94
+ | `--ignore-files PATH`
95
+ | YAML file with file patterns to ignore
96
+ | none
97
+
98
+ | `--help`, `-h`
99
+ | Display help message
100
+ | -
101
+ |===
102
+
103
+ ==== Format Option
104
+
105
+ [source,bash]
106
+ ----
107
+ # Human-readable text output (default)
108
+ expressir coverage schemas/ --format text
109
+
110
+ # JSON output for programmatic processing
111
+ expressir coverage schemas/ --format json
112
+
113
+ # YAML output
114
+ expressir coverage schemas/ --format yaml
115
+ ----
116
+
117
+ ==== Output Option
118
+
119
+ [source,bash]
120
+ ----
121
+ # Save JSON results to file
122
+ expressir coverage schemas/ --format json --output coverage_report.json
123
+
124
+ # Save YAML results to file
125
+ expressir coverage schemas/ --format yaml --output coverage_report.yaml
126
+ ----
127
+
128
+ ==== Exclude Option
129
+
130
+ [source,bash]
131
+ ----
132
+ # Exclude TYPE entities
133
+ expressir coverage schemas/ --exclude=TYPE
134
+
135
+ # Exclude multiple entity types
136
+ expressir coverage schemas/ --exclude=TYPE,CONSTANT,FUNCTION
137
+
138
+ # Exclude specific TYPE subtypes
139
+ expressir coverage schemas/ --exclude=TYPE:SELECT,TYPE:ENUMERATION
140
+
141
+ # Exclude inner functions
142
+ expressir coverage schemas/ --exclude=FUNCTION:INNER
143
+ ----
144
+
145
+ ==== Ignore Files Option
146
+
147
+ [source,bash]
148
+ ----
149
+ # Use ignore file list
150
+ expressir coverage schemas/ --ignore-files coverage_ignore.yml
151
+ ----
152
+
153
+ === Output Formats
154
+
155
+ ==== Text Format
156
+
157
+ Default human-readable format with tables:
158
+
159
+ [source,bash]
160
+ ----
161
+ expressir coverage schema.exp
162
+ ----
163
+
164
+ Output:
165
+ [source]
166
+ ----
167
+ EXPRESS Documentation Coverage
168
+ ==============================
169
+
170
+ ┌─────────────────────────────────────────────────────────────────┐
171
+ │ Entity coverage in file │
172
+ ├──────────────────┬─────────────────────────┬────────────────────┤
173
+ │ Filename │ Undocumented Entities │ Coverage % │
174
+ ├──────────────────┼─────────────────────────┼────────────────────┤
175
+ │ schema.exp │ ENTITY entity1, │ 75.0% │
176
+ │ │ TYPE type1 │ │
177
+ └──────────────────┴─────────────────────────┴────────────────────┘
178
+
179
+ ┌──────────────────────────────────────────────────────┐
180
+ │ Entity overall coverage │
181
+ ├─────────────────────────┬────────────────────────────┤
182
+ │ Metric │ Value │
183
+ ├─────────────────────────┼────────────────────────────┤
184
+ │ Coverage Percentage │ 75.0% │
185
+ │ Total Entities │ 100 │
186
+ │ Documented Entities │ 75 │
187
+ │ Undocumented Entities │ 25 │
188
+ └─────────────────────────┴────────────────────────────┘
189
+ ----
190
+
191
+ ==== JSON Format
192
+
193
+ Machine-readable structured output:
194
+
195
+ [source,bash]
196
+ ----
197
+ expressir coverage schemas/ --format json --output report.json
198
+ ----
199
+
200
+ Output structure:
201
+ [source,json]
202
+ ----
203
+ {
204
+ "overall": {
205
+ "coverage_percentage": 75.0,
206
+ "total_entities": 100,
207
+ "documented_entities": 75,
208
+ "undocumented_entities": 25
209
+ },
210
+ "files" [
211
+ {
212
+ "file": "schemas/action_schema.exp",
213
+ "file_basename": "action_schema.exp",
214
+ "directory": "schemas",
215
+ "ignored": false,
216
+ "coverage": 80.0,
217
+ "total": 50,
218
+ "documented": 40,
219
+ "undocumented": [
220
+ {
221
+ "type": "ENTITY",
222
+ "name": "undocumented_entity"
223
+ },
224
+ {
225
+ "type": "TYPE",
226
+ "name": "undocumented_type"
227
+ }
228
+ ]
229
+ }
230
+ ],
231
+ "directories": [
232
+ {
233
+ "directory": "schemas",
234
+ "total": 100,
235
+ "documented": 75,
236
+ "undocumented": 25,
237
+ "coverage": 75.0,
238
+ "files": 2
239
+ }
240
+ ]
241
+ }
242
+ ----
243
+
244
+ ==== YAML Format
245
+
246
+ YAML structured output:
247
+
248
+ [source,bash]
249
+ ----
250
+ expressir coverage schemas/ --format yaml --output report.yaml
251
+ ----
252
+
253
+ Output:
254
+ [source,yaml]
255
+ ----
256
+ overall:
257
+ coverage_percentage: 75.0
258
+ total_entities: 100
259
+ documented_entities: 75
260
+ undocumented_entities: 25
261
+ files:
262
+ - file: schemas/action_schema.exp
263
+ directory: schemas
264
+ coverage: 80.0
265
+ total: 50
266
+ documented: 40
267
+ undocumented:
268
+ - type: ENTITY
269
+ name: undocumented_entity
270
+ directories:
271
+ - directory: schemas
272
+ total: 100
273
+ documented: 75
274
+ coverage: 75.0
275
+ ----
276
+
277
+ === Entity Types
278
+
279
+ ==== Supported Entity Types
280
+
281
+ Coverage analysis checks all EXPRESS element types:
282
+
283
+ **Schema-level entities:**
284
+
285
+ `ENTITY`:: Entity definitions
286
+ `TYPE`:: Type definitions (supports subtype exclusion)
287
+ `CONSTANT`:: Constant definitions
288
+ `FUNCTION`:: Function definitions (supports INNER exclusion)
289
+ `PROCEDURE`:: Procedure definitions
290
+ `RULE`:: Rule definitions
291
+ `SUBTYPE_CONSTRAINT`:: Subtype constraint definitions
292
+ `INTERFACE`:: Interface definitions
293
+
294
+ **Nested entities:**
295
+
296
+ `ATTRIBUTE`:: Entity attributes
297
+ `DERIVED_ATTRIBUTE`:: Derived attributes
298
+ `INVERSE_ATTRIBUTE`:: Inverse attributes
299
+ `UNIQUE_RULE`:: Unique rules
300
+ `WHERE_RULE`:: Where rules
301
+ `PARAMETER`:: Function/procedure parameters
302
+ `VARIABLE`:: Local variables
303
+ `ENUMERATION_ITEM`:: Enumeration values
304
+ `INTERFACE_ITEM`:: Interface items
305
+ `INTERFACED_ITEM`:: Interfaced items
306
+ `SCHEMA_VERSION`:: Schema version
307
+ `SCHEMA_VERSION_ITEM`:: Version items
308
+
309
+ ==== TYPE Subtypes
310
+
311
+ For TYPE elements, you can exclude specific subtypes:
312
+
313
+ [source,bash]
314
+ ----
315
+ # Exclude SELECT types
316
+ expressir coverage schemas/ --exclude=TYPE:SELECT
317
+
318
+ # Exclude ENUMERATION types
319
+ expressir coverage schemas/ --exclude=TYPE:ENUMERATION
320
+
321
+ # Exclude multiple subtypes
322
+ expressir coverage schemas/ --exclude=TYPE:SELECT,TYPE:ENUMERATION
323
+ ----
324
+
325
+ Valid TYPE subtypes:
326
+
327
+ * `AGGREGATE` - Aggregate types
328
+ * `ARRAY` - Array types
329
+ * `BAG` - Bag types
330
+ * `BINARY` - Binary types
331
+ * `BOOLEAN` - Boolean types
332
+ * `ENUMERATION` - Enumeration types
333
+ * `GENERIC` - Generic types
334
+ * `GENERIC_ENTITY` - Generic entity types
335
+ * `INTEGER` - Integer types
336
+ * `LIST` - List types
337
+ * `LOGICAL` - Logical types
338
+ * `NUMBER` - Number types
339
+ * `REAL` - Real types
340
+ * `SELECT` - Select types
341
+ * `SET` - Set types
342
+ * `STRING` - String types
343
+
344
+ ==== FUNCTION Subtypes
345
+
346
+ For FUNCTION elements, you can exclude inner functions:
347
+
348
+ [source,bash]
349
+ ----
350
+ # Exclude inner functions (nested within other constructs)
351
+ expressir coverage schemas/ --exclude=FUNCTION:INNER
352
+ ----
353
+
354
+ This excludes functions nested within:
355
+ * Other functions
356
+ * Rules
357
+ * Procedures
358
+
359
+ === Exclusion Patterns
360
+
361
+ ==== Exclude Single Type
362
+
363
+ [source,bash]
364
+ ----
365
+ # Exclude all TYPE entities
366
+ expressir coverage schemas/ --exclude=TYPE
367
+ ----
368
+
369
+ ==== Exclude Multiple Types
370
+
371
+ [source,bash]
372
+ ----
373
+ # Exclude multiple types
374
+ expressir coverage schemas/ --exclude=TYPE,CONSTANT,PARAMETER
375
+ ----
376
+
377
+ ==== Exclude with Subtypes
378
+
379
+ [source,bash]
380
+ ----
381
+ # TYPE subtypes commonly excluded (ISO 10303 practice)
382
+ expressir coverage schemas/ --exclude=TYPE:SELECT,TYPE:ENUMERATION
383
+
384
+ # Exclude inner functions
385
+ expressir coverage schemas/ --exclude=FUNCTION:INNER
386
+
387
+ # Combine different exclusions
388
+ expressir coverage schemas/ --exclude=TYPE:SELECT,FUNCTION:INNER,PARAMETER
389
+ ----
390
+
391
+ ==== Common Exclusion Patterns
392
+
393
+ ISO 10303 Standards:
394
+ [source,bash]
395
+ ----
396
+ # ISO 10303 excludes SELECT and ENUMERATION
397
+ expressir coverage schemas/ --exclude=TYPE:SELECT,TYPE:ENUMERATION
398
+ ----
399
+
400
+ Internal Development:
401
+ [source,bash]
402
+ ----
403
+ # Focus on public API
404
+ expressir coverage schemas/ --exclude=PARAMETER,VARIABLE,FUNCTION:INNER
405
+ ----
406
+
407
+ === Ignore Files
408
+
409
+ ==== Create Ignore File
410
+
411
+ Create `coverage_ignore.yml`:
412
+
413
+ [source,yaml]
414
+ ----
415
+ # Exact file paths
416
+ - examples/test_schema.exp
417
+ - temp/temporary_schema.exp
418
+
419
+ # Glob patterns
420
+ - examples/*_test_*.exp
421
+ - legacy/old_*.exp
422
+ - temp/*.exp
423
+
424
+ # Recursive patterns
425
+ - schemas/**/test_*.exp
426
+ ----
427
+
428
+ ==== Use Ignore File
429
+
430
+ [source,bash]
431
+ ----
432
+ expressir coverage schemas/ --ignore-files coverage_ignore.yml
433
+ ----
434
+
435
+ ==== Ignore File Behavior
436
+
437
+ **Ignored files are:**
438
+ * Still processed and analyzed
439
+ * Marked with `ignored: true` flag in output
440
+ * Excluded from overall coverage percentage
441
+ * Listed in separate `ignored_files` section
442
+
443
+ **Example output with ignored files:**
444
+
445
+ [source,json]
446
+ ----
447
+ {
448
+ "overall": {
449
+ "coverage_percentage": 80.0,
450
+ "total_entities": 100,
451
+ "documented_entities": 80,
452
+ "undocumented_entities": 20,
453
+ "ignored_files_count": 2,
454
+ "ignored_entities_count": 15
455
+ },
456
+ "ignored_files": [
457
+ {
458
+ "file": "examples/test_schema.exp",
459
+ "matched_pattern": "examples/*_test_*.exp",
460
+ "coverage": 20.0,
461
+ "total": 10
462
+ }
463
+ ]
464
+ }
465
+ ----
466
+
467
+ === Use Cases
468
+
469
+ ==== Quality Assurance
470
+
471
+ Check documentation before release:
472
+
473
+ [source,bash]
474
+ ----
475
+ #!/bin/bash
476
+ # check-docs.sh
477
+
478
+ echo "Checking documentation coverage..."
479
+
480
+ # Run coverage analysis
481
+ expressir coverage schemas/ --format json --output coverage.json
482
+
483
+ # Extract coverage percentage
484
+ COVERAGE=$(jq '.overall.coverage_percentage' coverage.json)
485
+
486
+ echo "Current coverage: ${COVERAGE}%"
487
+
488
+ # Require minimum 80% coverage
489
+ if (( $(echo "$COVERAGE < 80" | bc -l) )); then
490
+ echo "❌ Coverage below 80%"
491
+ exit 1
492
+ fi
493
+
494
+ echo "✓ Coverage meets requirements"
495
+ ----
496
+
497
+ ==== Pre-commit Hook
498
+
499
+ Ensure documentation before committing:
500
+
501
+ [source,bash]
502
+ ----
503
+ #!/bin/bash
504
+ # .git/hooks/pre-commit
505
+
506
+ # Get staged .exp files
507
+ STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.exp$')
508
+
509
+ if [ -z "$STAGED" ]; then
510
+ exit 0
511
+ fi
512
+
513
+ echo "Checking documentation coverage..."
514
+
515
+ # Check coverage on staged files
516
+ for file in $STAGED; do
517
+ RESULT=$(expressir coverage "$file" --format json)
518
+ COVERAGE=$(echo "$RESULT" | jq '.overall.coverage_percentage')
519
+
520
+ if (( $(echo "$COVERAGE < 75" | bc -l) )); then
521
+ echo "❌ $file has ${COVERAGE}% coverage (minimum 75%)"
522
+ exit 1
523
+ fi
524
+ done
525
+
526
+ echo "✓ All files meet documentation requirements"
527
+ ----
528
+
529
+ ==== CI/CD Integration
530
+
531
+ GitHub Actions workflow:
532
+
533
+ [source,yaml]
534
+ ----
535
+ name: Documentation Coverage
536
+
537
+ on: [push, pull_request]
538
+
539
+ jobs:
540
+ coverage:
541
+ runs-on: ubuntu-latest
542
+ steps:
543
+ - uses: actions/checkout@v2
544
+
545
+ - name: Install Expressir
546
+ run: gem install expressir
547
+
548
+ - name: Check Coverage
549
+ run: |
550
+ expressir coverage schemas/ \
551
+ --exclude=TYPE:SELECT,TYPE:ENUMERATION \
552
+ --format json \
553
+ --output coverage.json
554
+
555
+ - name: Verify Coverage
556
+ run: |
557
+ COVERAGE=$(jq '.overall.coverage_percentage' coverage.json)
558
+ REQUIRED=80
559
+
560
+ echo "Coverage: ${COVERAGE}%"
561
+
562
+ if (( $(echo "$COVERAGE < $REQUIRED" | bc -l) )); then
563
+ echo "Coverage below ${REQUIRED}%"
564
+ exit 1
565
+ fi
566
+
567
+ - name: Upload Report
568
+ uses: actions/upload-artifact@v2
569
+ with:
570
+ name: coverage-report
571
+ path: coverage.json
572
+ ----
573
+
574
+ ==== Generate Coverage Badge
575
+
576
+ [source,bash]
577
+ ----
578
+ #!/bin/bash
579
+ # generate-badge.sh
580
+
581
+ # Get coverage
582
+ COVERAGE=$(expressir coverage schemas/ --format json | \
583
+ jq '.overall.coverage_percentage')
584
+
585
+ # Round to integer
586
+ COVERAGE_INT=${COVERAGE%.*}
587
+
588
+ # Determine color
589
+ if [ "$COVERAGE_INT" -ge 90 ]; then
590
+ COLOR="brightgreen"
591
+ elif [ "$COVERAGE_INT" -ge 75 ]; then
592
+ COLOR="green"
593
+ elif [ "$COVERAGE_INT" -ge 60 ]; then
594
+ COLOR="yellow"
595
+ else
596
+ COLOR="red"
597
+ fi
598
+
599
+ # Generate badge URL
600
+ BADGE_URL="https://img.shields.io/badge/docs-${COVERAGE_INT}%25-${COLOR}"
601
+
602
+ echo "Badge: $BADGE_URL"
603
+ echo "![Documentation](${BADGE_URL})" > coverage_badge.md
604
+ ----
605
+
606
+ ==== Track Coverage Over Time
607
+
608
+ [source,bash]
609
+ ----
610
+ #!/bin/bash
611
+ # track-coverage.sh
612
+
613
+ DATE=$(date +%Y%m%d)
614
+ REPORT_DIR="coverage_history"
615
+ mkdir -p "$REPORT_DIR"
616
+
617
+ # Generate coverage report with timestamp
618
+ expressir coverage schemas/ \
619
+ --exclude=TYPE:SELECT,TYPE:ENUMERATION \
620
+ --format json \
621
+ --output "${REPORT_DIR}/${DATE}_coverage.json"
622
+
623
+ # Extract key metrics
624
+ COVERAGE=$(jq '.overall.coverage_percentage' \
625
+ "${REPORT_DIR}/${DATE}_coverage.json")
626
+
627
+ # Append to history CSV
628
+ echo "${DATE},${COVERAGE}" >> coverage_history.csv
629
+
630
+ echo "Coverage recorded: ${COVERAGE}%"
631
+ ----
632
+
633
+ ==== Find Undocumented Elements
634
+
635
+ [source,bash]
636
+ ----
637
+ #!/bin/bash
638
+ # find-undocumented.sh
639
+
640
+ echo "Finding undocumented entities..."
641
+
642
+ # Get coverage report
643
+ expressir coverage schemas/ --format json > coverage.json
644
+
645
+ # Extract undocumented entities
646
+ jq -r '.files[] |
647
+ .undocumented[] |
648
+ "\(.type) \(.name) in \(.file)"' coverage.json | \
649
+ sort
650
+
651
+ echo ""
652
+ echo "Total undocumented:"
653
+ jq '.overall.undocumented_entities' coverage.json
654
+ ----
655
+
656
+ ==== Documentation Report
657
+
658
+ [source,bash]
659
+ ----
660
+ #!/bin/bash
661
+ # generate-doc-report.sh
662
+
663
+ echo "# Documentation Coverage Report" > report.md
664
+ echo "" >> report.md
665
+ echo "Generated: $(date)" >> report.md
666
+ echo "" >> report.md
667
+
668
+ # Get coverage data
669
+ expressir coverage schemas/ --format json > coverage.json
670
+
671
+ # Overall statistics
672
+ echo "## Overall Statistics" >> report.md
673
+ echo "" >> report.md
674
+ jq -r '.overall |
675
+ "- Coverage: \(.coverage_percentage)%\n" +
676
+ "- Total Entities: \(.total_entities)\n" +
677
+ "- Documented: \(.documented_entities)\n" +
678
+ "- Undocumented: \(.undocumented_entities)"' \
679
+ coverage.json >> report.md
680
+
681
+ echo "" >> report.md
682
+ echo "## Files Needing Attention" >> report.md
683
+ echo "" >> report.md
684
+
685
+ # Files below 80% coverage
686
+ jq -r '.files[] |
687
+ select(.coverage < 80) |
688
+ "- \(.file): \(.coverage)%"' \
689
+ coverage.json >> report.md
690
+
691
+ echo "Report generated: report.md"
692
+ ----
693
+
694
+ === Advanced Usage
695
+
696
+ ==== Combine with Other Checks
697
+
698
+ [source,bash]
699
+ ----
700
+ #!/bin/bash
701
+ # comprehensive-check.sh
702
+
703
+ echo "=== Validating Schemas ==="
704
+ expressir validate schemas/*.exp || exit 1
705
+
706
+ echo ""
707
+ echo "=== Checking Documentation ==="
708
+ expressir coverage schemas/ \
709
+ --exclude=TYPE:SELECT,TYPE:ENUMERATION \
710
+ --format json > coverage.json
711
+
712
+ COVERAGE=$(jq '.overall.coverage_percentage' coverage.json)
713
+
714
+ if (( $(echo "$COVERAGE < 80" | bc -l) )); then
715
+ echo "❌ Documentation coverage: ${COVERAGE}%"
716
+ exit 1
717
+ fi
718
+
719
+ echo "✓ Documentation coverage: ${COVERAGE}%"
720
+
721
+ echo ""
722
+ echo "=== All Checks Passed ==="
723
+ ----
724
+
725
+ ==== Multi-Project Coverage
726
+
727
+ [source,bash]
728
+ ----
729
+ #!/bin/bash
730
+ # multi-project-coverage.sh
731
+
732
+ PROJECTS=("project1" "project2" "project3")
733
+
734
+ echo "Multi-Project Coverage Report" > report.txt
735
+ echo "=============================" >> report.txt
736
+
737
+ for project in "${PROJECTS[@]}"; do
738
+ echo "" >> report.txt
739
+ echo "Project: $project" >> report.txt
740
+ echo "---------" >> report.txt
741
+
742
+ expressir coverage "$project/schemas" --format json > temp.json
743
+
744
+ COVERAGE=$(jq '.overall.coverage_percentage' temp.json)
745
+ TOTAL=$(jq '.overall.total_entities' temp.json)
746
+
747
+ echo "Coverage: ${COVERAGE}%" >> report.txt
748
+ echo "Entities: ${TOTAL}" >> report.txt
749
+
750
+ rm temp.json
751
+ done
752
+
753
+ cat report.txt
754
+ ----
755
+
756
+ ==== Selective Analysis
757
+
758
+ [source,bash]
759
+ ----
760
+ #!/bin/bash
761
+ # Check only public API files
762
+
763
+ PUBLIC_SCHEMAS=(
764
+ "schemas/public/action_schema.exp"
765
+ "schemas/public/product_schema.exp"
766
+ "schemas/public/geometry_schema.exp"
767
+ )
768
+
769
+ echo "Checking public API documentation..."
770
+
771
+ for schema in "${PUBLIC_SCHEMAS[@]}"; do
772
+ echo "Analyzing: $schema"
773
+ expressir coverage "$schema" --exclude=PARAMETER
774
+ done
775
+ ----
776
+
777
+ === Best Practices
778
+
779
+ **Set Coverage Targets**::
780
+ Define minimum coverage requirements
781
+ +
782
+ [source,bash]
783
+ ----
784
+ # Enforce 80% coverage
785
+ COVERAGE=$(expressir coverage schemas/ --format json | \
786
+ jq '.overall.coverage_percentage')
787
+ [ $(echo "$COVERAGE >= 80" | bc) -eq 1 ] || exit 1
788
+ ----
789
+
790
+ **Exclude Appropriately**::
791
+ Follow industry standards for exclusions
792
+ +
793
+ [source,bash]
794
+ ----
795
+ # ISO 10303 standard exclusions
796
+ expressir coverage schemas/ --exclude=TYPE:SELECT,TYPE:ENUMERATION
797
+ ----
798
+
799
+ **Track Over Time**::
800
+ Monitor coverage trends
801
+ +
802
+ [source,bash]
803
+ ----
804
+ # Daily coverage tracking
805
+ expressir coverage schemas/ --format json > \
806
+ "coverage_$(date +%Y%m%d).json"
807
+ ----
808
+
809
+ **Document Exclusions**::
810
+ Keep a record of why types are excluded
811
+ +
812
+ [source,bash]
813
+ ----
814
+ # README.md
815
+ ## Documentation Coverage
816
+ We exclude TYPE:SELECT and TYPE:ENUMERATION per ISO 10303 guidelines.
817
+ Current target: 80% coverage
818
+ ----
819
+
820
+ **Use Ignore Files Wisely**::
821
+ Only ignore test files and examples
822
+ +
823
+ [source,yaml]
824
+ ----
825
+ # coverage_ignore.yml
826
+ - examples/**/*.exp
827
+ - test/**/*.exp
828
+ - temp/**/*.exp
829
+ ----
830
+
831
+ **Integrate with CI/CD**::
832
+ Automate coverage checks in pipelines
833
+
834
+ **Generate Reports Regularly**::
835
+ Create human-readable documentation status reports
836
+
837
+ === Troubleshooting
838
+
839
+ ==== Coverage Not Calculating
840
+
841
+ **Problem**: Coverage shows 0% or incorrect value
842
+
843
+ **Solutions**:
844
+ * Check that files contain valid EXPRESS
845
+ * Ensure remarks are properly formatted
846
+ * Verify entity names match exactly
847
+ * Run validation first
848
+
849
+ ==== Slow Analysis
850
+
851
+ **Problem**: Coverage analysis takes too long
852
+
853
+ **Solutions**:
854
+ [source,bash]
855
+ ----
856
+ # Process files individually
857
+ for file in schemas/*.exp; do
858
+ expressir coverage "$file"
859
+ done
860
+
861
+ # Use manifest for better progress tracking
862
+ expressir coverage schemas.yml
863
+ ----
864
+
865
+ ==== Invalid Entity Type Error
866
+
867
+ **Problem**: "Invalid entity type" error
868
+
869
+ **Solution**:
870
+ [source,bash]
871
+ ----
872
+ # Check valid types
873
+ expressir coverage --help
874
+
875
+ # Use correct type name (all caps)
876
+ expressir coverage schemas/ --exclude=ENTITY,TYPE
877
+ ----
878
+
879
+ ==== Ignored Files Not Working
880
+
881
+ **Problem**: Files still included in coverage
882
+
883
+ **Debugging**:
884
+ [source,bash]
885
+ ----
886
+ # Check if patterns match
887
+ expressir coverage schemas/ \
888
+ --ignore-files coverage_ignore.yml \
889
+ --format json | \
890
+ jq '.ignored_files'
891
+ ----
892
+
893
+ === Next Steps
894
+
895
+ **Related Commands**::
896
+ * link:validate-schemas.html[Validate Schemas] - Ensure schema correctness
897
+ * link:format-schemas.html[Format Schemas] - Improve readability
898
+
899
+ **Advanced Topics**::
900
+ * link:../ruby-api/[Ruby API Guides] - Programmatic coverage analysis
901
+ * link:../../tutorials/documentation-coverage.html[Tutorial: Documentation Coverage]
902
+
903
+ **Automation**::
904
+ * link:../deployment/ci-cd-setup.html[CI/CD Setup] - Automated workflows
905
+ * Coverage enforcement policies
906
+ * Documentation badge generation
907
+
908
+ === Summary
909
+
910
+ The coverage command:
911
+
912
+ * ✅ Analyzes EXPRESS schema documentation
913
+ * ✅ Reports documented vs undocumented entities
914
+ * ✅ Supports multiple output formats (text, JSON, YAML)
915
+ * ✅ Allows entity type exclusions
916
+ * ✅ Handles file ignore patterns
917
+ * ✅ Integrates with CI/CD pipelines
918
+ * ✅ Tracks coverage over time
919
+ * ✅ Helps maintain documentation quality
920
+
921
+ Use coverage analysis regularly to ensure comprehensive documentation and maintain high-quality EXPRESS schemas.