expressir 2.1.21 → 2.1.23
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/.rubocop.yml +9 -9
- data/.rubocop_todo.yml +62 -50
- data/Gemfile +2 -2
- data/README.adoc +364 -7
- data/bin/rspec +2 -1
- data/docs/liquid_drops.adoc +1 -1
- data/expressir.gemspec +0 -2
- data/lib/expressir/benchmark.rb +6 -3
- data/lib/expressir/cli.rb +24 -11
- data/lib/expressir/commands/benchmark.rb +7 -16
- data/lib/expressir/commands/benchmark_cache.rb +9 -17
- data/lib/expressir/commands/coverage.rb +125 -55
- data/lib/expressir/coverage.rb +100 -26
- data/lib/expressir/express/cache.rb +2 -1
- data/lib/expressir/express/formatter.rb +54 -12
- data/lib/expressir/express/hyperlink_formatter.rb +2 -1
- data/lib/expressir/express/parser.rb +329 -112
- data/lib/expressir/express/schema_head_formatter.rb +2 -1
- data/lib/expressir/express/visitor.rb +114 -51
- data/lib/expressir/model/declarations/entity.rb +2 -1
- data/lib/expressir/model/declarations/informal_proposition_rule.rb +24 -0
- data/lib/expressir/model/declarations/rule.rb +2 -1
- data/lib/expressir/model/declarations/schema.rb +4 -1
- data/lib/expressir/model/declarations/type.rb +2 -1
- data/lib/expressir/model/identifier.rb +2 -1
- data/lib/expressir/model/literals/string.rb +2 -1
- data/lib/expressir/model/model_element.rb +84 -145
- data/lib/expressir/model/repository.rb +2 -1
- data/lib/expressir/schema_manifest.rb +150 -0
- data/lib/expressir/schema_manifest_entry.rb +17 -0
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +29 -12
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b862b81010dd9fcdfe17e323db319206a7cae0ee23bbc2f5fa67f2425902c45f
|
4
|
+
data.tar.gz: 1e18551038a0e7a0577e7017ca6404c6e0a6424473b969f2ed8d18469ee516fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb30354610152c62957729f35389ce727a58e1867701bd22728333459ff291851befa809ba3c7165d6da658a85a31f88603d7a48492c1a6bd5845b2a6df10c68
|
7
|
+
data.tar.gz: eb5a9690942e44db8fd304c77efa967e57919b2b5b25149b65abb3c870b6adb5667b94fa8e87ec3d78aab59a5dbf1006350054e5728fbe17e8372a196444bc26
|
data/.rubocop.yml
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require:
|
2
|
-
- rubocop-performance
|
3
|
-
|
4
1
|
inherit_from:
|
5
2
|
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
6
3
|
- .rubocop_todo.yml
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
plugins:
|
6
|
+
- rubocop-performance
|
7
|
+
- rubocop-rake
|
8
|
+
- rubocop-rspec
|
9
|
+
|
13
10
|
AllCops:
|
14
|
-
TargetRubyVersion:
|
11
|
+
TargetRubyVersion: 3.0
|
12
|
+
NewCops: enable
|
13
|
+
Exclude:
|
14
|
+
- 'vendor/**/*'
|
data/.rubocop_todo.yml
CHANGED
@@ -1,25 +1,17 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2025-
|
3
|
+
# on 2025-07-04 10:39:56 UTC using RuboCop version 1.77.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
10
|
-
# Configuration parameters: Severity, Include.
|
11
|
-
# Include: **/*.gemspec
|
12
|
-
Gemspec/RequiredRubyVersion:
|
13
|
-
Exclude:
|
14
|
-
- 'expressir.gemspec'
|
15
|
-
|
16
|
-
# Offense count: 2
|
9
|
+
# Offense count: 550
|
17
10
|
# This cop supports safe autocorrection (--autocorrect).
|
18
|
-
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
11
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
19
12
|
# URISchemes: http, https
|
20
13
|
Layout/LineLength:
|
21
|
-
|
22
|
-
- 'lib/expressir/express/parser.rb'
|
14
|
+
Enabled: false
|
23
15
|
|
24
16
|
# Offense count: 1
|
25
17
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
@@ -27,25 +19,6 @@ Lint/DuplicateBranch:
|
|
27
19
|
Exclude:
|
28
20
|
- 'lib/expressir/coverage.rb'
|
29
21
|
|
30
|
-
# Offense count: 1
|
31
|
-
# This cop supports safe autocorrection (--autocorrect).
|
32
|
-
Lint/ScriptPermission:
|
33
|
-
Exclude:
|
34
|
-
- 'update_yaml_fixtures.rb'
|
35
|
-
|
36
|
-
# Offense count: 3
|
37
|
-
Lint/ShadowingOuterLocalVariable:
|
38
|
-
Exclude:
|
39
|
-
- 'lib/expressir/express/visitor.rb'
|
40
|
-
|
41
|
-
# Offense count: 2
|
42
|
-
# This cop supports safe autocorrection (--autocorrect).
|
43
|
-
# Configuration parameters: AutoCorrect, IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
44
|
-
Lint/UnusedBlockArgument:
|
45
|
-
Exclude:
|
46
|
-
- 'lib/expressir/express/visitor.rb'
|
47
|
-
- 'spec/support/yaml_matchers.rb'
|
48
|
-
|
49
22
|
# Offense count: 2
|
50
23
|
# This cop supports safe autocorrection (--autocorrect).
|
51
24
|
# Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
@@ -55,7 +28,7 @@ Lint/UnusedMethodArgument:
|
|
55
28
|
- 'lib/expressir/express/cache.rb'
|
56
29
|
- 'lib/expressir/express/parser.rb'
|
57
30
|
|
58
|
-
# Offense count:
|
31
|
+
# Offense count: 79
|
59
32
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
60
33
|
Metrics/AbcSize:
|
61
34
|
Exclude:
|
@@ -74,11 +47,11 @@ Metrics/AbcSize:
|
|
74
47
|
- 'lib/expressir/model/declarations/schema.rb'
|
75
48
|
- 'lib/expressir/model/model_element.rb'
|
76
49
|
|
77
|
-
# Offense count:
|
78
|
-
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
50
|
+
# Offense count: 1
|
51
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
79
52
|
# AllowedMethods: refine
|
80
53
|
Metrics/BlockLength:
|
81
|
-
Max:
|
54
|
+
Max: 46
|
82
55
|
|
83
56
|
# Offense count: 56
|
84
57
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
@@ -95,10 +68,10 @@ Metrics/CyclomaticComplexity:
|
|
95
68
|
- 'lib/expressir/model/model_element.rb'
|
96
69
|
- 'spec/support/model_element_helper.rb'
|
97
70
|
|
98
|
-
# Offense count:
|
71
|
+
# Offense count: 105
|
99
72
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
100
73
|
Metrics/MethodLength:
|
101
|
-
Max:
|
74
|
+
Max: 106
|
102
75
|
|
103
76
|
# Offense count: 44
|
104
77
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
@@ -112,29 +85,68 @@ Metrics/PerceivedComplexity:
|
|
112
85
|
- 'lib/expressir/model/declarations/schema.rb'
|
113
86
|
- 'lib/expressir/model/model_element.rb'
|
114
87
|
|
115
|
-
# Offense count:
|
116
|
-
# Configuration parameters:
|
117
|
-
#
|
118
|
-
|
119
|
-
# AllowedMethods: is_a?
|
120
|
-
# MethodDefinitionMacros: define_method, define_singleton_method
|
121
|
-
Naming/PredicateName:
|
88
|
+
# Offense count: 135
|
89
|
+
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
|
90
|
+
# SupportedStyles: snake_case, camelCase
|
91
|
+
Naming/VariableName:
|
122
92
|
Exclude:
|
123
|
-
- '
|
124
|
-
- 'lib/expressir/coverage.rb'
|
93
|
+
- 'lib/expressir/express/visitor.rb'
|
125
94
|
|
126
95
|
# Offense count: 5
|
127
96
|
Performance/FixedSize:
|
128
97
|
Exclude:
|
129
98
|
- 'lib/expressir/express/formatter.rb'
|
130
99
|
|
100
|
+
# Offense count: 6
|
101
|
+
Performance/MapMethodChain:
|
102
|
+
Exclude:
|
103
|
+
- 'lib/expressir/commands/coverage.rb'
|
104
|
+
- 'spec/expressir/commands/coverage_ignore_files_spec.rb'
|
105
|
+
- 'spec/expressir/coverage_spec.rb'
|
106
|
+
|
107
|
+
# Offense count: 102
|
108
|
+
# Configuration parameters: CountAsOne.
|
109
|
+
RSpec/ExampleLength:
|
110
|
+
Max: 123
|
111
|
+
|
112
|
+
# Offense count: 14
|
113
|
+
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
114
|
+
RSpec/IndexedLet:
|
115
|
+
Exclude:
|
116
|
+
- 'spec/expressir/model/data_types/array_spec.rb'
|
117
|
+
- 'spec/expressir/model/data_types/bag_spec.rb'
|
118
|
+
- 'spec/expressir/model/data_types/binary_spec.rb'
|
119
|
+
- 'spec/expressir/model/data_types/real_spec.rb'
|
120
|
+
- 'spec/expressir/model/data_types/set_spec.rb'
|
121
|
+
- 'spec/expressir/model/data_types/string_spec.rb'
|
122
|
+
|
131
123
|
# Offense count: 1
|
132
|
-
|
124
|
+
RSpec/IteratedExpectation:
|
133
125
|
Exclude:
|
134
|
-
- '
|
126
|
+
- 'spec/expressir/schema_manifest_spec.rb'
|
127
|
+
|
128
|
+
# Offense count: 235
|
129
|
+
RSpec/MultipleExpectations:
|
130
|
+
Max: 114
|
131
|
+
|
132
|
+
# Offense count: 21
|
133
|
+
# Configuration parameters: AllowSubject.
|
134
|
+
RSpec/MultipleMemoizedHelpers:
|
135
|
+
Max: 13
|
136
|
+
|
137
|
+
# Offense count: 5
|
138
|
+
RSpec/PendingWithoutReason:
|
139
|
+
Exclude:
|
140
|
+
- 'spec/expressir/model/declarations/remark_item_spec.rb'
|
141
|
+
- 'spec/expressir/model/declarations/rule_spec.rb'
|
142
|
+
- 'spec/expressir/model/declarations/schema_spec.rb'
|
135
143
|
|
136
144
|
# Offense count: 2
|
137
|
-
|
138
|
-
|
145
|
+
RSpec/RepeatedExample:
|
146
|
+
Exclude:
|
147
|
+
- 'spec/expressir/model/data_types/logical_spec.rb'
|
148
|
+
|
149
|
+
# Offense count: 1
|
150
|
+
Style/MissingRespondToMissing:
|
139
151
|
Exclude:
|
140
152
|
- 'lib/expressir/express/visitor.rb'
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
@@ -178,17 +178,17 @@ expressir benchmark schemas/resources/action_schema/action_schema.exp --ips
|
|
178
178
|
expressir benchmark schemas/resources/action_schema/action_schema.exp --format json
|
179
179
|
----
|
180
180
|
|
181
|
-
==== Benchmark multiple files from
|
181
|
+
==== Benchmark multiple files from schema manifest
|
182
182
|
|
183
|
-
Create a YAML file with a list of schema paths:
|
183
|
+
Create a schema manifest YAML file with a list of schema paths:
|
184
184
|
|
185
185
|
.schemas.yml
|
186
186
|
[source, yaml]
|
187
187
|
----
|
188
188
|
schemas:
|
189
|
-
- schemas/resources/action_schema/action_schema.exp
|
190
|
-
- schemas/resources/approval_schema/approval_schema.exp
|
191
|
-
- schemas/resources/date_time_schema/date_time_schema.exp
|
189
|
+
- path: schemas/resources/action_schema/action_schema.exp
|
190
|
+
- path: schemas/resources/approval_schema/approval_schema.exp
|
191
|
+
- path: schemas/resources/date_time_schema/date_time_schema.exp
|
192
192
|
----
|
193
193
|
|
194
194
|
Then benchmark all schemas at once:
|
@@ -271,6 +271,7 @@ The coverage command supports different output formats and exclusion options:
|
|
271
271
|
| `--format json` | Output in JSON format for programmatic processing
|
272
272
|
| `--format yaml` | Output in YAML format for programmatic processing
|
273
273
|
| `--exclude TYPES` | Comma-separated list of EXPRESS entity types to exclude from coverage analysis
|
274
|
+
| `--ignore-files PATH` | Path to YAML file containing array of files to ignore from overall coverage calculation
|
274
275
|
|===
|
275
276
|
|
276
277
|
==== Excluding entity types from coverage
|
@@ -360,11 +361,12 @@ expressir coverage --exclude=TYPE:SELECT,FUNCTION:INNER schemas/resources/action
|
|
360
361
|
|
361
362
|
This is useful when you want to focus documentation coverage on top-level
|
362
363
|
functions while excluding nested helper functions that may not require
|
363
|
-
individual documentation.
|
364
|
+
individual documentation. The exclusion works recursively, excluding functions
|
365
|
+
at any nesting level within other constructs.
|
364
366
|
|
365
367
|
Valid FUNCTION subtypes that can be excluded:
|
366
368
|
|
367
|
-
`INNER`:: Inner functions nested within other functions, rules, or procedures
|
369
|
+
`INNER`:: Inner functions nested within other functions, rules, or procedures (at any depth)
|
368
370
|
+
|
369
371
|
[example]
|
370
372
|
====
|
@@ -372,14 +374,172 @@ Valid FUNCTION subtypes that can be excluded:
|
|
372
374
|
FUNCTION outer_function : BOOLEAN;
|
373
375
|
-- This inner function would be excluded with FUNCTION:INNER
|
374
376
|
FUNCTION inner_helper_function : BOOLEAN;
|
377
|
+
-- Even deeply nested functions are excluded
|
378
|
+
FUNCTION deeply_nested_function : BOOLEAN;
|
379
|
+
RETURN (TRUE);
|
380
|
+
END_FUNCTION;
|
375
381
|
RETURN (TRUE);
|
376
382
|
END_FUNCTION;
|
377
383
|
|
378
384
|
RETURN (TRUE);
|
379
385
|
END_FUNCTION;
|
386
|
+
|
387
|
+
RULE example_rule FOR (some_entity);
|
388
|
+
-- Inner functions in rules are also excluded
|
389
|
+
FUNCTION inner_function_in_rule : BOOLEAN;
|
390
|
+
RETURN (TRUE);
|
391
|
+
END_FUNCTION;
|
392
|
+
WHERE
|
393
|
+
WR1: inner_function_in_rule();
|
394
|
+
END_RULE;
|
395
|
+
|
396
|
+
PROCEDURE example_procedure;
|
397
|
+
-- Inner functions in procedures are also excluded
|
398
|
+
FUNCTION inner_function_in_procedure : BOOLEAN;
|
399
|
+
RETURN (TRUE);
|
400
|
+
END_FUNCTION;
|
401
|
+
END_PROCEDURE;
|
380
402
|
----
|
381
403
|
====
|
382
404
|
|
405
|
+
The `FUNCTION:INNER` exclusion helps maintain focus on documenting the primary
|
406
|
+
API functions while ignoring implementation details of nested helper functions.
|
407
|
+
|
408
|
+
==== Ignoring files from coverage calculation
|
409
|
+
|
410
|
+
You can exclude entire files from the overall coverage calculation using the
|
411
|
+
`--ignore-files` option. This is useful when you have files that should not
|
412
|
+
contribute to the overall documentation coverage statistics, such as test
|
413
|
+
schemas, example files, or legacy schemas.
|
414
|
+
|
415
|
+
[source, sh]
|
416
|
+
----
|
417
|
+
# Use ignore files to exclude specific files from coverage calculation
|
418
|
+
expressir coverage --ignore-files ignore_list.yaml schemas/resources/
|
419
|
+
|
420
|
+
# Combine with other options
|
421
|
+
expressir coverage --ignore-files ignore_list.yaml --exclude=TYPE:SELECT --format=json schemas/resources/
|
422
|
+
----
|
423
|
+
|
424
|
+
===== Ignore files YAML format
|
425
|
+
|
426
|
+
The ignore files YAML should contain an array of file patterns. Each pattern
|
427
|
+
can be either an exact file path or use glob patterns for matching multiple files.
|
428
|
+
|
429
|
+
.ignore_list.yaml
|
430
|
+
[source, yaml]
|
431
|
+
----
|
432
|
+
# Array of file patterns to ignore
|
433
|
+
- examples/test_schema.exp # Exact file path
|
434
|
+
- examples/*_test_*.exp # Glob pattern for test files
|
435
|
+
- legacy/old_*.exp # Glob pattern for legacy files
|
436
|
+
- temp/temporary_schema.exp # Another exact path
|
437
|
+
----
|
438
|
+
|
439
|
+
===== Pattern matching behavior
|
440
|
+
|
441
|
+
File patterns in the ignore files YAML support:
|
442
|
+
|
443
|
+
* **Exact paths**: Match specific files exactly
|
444
|
+
* **Glob patterns**: Use `*` for wildcard matching
|
445
|
+
* **Relative paths**: Patterns are resolved relative to the YAML file's directory
|
446
|
+
* **Absolute paths**: Full system paths are also supported
|
447
|
+
|
448
|
+
[source, yaml]
|
449
|
+
----
|
450
|
+
# Examples of different pattern types
|
451
|
+
- schemas/action_schema/action_schema.exp # Exact relative path
|
452
|
+
- /full/path/to/schema.exp # Absolute path
|
453
|
+
- schemas/**/test_*.exp # Recursive glob pattern
|
454
|
+
- temp/*.exp # All .exp files in temp directory
|
455
|
+
----
|
456
|
+
|
457
|
+
===== Behavior of ignored files
|
458
|
+
|
459
|
+
When files are ignored using the `--ignore-files` option:
|
460
|
+
|
461
|
+
. **Excluded from overall statistics**: Ignored files do not contribute to the
|
462
|
+
overall coverage percentage calculation
|
463
|
+
|
464
|
+
. **Still processed and reported**: Ignored files are still analyzed and appear
|
465
|
+
in the output, but marked with an `ignored: true` flag
|
466
|
+
|
467
|
+
. **Separate reporting section**: In JSON/YAML output formats, ignored files
|
468
|
+
appear in both the main `files` section (with the ignored flag) and in a
|
469
|
+
separate `ignored_files` section
|
470
|
+
|
471
|
+
. **Overall statistics updated**: The overall statistics include additional
|
472
|
+
fields showing the count of ignored files and entities
|
473
|
+
|
474
|
+
.Example JSON output with ignored files:
|
475
|
+
[source, json]
|
476
|
+
----
|
477
|
+
{
|
478
|
+
"overall": {
|
479
|
+
"coverage_percentage": 75.0,
|
480
|
+
"total_entities": 100,
|
481
|
+
"documented_entities": 75,
|
482
|
+
"undocumented_entities": 25,
|
483
|
+
"ignored_files_count": 2,
|
484
|
+
"ignored_entities_count": 15
|
485
|
+
},
|
486
|
+
"files": [
|
487
|
+
{
|
488
|
+
"file": "schemas/main_schema.exp",
|
489
|
+
"ignored": false,
|
490
|
+
"coverage": 80.0,
|
491
|
+
"total": 50,
|
492
|
+
"documented": 40,
|
493
|
+
"undocumented": ["entity1", "entity2"]
|
494
|
+
},
|
495
|
+
{
|
496
|
+
"file": "examples/test_schema.exp",
|
497
|
+
"ignored": true,
|
498
|
+
"matched_pattern": "examples/*_test_*.exp",
|
499
|
+
"coverage": 20.0,
|
500
|
+
"total": 10,
|
501
|
+
"documented": 2,
|
502
|
+
"undocumented": ["test_entity1", "test_entity2"]
|
503
|
+
}
|
504
|
+
],
|
505
|
+
"ignored_files": [
|
506
|
+
{
|
507
|
+
"file": "examples/test_schema.exp",
|
508
|
+
"matched_pattern": "examples/*_test_*.exp",
|
509
|
+
"coverage": 20.0,
|
510
|
+
"total": 10,
|
511
|
+
"documented": 2,
|
512
|
+
"undocumented": ["test_entity1", "test_entity2"]
|
513
|
+
}
|
514
|
+
]
|
515
|
+
}
|
516
|
+
----
|
517
|
+
|
518
|
+
===== Error handling
|
519
|
+
|
520
|
+
The ignore files functionality handles various error conditions gracefully:
|
521
|
+
|
522
|
+
* **Missing YAML file**: If the specified ignore files YAML doesn't exist, a
|
523
|
+
warning is displayed and coverage analysis continues normally
|
524
|
+
|
525
|
+
* **Invalid YAML format**: If the YAML file is malformed or doesn't contain an
|
526
|
+
array, a warning is displayed and the file is ignored
|
527
|
+
|
528
|
+
* **Non-matching patterns**: Patterns that don't match any files are silently
|
529
|
+
ignored (no error or warning)
|
530
|
+
|
531
|
+
* **Permission errors**: File access errors are reported as warnings
|
532
|
+
|
533
|
+
===== Use cases for ignore files
|
534
|
+
|
535
|
+
Common scenarios where ignore files are useful:
|
536
|
+
|
537
|
+
* **Test schemas**: Exclude test or example schemas from production coverage metrics
|
538
|
+
* **Legacy files**: Ignore old schemas that are being phased out
|
539
|
+
* **Generated files**: Exclude automatically generated schemas
|
540
|
+
* **Work-in-progress**: Temporarily ignore files under development
|
541
|
+
* **Different coverage standards**: Apply different documentation standards to different file sets
|
542
|
+
|
383
543
|
Valid TYPE subtypes that can be excluded:
|
384
544
|
|
385
545
|
`AGGREGATE`:: Aggregate type
|
@@ -705,6 +865,203 @@ all_entities = Expressir::Coverage.find_entities(schema)
|
|
705
865
|
puts "Found #{all_entities.size} entities in schema #{schema.id}"
|
706
866
|
----
|
707
867
|
|
868
|
+
=== EXPRESS schema manifest
|
869
|
+
|
870
|
+
==== General
|
871
|
+
|
872
|
+
The EXPRESS schema manifest is a file format defined by ELF at
|
873
|
+
https://www.expresslang.org/docs[EXPRESS schema manifest specification].
|
874
|
+
|
875
|
+
Expressir provides a `SchemaManifest` class for managing collections of EXPRESS
|
876
|
+
schema files. This is particularly useful when working with multiple related
|
877
|
+
schemas or when you need to organize schema files in a structured way.
|
878
|
+
|
879
|
+
The `SchemaManifest` class allows you to:
|
880
|
+
|
881
|
+
* Load schema file lists from YAML manifest files
|
882
|
+
* Manage schema metadata and paths
|
883
|
+
* Programmatically create and manipulate schema collections
|
884
|
+
* Save manifest configurations to files
|
885
|
+
|
886
|
+
|
887
|
+
[example]
|
888
|
+
.Example project structure with schema manifest:
|
889
|
+
====
|
890
|
+
[source]
|
891
|
+
----
|
892
|
+
project/
|
893
|
+
├── schemas.yml # Schema manifest
|
894
|
+
└── schemas/
|
895
|
+
├── core/
|
896
|
+
│ ├── action_schema.exp
|
897
|
+
│ └── approval_schema.exp
|
898
|
+
└── extensions/
|
899
|
+
└── date_time_schema.exp
|
900
|
+
----
|
901
|
+
|
902
|
+
.schemas.yml
|
903
|
+
[source,yaml]
|
904
|
+
----
|
905
|
+
schemas:
|
906
|
+
- path: schemas/core/action_schema.exp
|
907
|
+
id: action_schema
|
908
|
+
- path: schemas/core/approval_schema.exp
|
909
|
+
id: approval_schema
|
910
|
+
- path: schemas/extensions/date_time_schema.exp
|
911
|
+
id: date_time_schema
|
912
|
+
----
|
913
|
+
====
|
914
|
+
|
915
|
+
==== Creating a schema manifest
|
916
|
+
|
917
|
+
===== From a YAML file
|
918
|
+
|
919
|
+
Load an existing schema manifest from a YAML file:
|
920
|
+
|
921
|
+
[source,ruby]
|
922
|
+
----
|
923
|
+
# Load manifest from file
|
924
|
+
manifest = Expressir::SchemaManifest.from_file("schemas.yml")
|
925
|
+
|
926
|
+
# Access schema entries
|
927
|
+
manifest.schemas.each do |schema_entry|
|
928
|
+
puts "Schema path: #{schema_entry.path}"
|
929
|
+
puts "Schema ID: #{schema_entry.id}" if schema_entry.id
|
930
|
+
end
|
931
|
+
|
932
|
+
# Get all schema file paths
|
933
|
+
schema_paths = manifest.schemas.map(&:path)
|
934
|
+
----
|
935
|
+
|
936
|
+
===== Programmatically
|
937
|
+
|
938
|
+
Create a new schema manifest programmatically:
|
939
|
+
|
940
|
+
[source,ruby]
|
941
|
+
----
|
942
|
+
# Create an empty manifest
|
943
|
+
manifest = Expressir::SchemaManifest.new
|
944
|
+
|
945
|
+
# Add schema entries
|
946
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
947
|
+
path: "schemas/action_schema.exp",
|
948
|
+
id: "action_schema"
|
949
|
+
)
|
950
|
+
|
951
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
952
|
+
path: "schemas/approval_schema.exp"
|
953
|
+
)
|
954
|
+
|
955
|
+
# Set base path for the manifest
|
956
|
+
manifest.base_path = "/path/to/schemas"
|
957
|
+
----
|
958
|
+
|
959
|
+
==== Schema manifest YAML format
|
960
|
+
|
961
|
+
The schema manifest uses a structured YAML format:
|
962
|
+
|
963
|
+
[source,yaml]
|
964
|
+
----
|
965
|
+
schemas:
|
966
|
+
- path: schemas/resources/action_schema/action_schema.exp
|
967
|
+
id: action_schema
|
968
|
+
- path: schemas/resources/approval_schema/approval_schema.exp
|
969
|
+
id: approval_schema
|
970
|
+
- path: schemas/resources/date_time_schema/date_time_schema.exp
|
971
|
+
----
|
972
|
+
|
973
|
+
===== Schema entry attributes
|
974
|
+
|
975
|
+
Each schema entry in the manifest can have the following attributes:
|
976
|
+
|
977
|
+
`path`:: (Required) The file path to the EXPRESS schema file
|
978
|
+
`id`:: (Optional) A unique identifier for the schema
|
979
|
+
`container_path`:: (Optional) Container path information
|
980
|
+
|
981
|
+
|
982
|
+
==== Working with schema manifests
|
983
|
+
|
984
|
+
===== Saving manifests
|
985
|
+
|
986
|
+
Save a manifest to a file:
|
987
|
+
|
988
|
+
[source,ruby]
|
989
|
+
----
|
990
|
+
# Save to a specific file
|
991
|
+
manifest.to_file("output_schemas.yml")
|
992
|
+
|
993
|
+
# Save to a path with automatic filename
|
994
|
+
manifest.save_to_path("/path/to/output/")
|
995
|
+
----
|
996
|
+
|
997
|
+
===== Concatenating manifests
|
998
|
+
|
999
|
+
Combine multiple manifests:
|
1000
|
+
|
1001
|
+
[source,ruby]
|
1002
|
+
----
|
1003
|
+
manifest1 = Expressir::SchemaManifest.from_file("schemas1.yml")
|
1004
|
+
manifest2 = Expressir::SchemaManifest.from_file("schemas2.yml")
|
1005
|
+
|
1006
|
+
# Concatenate manifests
|
1007
|
+
combined_manifest = manifest1.concat(manifest2)
|
1008
|
+
|
1009
|
+
# Or use the + operator
|
1010
|
+
combined_manifest = manifest1 + manifest2
|
1011
|
+
----
|
1012
|
+
|
1013
|
+
===== Using manifests with parsers
|
1014
|
+
|
1015
|
+
Parse all schemas from a manifest:
|
1016
|
+
|
1017
|
+
[source,ruby]
|
1018
|
+
----
|
1019
|
+
# Load manifest
|
1020
|
+
manifest = Expressir::SchemaManifest.from_file("schemas.yml")
|
1021
|
+
|
1022
|
+
# Get schema file paths
|
1023
|
+
schema_paths = manifest.schemas.map(&:path)
|
1024
|
+
|
1025
|
+
# Parse all schemas
|
1026
|
+
repository = Expressir::Express::Parser.from_files(schema_paths)
|
1027
|
+
|
1028
|
+
# With progress tracking
|
1029
|
+
repository = Expressir::Express::Parser.from_files(schema_paths) do |filename, schemas, error|
|
1030
|
+
if error
|
1031
|
+
puts "Error loading #{filename}: #{error.message}"
|
1032
|
+
else
|
1033
|
+
puts "Successfully loaded #{schemas.length} schemas from #{filename}"
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
----
|
1037
|
+
|
1038
|
+
==== Integration with CLI commands
|
1039
|
+
|
1040
|
+
Schema manifests are supported by several CLI commands:
|
1041
|
+
|
1042
|
+
===== Benchmarking with manifests
|
1043
|
+
|
1044
|
+
[source,sh]
|
1045
|
+
----
|
1046
|
+
# Benchmark all schemas in a manifest
|
1047
|
+
expressir benchmark schemas.yml --verbose
|
1048
|
+
|
1049
|
+
# Benchmark with caching
|
1050
|
+
expressir benchmark-cache schemas.yml --cache_path /tmp/cache.bin
|
1051
|
+
----
|
1052
|
+
|
1053
|
+
===== Coverage analysis with manifests
|
1054
|
+
|
1055
|
+
[source,sh]
|
1056
|
+
----
|
1057
|
+
# Analyze coverage for all schemas in manifest
|
1058
|
+
expressir coverage schemas.yml
|
1059
|
+
|
1060
|
+
# With output format and exclusions
|
1061
|
+
expressir coverage schemas.yml --format json --exclude=TYPE:SELECT
|
1062
|
+
----
|
1063
|
+
|
1064
|
+
|
708
1065
|
|
709
1066
|
== Contributing
|
710
1067
|
|
data/bin/rspec
CHANGED
@@ -15,7 +15,8 @@ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
|
15
15
|
bundle_binstub = File.expand_path("bundle", __dir__)
|
16
16
|
|
17
17
|
if File.file?(bundle_binstub)
|
18
|
-
if File.read(bundle_binstub,
|
18
|
+
if File.read(bundle_binstub,
|
19
|
+
300).include?("This file was generated by Bundler")
|
19
20
|
load(bundle_binstub)
|
20
21
|
else
|
21
22
|
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
data/docs/liquid_drops.adoc
CHANGED
@@ -249,7 +249,7 @@ Attributes:
|
|
249
249
|
`attributes`:: Array of AttributeDrop objects
|
250
250
|
`unique_rules`:: Array of UniqueRuleDrop objects
|
251
251
|
`where_rules`:: Array of WhereRuleDrop objects
|
252
|
-
`informal_propositions`:: Array of
|
252
|
+
`informal_propositions`:: Array of InformalPropositionRule objects
|
253
253
|
|
254
254
|
==== FunctionDrop
|
255
255
|
|
data/expressir.gemspec
CHANGED
data/lib/expressir/benchmark.rb
CHANGED
@@ -146,7 +146,8 @@ module Expressir
|
|
146
146
|
|
147
147
|
# Measure cache reading time
|
148
148
|
cache_read_time = ::Benchmark.measure do
|
149
|
-
results[:cached_repository] =
|
149
|
+
results[:cached_repository] =
|
150
|
+
Expressir::Express::Cache.from_file(cache_path)
|
150
151
|
end
|
151
152
|
results[:cache_read_time] = cache_read_time.real
|
152
153
|
|
@@ -287,8 +288,10 @@ module Expressir
|
|
287
288
|
}
|
288
289
|
puts JSON.generate(result)
|
289
290
|
when "csv"
|
290
|
-
headers = ["Files", "Schemas", "Objects", "Total Time (s)",
|
291
|
-
|
291
|
+
headers = ["Files", "Schemas", "Objects", "Total Time (s)",
|
292
|
+
"Avg Time (s)", "Objects/s"]
|
293
|
+
values = [count, schema_count, total_objects, total_time.round(4),
|
294
|
+
avg_time.round(4), objects_per_second]
|
292
295
|
|
293
296
|
puts headers.join(",")
|
294
297
|
puts values.join(",")
|