expressir 2.4.29-aarch64-mingw-ucrt
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 +7 -0
- data/.cargo/config.toml +3 -0
- data/.github/scripts/test_installed_gem.rb +34 -0
- data/.github/workflows/codeql.yml +35 -0
- data/.github/workflows/docs.yml +99 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/native-gems.yml +201 -0
- data/.github/workflows/rake.yml +19 -0
- data/.github/workflows/release.yml +37 -0
- data/.github/workflows/rust-ext.yml +41 -0
- data/.github/workflows/stress.yml +36 -0
- data/.github/workflows/validate_schemas.yml +48 -0
- data/.github/workflows/verify_remarks.yml +33 -0
- data/.gitignore +55 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +297 -0
- data/CHANGELOG.md +159 -0
- data/Gemfile +18 -0
- data/README.adoc +2783 -0
- data/Rakefile +41 -0
- data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
- data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
- data/TODO.bugs/03-builder-mutable-state.md +43 -0
- data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
- data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
- data/TODO.bugs/06-collection-registry-single-source.md +53 -0
- data/TODO.bugs/07-require-relative-cleanup.md +42 -0
- data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
- data/TODO.bugs/09-parser-split.md +53 -0
- data/TODO.bugs/10-to-s-override.md +42 -0
- data/TODO.bugs/11-parser-class-variables.md +39 -0
- data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
- data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
- data/TODO.bugs/14-model-formatting-leak.md +30 -0
- data/TODO.bugs/15-expression-children-macro.md +27 -0
- data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
- data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
- data/TODO.bugs/18-const-get-private-constants.md +30 -0
- data/TODO.bugs/19-format-methods-public.md +22 -0
- data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
- data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
- data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
- data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
- data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
- data/TODO.bugs/25-debug-puts-in-production.md +21 -0
- data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
- data/TODO.bugs/27-package-build-god-method.md +19 -0
- data/TODO.bugs/28-package-god-class.md +30 -0
- data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
- data/TODO.bugs/30-unicode-map-extraction.md +19 -0
- data/TODO.bugs/README.md +43 -0
- data/TODO.max-perf/01-restore-ci-green.md +36 -0
- data/TODO.max-perf/02-streaming-parse-path.md +31 -0
- data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
- data/TODO.max-perf/04-benchmark-harness.md +28 -0
- data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
- data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
- data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
- data/TODO.max-perf/08-builder-build-perf.md +45 -0
- data/TODO.max-perf/09-grammar-cold-start.md +25 -0
- data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
- data/TODO.max-perf/11-ci-green-closeout.md +25 -0
- data/TODO.max-perf/12-require-boot-profile.md +25 -0
- data/TODO.max-perf/13-key-conversion-specs.md +26 -0
- data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
- data/TODO.parity-ee/00-overview.md +76 -0
- data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
- data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
- data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
- data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
- data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
- data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
- data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
- data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
- data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
- data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
- data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
- data/TODO.parity-ee/12-full-check-catalog.md +67 -0
- data/TODO.parity-ee/13-population-p21.md +54 -0
- data/TODO.parity-ee/14-shtolo-completion.md +44 -0
- data/TODO.parity-ee/15-part28-xml.md +51 -0
- data/TODO.parity-ee/16-compare-patch.md +48 -0
- data/TODO.parity-ee/17-official-tests.md +42 -0
- data/TODO.parity-ee/18-mim-mapping.md +47 -0
- data/TODO.parity-ee/19-architecture.md +97 -0
- data/TODO.parity-ee/parity-matrix.md +108 -0
- data/TODO.refpath-v2/00-overview.md +64 -0
- data/TODO.suma-improvements/00-overview.md +23 -0
- data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
- data/TODO.suma-improvements/02-suma-e2e.md +39 -0
- data/TODO.suma-improvements/03-item-graph.md +22 -0
- data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
- data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
- data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
- data/TODO.suma-improvements/07-part28-xml.md +15 -0
- data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
- data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
- data/TODO.suma-improvements/10-expressdoc.md +8 -0
- data/benchmark/srl_benchmark.rb +458 -0
- data/benchmark/srl_native_benchmark.rb +146 -0
- data/benchmark/srl_ruby_benchmark.rb +132 -0
- data/bin/console +11 -0
- data/bin/rspec +30 -0
- data/bin/setup +8 -0
- 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/formatter/formatter-architecture.adoc +401 -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/step-packages.adoc +385 -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 +709 -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/formatting-schemas.adoc +89 -0
- data/docs/_tutorials/index.adoc +231 -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 +90 -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/exe/expressir +11 -0
- data/exe/expressir-format +14 -0
- data/exe/expressir-format-test +82 -0
- data/expressir.gemspec +61 -0
- data/lib/expressir/3.4/expressir_core.so +0 -0
- data/lib/expressir/4.0/expressir_core.so +0 -0
- data/lib/expressir/benchmark.rb +310 -0
- data/lib/expressir/changes/item_change.rb +20 -0
- data/lib/expressir/changes/mapping_change.rb +16 -0
- data/lib/expressir/changes/schema_change.rb +85 -0
- data/lib/expressir/changes/version_change.rb +26 -0
- data/lib/expressir/changes.rb +9 -0
- data/lib/expressir/cli.rb +148 -0
- data/lib/expressir/commands/base.rb +25 -0
- data/lib/expressir/commands/benchmark.rb +59 -0
- data/lib/expressir/commands/benchmark_cache.rb +80 -0
- data/lib/expressir/commands/changes.rb +34 -0
- data/lib/expressir/commands/changes_import_eengine.rb +146 -0
- data/lib/expressir/commands/changes_validate.rb +63 -0
- data/lib/expressir/commands/check.rb +56 -0
- data/lib/expressir/commands/clean.rb +20 -0
- data/lib/expressir/commands/coverage.rb +458 -0
- data/lib/expressir/commands/expand.rb +26 -0
- data/lib/expressir/commands/file_violations.rb +70 -0
- data/lib/expressir/commands/fix.rb +33 -0
- data/lib/expressir/commands/flatten.rb +29 -0
- data/lib/expressir/commands/format.rb +43 -0
- data/lib/expressir/commands/manifest.rb +420 -0
- data/lib/expressir/commands/mapping_validate.rb +68 -0
- data/lib/expressir/commands/non_ascii_character.rb +49 -0
- data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
- data/lib/expressir/commands/package.rb +1222 -0
- data/lib/expressir/commands/parity_inputs.rb +160 -0
- data/lib/expressir/commands/validate.rb +106 -0
- data/lib/expressir/commands/validate_ascii.rb +94 -0
- data/lib/expressir/commands/validate_load.rb +91 -0
- data/lib/expressir/commands/version.rb +9 -0
- data/lib/expressir/commands/xsd.rb +23 -0
- data/lib/expressir/commands.rb +30 -0
- data/lib/expressir/config.rb +60 -0
- data/lib/expressir/coverage.rb +510 -0
- data/lib/expressir/eengine/arm_compare_report.rb +23 -0
- data/lib/expressir/eengine/changes_section.rb +16 -0
- data/lib/expressir/eengine/compare_report.rb +69 -0
- data/lib/expressir/eengine/mim_compare_report.rb +23 -0
- data/lib/expressir/eengine/modified_object.rb +21 -0
- data/lib/expressir/eengine.rb +9 -0
- data/lib/expressir/errors.rb +113 -0
- data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
- data/lib/expressir/express/adoc_source_formatter.rb +12 -0
- data/lib/expressir/express/ast_key_converter.rb +114 -0
- data/lib/expressir/express/builder.rb +277 -0
- data/lib/expressir/express/builder_context.rb +22 -0
- data/lib/expressir/express/builder_registry.rb +397 -0
- data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
- data/lib/expressir/express/builders/built_in_builder.rb +75 -0
- data/lib/expressir/express/builders/constant_builder.rb +108 -0
- data/lib/expressir/express/builders/declaration_builder.rb +20 -0
- data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
- data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
- data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
- data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
- data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
- data/lib/expressir/express/builders/expression_builder.rb +416 -0
- data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
- data/lib/expressir/express/builders/helpers.rb +148 -0
- data/lib/expressir/express/builders/interface_builder.rb +151 -0
- data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
- data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
- data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
- data/lib/expressir/express/builders/literal_builder.rb +93 -0
- data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
- data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
- data/lib/expressir/express/builders/reference_builder.rb +18 -0
- data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
- data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
- data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
- data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
- data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
- data/lib/expressir/express/builders/statement_builder.rb +243 -0
- data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
- data/lib/expressir/express/builders/syntax_builder.rb +30 -0
- data/lib/expressir/express/builders/type_builder.rb +238 -0
- data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
- data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
- data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
- data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
- data/lib/expressir/express/builders.rb +55 -0
- data/lib/expressir/express/cache.rb +76 -0
- data/lib/expressir/express/checker.rb +812 -0
- data/lib/expressir/express/concatenator.rb +79 -0
- data/lib/expressir/express/core.rb +95 -0
- data/lib/expressir/express/error.rb +124 -0
- data/lib/expressir/express/formatter.rb +149 -0
- data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
- data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
- data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
- data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
- data/lib/expressir/express/formatters/references_formatter.rb +53 -0
- data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
- data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
- data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
- data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
- data/lib/expressir/express/formatters.rb +22 -0
- data/lib/expressir/express/grammar/parser.rb +712 -0
- data/lib/expressir/express/grammar.rb +11 -0
- data/lib/expressir/express/hyperlink_formatter.rb +35 -0
- data/lib/expressir/express/interface_dot.rb +105 -0
- data/lib/expressir/express/lazy_repository.rb +211 -0
- data/lib/expressir/express/line_map.rb +48 -0
- data/lib/expressir/express/listing.rb +174 -0
- data/lib/expressir/express/model_traversal.rb +42 -0
- data/lib/expressir/express/model_visitor.rb +25 -0
- data/lib/expressir/express/node_position_index.rb +342 -0
- data/lib/expressir/express/parallel_files.rb +229 -0
- data/lib/expressir/express/parser.rb +523 -0
- data/lib/expressir/express/pretty_formatter.rb +586 -0
- data/lib/expressir/express/pretty_gate.rb +61 -0
- data/lib/expressir/express/refs_overlay.rb +47 -0
- data/lib/expressir/express/remark_attacher.rb +1098 -0
- data/lib/expressir/express/remark_overlay.rb +86 -0
- data/lib/expressir/express/remark_scanner.rb +245 -0
- data/lib/expressir/express/resolve_references_model_visitor.rb +29 -0
- data/lib/expressir/express/schema_block_scanner.rb +137 -0
- data/lib/expressir/express/schema_head_formatter.rb +22 -0
- data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
- data/lib/expressir/express/schema_source_formatter.rb +15 -0
- data/lib/expressir/express/scope_resolver.rb +223 -0
- data/lib/expressir/express/self_schema_reference.rb +126 -0
- data/lib/expressir/express/shtolo.rb +679 -0
- data/lib/expressir/express/smrl_xml.rb +125 -0
- data/lib/expressir/express/source_formatter.rb +15 -0
- data/lib/expressir/express/streaming_builder.rb +435 -0
- data/lib/expressir/express/xsd.rb +259 -0
- data/lib/expressir/express.rb +53 -0
- data/lib/expressir/liquid.rb +1 -0
- data/lib/expressir/manifest/resolver.rb +210 -0
- data/lib/expressir/manifest/validator.rb +192 -0
- data/lib/expressir/manifest.rb +6 -0
- data/lib/expressir/mapping/refpath.rb +857 -0
- data/lib/expressir/mapping.rb +253 -0
- data/lib/expressir/model/cache.rb +18 -0
- data/lib/expressir/model/concerns.rb +42 -0
- data/lib/expressir/model/data_types/aggregate.rb +26 -0
- data/lib/expressir/model/data_types/array.rb +25 -0
- data/lib/expressir/model/data_types/bag.rb +21 -0
- data/lib/expressir/model/data_types/binary.rb +19 -0
- data/lib/expressir/model/data_types/boolean.rb +15 -0
- data/lib/expressir/model/data_types/enumeration.rb +21 -0
- data/lib/expressir/model/data_types/enumeration_item.rb +24 -0
- data/lib/expressir/model/data_types/generic.rb +24 -0
- data/lib/expressir/model/data_types/generic_entity.rb +24 -0
- data/lib/expressir/model/data_types/integer.rb +15 -0
- data/lib/expressir/model/data_types/list.rb +23 -0
- data/lib/expressir/model/data_types/logical.rb +15 -0
- data/lib/expressir/model/data_types/number.rb +15 -0
- data/lib/expressir/model/data_types/real.rb +17 -0
- data/lib/expressir/model/data_types/select.rb +23 -0
- data/lib/expressir/model/data_types/set.rb +21 -0
- data/lib/expressir/model/data_types/string.rb +19 -0
- data/lib/expressir/model/data_types.rb +25 -0
- data/lib/expressir/model/declarations/attribute.rb +38 -0
- data/lib/expressir/model/declarations/constant.rb +28 -0
- data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
- data/lib/expressir/model/declarations/entity.rb +62 -0
- data/lib/expressir/model/declarations/function.rb +59 -0
- data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
- data/lib/expressir/model/declarations/interface.rb +37 -0
- data/lib/expressir/model/declarations/interface_item.rb +21 -0
- data/lib/expressir/model/declarations/interfaced_item.rb +33 -0
- data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
- data/lib/expressir/model/declarations/parameter.rb +28 -0
- data/lib/expressir/model/declarations/procedure.rb +57 -0
- data/lib/expressir/model/declarations/remark_item.rb +21 -0
- data/lib/expressir/model/declarations/rule.rb +66 -0
- data/lib/expressir/model/declarations/schema.rb +215 -0
- data/lib/expressir/model/declarations/schema_version.rb +19 -0
- data/lib/expressir/model/declarations/schema_version_item.rb +19 -0
- data/lib/expressir/model/declarations/subtype_constraint.rb +32 -0
- data/lib/expressir/model/declarations/type.rb +45 -0
- data/lib/expressir/model/declarations/unique_rule.rb +26 -0
- data/lib/expressir/model/declarations/variable.rb +28 -0
- data/lib/expressir/model/declarations/where_rule.rb +26 -0
- data/lib/expressir/model/declarations.rb +31 -0
- data/lib/expressir/model/dependency_resolver.rb +268 -0
- data/lib/expressir/model/exp_file.rb +42 -0
- data/lib/expressir/model/expressions/aggregate_initializer.rb +18 -0
- data/lib/expressir/model/expressions/aggregate_initializer_item.rb +20 -0
- data/lib/expressir/model/expressions/binary_expression.rb +59 -0
- data/lib/expressir/model/expressions/entity_constructor.rb +20 -0
- data/lib/expressir/model/expressions/function_call.rb +20 -0
- data/lib/expressir/model/expressions/interval.rb +29 -0
- data/lib/expressir/model/expressions/query_expression.rb +31 -0
- data/lib/expressir/model/expressions/unary_expression.rb +25 -0
- data/lib/expressir/model/expressions.rb +18 -0
- data/lib/expressir/model/identifier.rb +26 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/item_graph.rb +185 -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/indexes.rb +12 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/literals/binary.rb +17 -0
- data/lib/expressir/model/literals/integer.rb +17 -0
- data/lib/expressir/model/literals/logical.rb +21 -0
- data/lib/expressir/model/literals/real.rb +17 -0
- data/lib/expressir/model/literals/string.rb +20 -0
- data/lib/expressir/model/literals.rb +13 -0
- data/lib/expressir/model/model_element.rb +377 -0
- data/lib/expressir/model/references/attribute_reference.rb +19 -0
- data/lib/expressir/model/references/group_reference.rb +19 -0
- data/lib/expressir/model/references/index_reference.rb +23 -0
- data/lib/expressir/model/references/simple_reference.rb +21 -0
- data/lib/expressir/model/references.rb +12 -0
- data/lib/expressir/model/remark_format.rb +17 -0
- data/lib/expressir/model/remark_info.rb +92 -0
- data/lib/expressir/model/remark_placement.rb +42 -0
- data/lib/expressir/model/repository.rb +483 -0
- data/lib/expressir/model/repository_validator.rb +293 -0
- data/lib/expressir/model/search_engine.rb +551 -0
- data/lib/expressir/model/statements/alias.rb +31 -0
- data/lib/expressir/model/statements/assignment.rb +23 -0
- data/lib/expressir/model/statements/case.rb +42 -0
- data/lib/expressir/model/statements/case_action.rb +20 -0
- data/lib/expressir/model/statements/compound.rb +21 -0
- data/lib/expressir/model/statements/escape.rb +18 -0
- data/lib/expressir/model/statements/if.rb +26 -0
- data/lib/expressir/model/statements/null.rb +18 -0
- data/lib/expressir/model/statements/procedure_call.rb +22 -0
- data/lib/expressir/model/statements/repeat.rb +40 -0
- data/lib/expressir/model/statements/return.rb +20 -0
- data/lib/expressir/model/statements/skip.rb +18 -0
- data/lib/expressir/model/statements.rb +20 -0
- data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +25 -0
- data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +17 -0
- data/lib/expressir/model/supertype_expressions.rb +12 -0
- data/lib/expressir/model.rb +39 -0
- data/lib/expressir/package/builder.rb +231 -0
- data/lib/expressir/package/metadata.rb +79 -0
- data/lib/expressir/package/reader.rb +149 -0
- data/lib/expressir/package.rb +8 -0
- data/lib/expressir/schema_manifest.rb +159 -0
- data/lib/expressir/schema_manifest_entry.rb +15 -0
- data/lib/expressir/version.rb +8 -0
- data/lib/expressir.rb +94 -0
- data/lib/tasks/verify_remarks.rake +16 -0
- data/rakelib/native.rake +24 -0
- data/rakelib/oracle.rake +52 -0
- data/rakelib/verify_remarks.rake +16 -0
- metadata +690 -0
data/README.adoc
ADDED
|
@@ -0,0 +1,2783 @@
|
|
|
1
|
+
= Expressir: EXPRESS in Ruby
|
|
2
|
+
|
|
3
|
+
image:https://img.shields.io/gem/v/expressir.svg["Gem Version", link="https://rubygems.org/gems/expressir"]
|
|
4
|
+
// image:https://codeclimate.com/github/lutaml/expressir/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/lutaml/expressir"]
|
|
5
|
+
image:https://github.com/lutaml/expressir/workflows/rake/badge.svg["Build Status", link="https://github.com/lutaml/expressir/actions?workflow=rake"]
|
|
6
|
+
|
|
7
|
+
== Purpose
|
|
8
|
+
|
|
9
|
+
Expressir ("`EXPRESS in Ruby`") is a Ruby parser for EXPRESS and
|
|
10
|
+
a set of Ruby tools for accessing ISO EXPRESS data models.
|
|
11
|
+
|
|
12
|
+
== Architecture
|
|
13
|
+
|
|
14
|
+
Expressir consists of 3 parts:
|
|
15
|
+
|
|
16
|
+
. Parsers. A parser allows Expressir to read EXPRESS files, including:
|
|
17
|
+
|
|
18
|
+
** EXPRESS data modelling language (ISO 10303-11:2007)
|
|
19
|
+
** EXPRESS data modelling language in XML (STEPmod)
|
|
20
|
+
** EXPRESS XML (ISO 10303-28:2007)
|
|
21
|
+
"`Industrial automation systems and integration — Product data representation and exchange — Part 28: Implementation methods: XML representations of EXPRESS schemas and data, using XML schemas`"
|
|
22
|
+
|
|
23
|
+
. Data model. The data model (`lib/expressir/express`) is the Ruby data model that fully represents an EXPRESS data model.
|
|
24
|
+
|
|
25
|
+
. Converters. A converter transforms the EXPRESS Ruby data model into an interoperable export format, including:
|
|
26
|
+
** EXPRESS data modelling language (ISO 10303-11:2007)
|
|
27
|
+
// ** W3C OWL
|
|
28
|
+
// ** OMG SysML (XMI 2.1, XMI 2.5)
|
|
29
|
+
// ** OMG UML 2 (XMI 2.1)
|
|
30
|
+
// ** OMG UML 2 for Eclipse (XMI 2.1)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
== Features
|
|
34
|
+
|
|
35
|
+
=== Remark preservation
|
|
36
|
+
|
|
37
|
+
Expressir fully preserves EXPRESS remarks (comments) during parsing and formatting, maintaining them in their original positions:
|
|
38
|
+
|
|
39
|
+
==== Preamble remarks
|
|
40
|
+
|
|
41
|
+
Remarks between a scope declaration and its first child are preserved as preamble remarks:
|
|
42
|
+
|
|
43
|
+
[source,express]
|
|
44
|
+
----
|
|
45
|
+
SCHEMA example;
|
|
46
|
+
-- This is a preamble remark
|
|
47
|
+
-- It appears after SCHEMA but before declarations
|
|
48
|
+
|
|
49
|
+
ENTITY person;
|
|
50
|
+
-- Entity preamble remark
|
|
51
|
+
name : STRING;
|
|
52
|
+
END_ENTITY;
|
|
53
|
+
|
|
54
|
+
END_SCHEMA;
|
|
55
|
+
----
|
|
56
|
+
|
|
57
|
+
==== Inline tail remarks
|
|
58
|
+
|
|
59
|
+
Remarks on the same line as attribute or enumeration item declarations:
|
|
60
|
+
|
|
61
|
+
[source,express]
|
|
62
|
+
----
|
|
63
|
+
ENTITY person;
|
|
64
|
+
name : STRING; -- Inline remark for name attribute
|
|
65
|
+
age : INTEGER; -- Inline remark for age attribute
|
|
66
|
+
END_ENTITY;
|
|
67
|
+
|
|
68
|
+
TYPE status = ENUMERATION OF
|
|
69
|
+
(active, -- Active status
|
|
70
|
+
inactive, -- Inactive status
|
|
71
|
+
pending); -- Pending status
|
|
72
|
+
END_TYPE;
|
|
73
|
+
----
|
|
74
|
+
|
|
75
|
+
==== END_* scope remarks
|
|
76
|
+
|
|
77
|
+
Remarks on END_TYPE, END_ENTITY, END_SCHEMA, etc. lines:
|
|
78
|
+
|
|
79
|
+
[source,express]
|
|
80
|
+
----
|
|
81
|
+
TYPE status = ENUMERATION OF
|
|
82
|
+
(active,
|
|
83
|
+
inactive);
|
|
84
|
+
END_TYPE; -- Status enumeration type
|
|
85
|
+
|
|
86
|
+
ENTITY person;
|
|
87
|
+
name : STRING;
|
|
88
|
+
END_ENTITY; -- Person entity
|
|
89
|
+
|
|
90
|
+
END_SCHEMA; -- schema_name
|
|
91
|
+
----
|
|
92
|
+
|
|
93
|
+
==== Unicode support
|
|
94
|
+
|
|
95
|
+
All remark types support full Unicode content:
|
|
96
|
+
|
|
97
|
+
[source,express]
|
|
98
|
+
----
|
|
99
|
+
SCHEMA test;
|
|
100
|
+
-- 日本語、中文、한글 in remarks
|
|
101
|
+
|
|
102
|
+
ENTITY person;
|
|
103
|
+
name : STRING; -- Name in Japanese: 名前
|
|
104
|
+
END_ENTITY;
|
|
105
|
+
|
|
106
|
+
END_SCHEMA; -- test
|
|
107
|
+
----
|
|
108
|
+
|
|
109
|
+
For implementation details, see link:docs/ARCHITECTURE.md#remark-attachment-system[Remark Attachment System].
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
== Performance: Parsanol Integration
|
|
113
|
+
|
|
114
|
+
Expressir uses the link:https://github.com/parsanol/parsanol-ruby[Parsanol] gem for high-performance parsing when available.
|
|
115
|
+
|
|
116
|
+
=== Performance Comparison
|
|
117
|
+
|
|
118
|
+
[cols="3,2,2,3"]
|
|
119
|
+
|===
|
|
120
|
+
| Mode | Time (179K lines) | Speedup | Notes
|
|
121
|
+
|
|
122
|
+
| Ruby (Parslet) | 507 s | 1x (baseline) | Pure Ruby parsing
|
|
123
|
+
| Native (Parsanol) | 29 s | 17x faster | Rust parser with AST transformation
|
|
124
|
+
|===
|
|
125
|
+
|
|
126
|
+
=== Features
|
|
127
|
+
|
|
128
|
+
When Parsanol is installed:
|
|
129
|
+
|
|
130
|
+
* **17x faster parsing** - Rust native backend
|
|
131
|
+
* **Lazy line/column** - Zero overhead for position info
|
|
132
|
+
* **Batch FFI** - Efficient u64 array transfer across language boundary
|
|
133
|
+
|
|
134
|
+
=== Usage
|
|
135
|
+
|
|
136
|
+
Expressir automatically uses Parsanol (Rust parser) when available for better performance:
|
|
137
|
+
|
|
138
|
+
[source,ruby]
|
|
139
|
+
----
|
|
140
|
+
# Parse a single file - returns ExpFile
|
|
141
|
+
exp_file = Expressir::Express::Parser.from_file("geometry.exp")
|
|
142
|
+
schema = exp_file.schemas.first
|
|
143
|
+
puts "Schema: #{schema.id}"
|
|
144
|
+
|
|
145
|
+
# Check if native parser is being used
|
|
146
|
+
if Parsanol::Native.available?
|
|
147
|
+
puts "Using Parsanol (Rust parser)"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Parse multiple files - returns Repository
|
|
151
|
+
files = ["schema1.exp", "schema2.exp"]
|
|
152
|
+
repo = Expressir::Express::Parser.from_files(files)
|
|
153
|
+
repo.schemas.each do |s|
|
|
154
|
+
puts "Schema: #{s.id}"
|
|
155
|
+
end
|
|
156
|
+
----
|
|
157
|
+
|
|
158
|
+
For maximum performance, ensure the Parsanol gem is installed:
|
|
159
|
+
|
|
160
|
+
[source,sh]
|
|
161
|
+
----
|
|
162
|
+
gem install parsanol
|
|
163
|
+
----
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
== Installation
|
|
167
|
+
|
|
168
|
+
Add this line to your application's `Gemfile`:
|
|
169
|
+
|
|
170
|
+
[source, sh]
|
|
171
|
+
----
|
|
172
|
+
gem "expressir"
|
|
173
|
+
----
|
|
174
|
+
|
|
175
|
+
And then execute:
|
|
176
|
+
|
|
177
|
+
[source, sh]
|
|
178
|
+
----
|
|
179
|
+
$ bundle install
|
|
180
|
+
----
|
|
181
|
+
|
|
182
|
+
Or install it yourself as:
|
|
183
|
+
|
|
184
|
+
[source, sh]
|
|
185
|
+
----
|
|
186
|
+
$ gem install expressir
|
|
187
|
+
----
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
== Testing
|
|
191
|
+
|
|
192
|
+
Run the test suite:
|
|
193
|
+
|
|
194
|
+
[source, sh]
|
|
195
|
+
----
|
|
196
|
+
bundle exec rake
|
|
197
|
+
----
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
== Usage: CLI
|
|
201
|
+
|
|
202
|
+
This gem ships with a CLI tool. To check what's available you can simply run
|
|
203
|
+
`expressir`, by default it will display some usage instructions.
|
|
204
|
+
|
|
205
|
+
[source, sh]
|
|
206
|
+
----
|
|
207
|
+
$ expressir
|
|
208
|
+
|
|
209
|
+
Commands:
|
|
210
|
+
expressir benchmark FILE_OR_YAML # Benchmark schema loading performance for a file or list of files from YAML
|
|
211
|
+
expressir benchmark-cache FILE_OR_YAML # Benchmark schema loading with caching
|
|
212
|
+
expressir changes SUBCOMMAND # Commands for EXPRESS Changes files
|
|
213
|
+
expressir clean PATH # Strip remarks and prettify EXPRESS schema at PATH
|
|
214
|
+
expressir expand PATH # Concatenate the interface closure into one .exp
|
|
215
|
+
expressir flatten PATH # Flatten the interface closure into an ISO 10303-11:1994 longform schema
|
|
216
|
+
expressir fix PATH # Rewrite self-schema-qualified references (#125)
|
|
217
|
+
expressir format PATH # pretty print EXPRESS schema located at PATH
|
|
218
|
+
expressir mapping_validate PATH # Validate <<express:...>> links in a module mapping.yaml against its ARM/MIM closure
|
|
219
|
+
expressir xsd PATH -o OUT.xsd # Write an XML Schema rendering of the EXPRESS schema at PATH
|
|
220
|
+
expressir help [COMMAND] # Describe available commands or one specific command
|
|
221
|
+
expressir validate load *PATH # validate EXPRESS schema located at PATH
|
|
222
|
+
expressir validate ascii PATH # Validate EXPRESS files for ASCII-only content (excluding remarks)
|
|
223
|
+
expressir validate check *PATHS # eeng check-p11 semantic checks
|
|
224
|
+
expressir coverage *PATH # List EXPRESS entities and check documentation coverage
|
|
225
|
+
expressir version # Expressir Version
|
|
226
|
+
----
|
|
227
|
+
|
|
228
|
+
=== Format schema
|
|
229
|
+
|
|
230
|
+
The `format` command pretty prints an EXPRESS schema, making it more readable
|
|
231
|
+
while preserving its structure.
|
|
232
|
+
|
|
233
|
+
[source, sh]
|
|
234
|
+
----
|
|
235
|
+
# Pretty print a schema to stdout
|
|
236
|
+
expressir format schemas/resources/action_schema/action_schema.exp
|
|
237
|
+
----
|
|
238
|
+
|
|
239
|
+
This command:
|
|
240
|
+
|
|
241
|
+
. Parses the EXPRESS schema
|
|
242
|
+
. Formats it with consistent indentation and spacing
|
|
243
|
+
. Outputs the formatted schema to stdout
|
|
244
|
+
|
|
245
|
+
=== Pretty print with ELF compliance
|
|
246
|
+
|
|
247
|
+
The `PrettyFormatter` class provides ELF (EXPRESS Language Foundation) compliant
|
|
248
|
+
pretty printing with configurable formatting options. This formatter follows the
|
|
249
|
+
https://www.express-language-foundation.org/pretty-print-spec/[ELF Pretty Print specification].
|
|
250
|
+
|
|
251
|
+
==== Using PrettyFormatter in Ruby
|
|
252
|
+
|
|
253
|
+
[source,ruby]
|
|
254
|
+
----
|
|
255
|
+
# Basic usage - formats with default settings
|
|
256
|
+
# Parser.from_file returns an ExpFile
|
|
257
|
+
exp_file = Expressir::Express::Parser.from_file("schema.exp")
|
|
258
|
+
formatter = Expressir::Express::PrettyFormatter.new
|
|
259
|
+
formatted = formatter.format(exp_file)
|
|
260
|
+
puts formatted
|
|
261
|
+
|
|
262
|
+
# The formatter also accepts Repository objects
|
|
263
|
+
repo = Expressir::Express::Parser.from_files(["schema1.exp", "schema2.exp"])
|
|
264
|
+
formatted = formatter.format(repo)
|
|
265
|
+
puts formatted
|
|
266
|
+
----
|
|
267
|
+
|
|
268
|
+
==== Configuration options
|
|
269
|
+
|
|
270
|
+
The PrettyFormatter supports several configuration options to customize the output.
|
|
271
|
+
|
|
272
|
+
[source,ruby]
|
|
273
|
+
----
|
|
274
|
+
formatter = Expressir::Express::PrettyFormatter.new(
|
|
275
|
+
indent: 4, # Spaces per indentation level (default: 4)
|
|
276
|
+
line_length: 80, # Maximum line length (default: nil)
|
|
277
|
+
provenance: true, # Include provenance info (default: true)
|
|
278
|
+
provenance_name: "MyTool", # Tool name (default: "Expressir")
|
|
279
|
+
provenance_version: "1.0.0", # Tool version (default: Expressir::VERSION)
|
|
280
|
+
no_remarks: false # Suppress remarks (default: false)
|
|
281
|
+
)
|
|
282
|
+
----
|
|
283
|
+
|
|
284
|
+
[options="header"]
|
|
285
|
+
|===
|
|
286
|
+
| Option | Type | Default | Description
|
|
287
|
+
|
|
288
|
+
| `indent`
|
|
289
|
+
| Integer
|
|
290
|
+
| `4`
|
|
291
|
+
| Number of spaces per indentation level
|
|
292
|
+
|
|
293
|
+
| `line_length`
|
|
294
|
+
| Integer or nil
|
|
295
|
+
| `nil`
|
|
296
|
+
| Maximum line length (not yet enforced)
|
|
297
|
+
|
|
298
|
+
| `provenance`
|
|
299
|
+
| Boolean
|
|
300
|
+
| `true`
|
|
301
|
+
| Include provenance information in output
|
|
302
|
+
|
|
303
|
+
| `provenance_name`
|
|
304
|
+
| String
|
|
305
|
+
| `"Expressir"`
|
|
306
|
+
| Tool name for provenance
|
|
307
|
+
|
|
308
|
+
| `provenance_version`
|
|
309
|
+
| String
|
|
310
|
+
| `Expressir::VERSION`
|
|
311
|
+
| Tool version for provenance
|
|
312
|
+
|
|
313
|
+
| `no_remarks`
|
|
314
|
+
| Boolean
|
|
315
|
+
| `false`
|
|
316
|
+
| Suppress remarks from source schema
|
|
317
|
+
|===
|
|
318
|
+
|
|
319
|
+
==== Environment variable configuration
|
|
320
|
+
|
|
321
|
+
Configuration can be overridden using environment variables. Environment variables
|
|
322
|
+
take precedence over defaults but are overridden by explicit options:
|
|
323
|
+
|
|
324
|
+
[source,sh]
|
|
325
|
+
----
|
|
326
|
+
# Set environment variables
|
|
327
|
+
export EXPRESSIR_INDENT=2
|
|
328
|
+
export EXPRESSIR_LINE_LENGTH=100
|
|
329
|
+
export EXPRESSIR_PROVENANCE=false
|
|
330
|
+
export EXPRESSIR_PROVENANCE_NAME="CustomTool"
|
|
331
|
+
export EXPRESSIR_PROVENANCE_VERSION="2.0.0"
|
|
332
|
+
|
|
333
|
+
# These will be used unless overridden by options
|
|
334
|
+
ruby my_formatter.rb
|
|
335
|
+
----
|
|
336
|
+
|
|
337
|
+
[options="header"]
|
|
338
|
+
|===
|
|
339
|
+
| Environment Variable | Description
|
|
340
|
+
|
|
341
|
+
| `EXPRESSIR_INDENT`
|
|
342
|
+
| Indentation width (spaces)
|
|
343
|
+
|
|
344
|
+
| `EXPRESSIR_LINE_LENGTH`
|
|
345
|
+
| Maximum line length
|
|
346
|
+
|
|
347
|
+
| `EXPRESSIR_PROVENANCE`
|
|
348
|
+
| Enable/disable provenance (`true`/`false`)
|
|
349
|
+
|
|
350
|
+
| `EXPRESSIR_PROVENANCE_NAME`
|
|
351
|
+
| Tool name for provenance
|
|
352
|
+
|
|
353
|
+
| `EXPRESSIR_PROVENANCE_VERSION`
|
|
354
|
+
| Tool version for provenance
|
|
355
|
+
|===
|
|
356
|
+
|
|
357
|
+
The configuration follows a MECE (Mutually Exclusive, Collectively Exhaustive)
|
|
358
|
+
hierarchy: **Options > ENV > Defaults**
|
|
359
|
+
|
|
360
|
+
==== Key features
|
|
361
|
+
|
|
362
|
+
The PrettyFormatter provides several enhancements over the standard formatter:
|
|
363
|
+
|
|
364
|
+
CONSTANT alignment:: Constants in CONSTANT blocks are aligned at both the colon
|
|
365
|
+
and assignment operator positions for improved readability.
|
|
366
|
+
+
|
|
367
|
+
[example]
|
|
368
|
+
====
|
|
369
|
+
[source]
|
|
370
|
+
----
|
|
371
|
+
CONSTANT
|
|
372
|
+
short_name : INTEGER := 1;
|
|
373
|
+
longer_name : STRING := 'test';
|
|
374
|
+
x : REAL := 3.14;
|
|
375
|
+
END_CONSTANT;
|
|
376
|
+
----
|
|
377
|
+
====
|
|
378
|
+
|
|
379
|
+
Provenance information:: Automatically includes metadata about the formatting
|
|
380
|
+
tool and parameters used, aiding in reproducibility.
|
|
381
|
+
+
|
|
382
|
+
[example]
|
|
383
|
+
====
|
|
384
|
+
[source]
|
|
385
|
+
----
|
|
386
|
+
(*
|
|
387
|
+
Generated by: Expressir version 2.1.31
|
|
388
|
+
Format parameters: indent: 4
|
|
389
|
+
*)
|
|
390
|
+
----
|
|
391
|
+
====
|
|
392
|
+
|
|
393
|
+
Configurable indentation:: Supports custom indentation width (2, 4, 8 spaces, etc.)
|
|
394
|
+
to match project coding standards.
|
|
395
|
+
|
|
396
|
+
Preamble support:: Preserves and formats source-level remarks that appear before
|
|
397
|
+
the first SCHEMA declaration.
|
|
398
|
+
|
|
399
|
+
==== Comparison with standard Formatter
|
|
400
|
+
|
|
401
|
+
[options="header"]
|
|
402
|
+
|===
|
|
403
|
+
| Feature | Formatter | PrettyFormatter
|
|
404
|
+
|
|
405
|
+
| Indentation
|
|
406
|
+
| 2 spaces (fixed)
|
|
407
|
+
| Configurable (default: 4)
|
|
408
|
+
|
|
409
|
+
| CONSTANT alignment
|
|
410
|
+
| No
|
|
411
|
+
| Yes (colons and assignments)
|
|
412
|
+
|
|
413
|
+
| Provenance
|
|
414
|
+
| No
|
|
415
|
+
| Yes (configurable)
|
|
416
|
+
|
|
417
|
+
| Preamble formatting
|
|
418
|
+
| No
|
|
419
|
+
| Yes
|
|
420
|
+
|
|
421
|
+
| Line length enforcement
|
|
422
|
+
| No
|
|
423
|
+
| Planned (not yet implemented)
|
|
424
|
+
|
|
425
|
+
| ELF compliant
|
|
426
|
+
| No
|
|
427
|
+
| Yes
|
|
428
|
+
|
|
429
|
+
| Configuration via ENV
|
|
430
|
+
| No
|
|
431
|
+
| Yes
|
|
432
|
+
|===
|
|
433
|
+
|
|
434
|
+
==== Example usage
|
|
435
|
+
|
|
436
|
+
.Formatting with custom settings
|
|
437
|
+
[example]
|
|
438
|
+
====
|
|
439
|
+
[source,ruby]
|
|
440
|
+
----
|
|
441
|
+
# Parse schema
|
|
442
|
+
repository = Expressir::Express::Parser.from_file("examples/ler/simple_schema.exp")
|
|
443
|
+
|
|
444
|
+
# Format with custom indentation and provenance
|
|
445
|
+
formatter = Expressir::Express::PrettyFormatter.new(
|
|
446
|
+
indent: 2,
|
|
447
|
+
provenance_name: "MyFormatter",
|
|
448
|
+
provenance_version: "1.0.0"
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
formatted = formatter.format(repository)
|
|
452
|
+
|
|
453
|
+
# Save to file
|
|
454
|
+
File.write("formatted_schema.exp", formatted)
|
|
455
|
+
----
|
|
456
|
+
====
|
|
457
|
+
|
|
458
|
+
.Formatting without provenance
|
|
459
|
+
[example]
|
|
460
|
+
====
|
|
461
|
+
[source,ruby]
|
|
462
|
+
----
|
|
463
|
+
# Format without provenance information
|
|
464
|
+
formatter = Expressir::Express::PrettyFormatter.new(provenance: false)
|
|
465
|
+
repository = Expressir::Express::Parser.from_file("schema.exp")
|
|
466
|
+
formatted = formatter.format(repository)
|
|
467
|
+
|
|
468
|
+
# Output is clean without metadata comments
|
|
469
|
+
puts formatted
|
|
470
|
+
----
|
|
471
|
+
====
|
|
472
|
+
|
|
473
|
+
.Round-trip formatting verification
|
|
474
|
+
[example]
|
|
475
|
+
====
|
|
476
|
+
[source,ruby]
|
|
477
|
+
----
|
|
478
|
+
# Format a schema
|
|
479
|
+
original = Expressir::Express::Parser.from_file("schema.exp")
|
|
480
|
+
formatter = Expressir::Express::PrettyFormatter.new
|
|
481
|
+
|
|
482
|
+
# Format once
|
|
483
|
+
formatted1 = formatter.format(original)
|
|
484
|
+
|
|
485
|
+
# Parse the formatted output
|
|
486
|
+
File.write("temp.exp", formatted1)
|
|
487
|
+
reparsed = Expressir::Express::Parser.from_file("temp.exp")
|
|
488
|
+
|
|
489
|
+
# Format again - should be identical (stable formatting)
|
|
490
|
+
formatted2 = formatter.format(reparsed)
|
|
491
|
+
|
|
492
|
+
puts "Formatting is stable" if formatted1 == formatted2
|
|
493
|
+
----
|
|
494
|
+
====
|
|
495
|
+
|
|
496
|
+
=== Clean schema
|
|
497
|
+
|
|
498
|
+
The `clean` command strips remarks and prettifies EXPRESS schemas. This is
|
|
499
|
+
useful for removing all documentation comments while maintaining the schema's
|
|
500
|
+
functional definition. You can optionally save the result to a file.
|
|
501
|
+
|
|
502
|
+
[source, sh]
|
|
503
|
+
----
|
|
504
|
+
# Output to stdout
|
|
505
|
+
expressir clean schemas/resources/action_schema/action_schema.exp
|
|
506
|
+
|
|
507
|
+
# Save to file
|
|
508
|
+
expressir clean schemas/resources/action_schema/action_schema.exp --output clean_schema.exp
|
|
509
|
+
----
|
|
510
|
+
|
|
511
|
+
[options="header"]
|
|
512
|
+
|===
|
|
513
|
+
| Option | Description
|
|
514
|
+
| `--output PATH` | Path to save the cleaned schema (optional, defaults to stdout)
|
|
515
|
+
|===
|
|
516
|
+
|
|
517
|
+
=== Expand schema (concatenated artifact)
|
|
518
|
+
|
|
519
|
+
The `expand` command flattens the interface closure of a root EXPRESS schema
|
|
520
|
+
into a single concatenated artifact (one section per source schema, ordered
|
|
521
|
+
alphabetically — the same shape eeng emits for `--concat_schema`).
|
|
522
|
+
|
|
523
|
+
[source, sh]
|
|
524
|
+
----
|
|
525
|
+
expressir expand schemas/resources/action_schema/action_schema.exp \
|
|
526
|
+
--output action-concatenated.exp
|
|
527
|
+
----
|
|
528
|
+
|
|
529
|
+
[options="header"]
|
|
530
|
+
|===
|
|
531
|
+
| Option | Description
|
|
532
|
+
| `--output PATH`, `-o PATH` | Write the artifact to PATH (defaults to stdout)
|
|
533
|
+
| `--manifest PATH` | ELF schema manifest YAML defining where schemas live (primary
|
|
534
|
+
resolution mode)
|
|
535
|
+
| `--stepmod DIR` | STEPmod checkout root — explicit opt-in to directory-convention
|
|
536
|
+
resolution as the fallback
|
|
537
|
+
|===
|
|
538
|
+
|
|
539
|
+
The closure is resolved by scanning `USE FROM` / `REFERENCE FROM` names in the
|
|
540
|
+
root source. Schema resolution order: `--manifest PATH` (an ELF schema
|
|
541
|
+
manifest — explicit, layout-independent) first; `--stepmod DIR` (the STEPmod
|
|
542
|
+
directory convention) as an explicit fallback; otherwise the file's own
|
|
543
|
+
directory, with a failed lookup warning and pointing at the two explicit
|
|
544
|
+
modes.
|
|
545
|
+
|
|
546
|
+
=== Flatten schema (SHTOLO longform)
|
|
547
|
+
|
|
548
|
+
The `flatten` command converts a STEPmod-style multi-schema root into a single
|
|
549
|
+
ISO 10303-11:1994 "longform" schema (expressir#32). It runs the Annex G
|
|
550
|
+
conversion locally: interface-closure copy with rename resolution and name
|
|
551
|
+
munging, then extensible enum/select resolution, subtype-constraint
|
|
552
|
+
elimination, RENAMED→DERIVE, GENERIC_ENTITY→GENERIC.
|
|
553
|
+
|
|
554
|
+
[source, sh]
|
|
555
|
+
----
|
|
556
|
+
expressir flatten schemas/resources/action_schema/action_schema.exp \
|
|
557
|
+
--output action_lf.exp --longform_name action_schema_lf
|
|
558
|
+
----
|
|
559
|
+
|
|
560
|
+
[options="header"]
|
|
561
|
+
|===
|
|
562
|
+
| Option | Description
|
|
563
|
+
| `--output PATH`, `-o PATH` | Write the longform schema to PATH (defaults to stdout)
|
|
564
|
+
| `--longform_name ID` | Identifier for the resulting SCHEMA (default: `<root>_lf`)
|
|
565
|
+
| `--extenders all|none` | `all` (default, the WG12 requirement): fold every extensible
|
|
566
|
+
SELECT/ENUMERATION extension in the closure into its base type — for
|
|
567
|
+
`EXTENSIBLE GENERIC_ENTITY SELECT` that means every entity the closure
|
|
568
|
+
carries. `none`: leave extensible types exactly as declared.
|
|
569
|
+
| `--manifest PATH` | ELF schema manifest YAML defining where schemas live (primary
|
|
570
|
+
resolution mode)
|
|
571
|
+
| `--stepmod DIR` | STEPmod checkout root — explicit opt-in to directory-convention
|
|
572
|
+
resolution as the fallback
|
|
573
|
+
|===
|
|
574
|
+
|
|
575
|
+
The longform output is verified against Express Engine: for
|
|
576
|
+
`description_assignment`, `eengine --compare` of our longform against
|
|
577
|
+
eengine's own reference artifact reports *No differences detected*
|
|
578
|
+
(`spec/expressir/express/shtolo_eengine_oracle_differential_spec.rb`).
|
|
579
|
+
|
|
580
|
+
=== Fix schema (self-schema references)
|
|
581
|
+
|
|
582
|
+
The `fix` command rewrites string literals that qualify an item with the
|
|
583
|
+
CURRENT schema's name — `'THIS_SCHEMA.ITEM'` inside THIS_SCHEMA is
|
|
584
|
+
technically incorrect: the item usually comes from another schema,
|
|
585
|
+
imported implicitly through a USEd supertype. Local items drop the
|
|
586
|
+
prefix; foreign items gain their true defining schema
|
|
587
|
+
(`'GEOMETRY_SCHEMA.B_SPLINE_SURFACE'`); unknown items are left untouched.
|
|
588
|
+
|
|
589
|
+
[source, sh]
|
|
590
|
+
----
|
|
591
|
+
expressir fix schemas/aic_topologically_bounded_surface.exp --output fixed.exp
|
|
592
|
+
----
|
|
593
|
+
|
|
594
|
+
=== Validate schema
|
|
595
|
+
|
|
596
|
+
The `validate load` command performs validation checks on EXPRESS schema files.
|
|
597
|
+
|
|
598
|
+
It verifies:
|
|
599
|
+
|
|
600
|
+
. That the schema can be parsed correctly into the EXPRESS data model
|
|
601
|
+
. That the schema includes a version string
|
|
602
|
+
|
|
603
|
+
[source, sh]
|
|
604
|
+
----
|
|
605
|
+
# Validate a single schema
|
|
606
|
+
expressir validate load schemas/resources/action_schema/action_schema.exp
|
|
607
|
+
|
|
608
|
+
# Validate multiple schemas
|
|
609
|
+
expressir validate load schemas/resources/action_schema/action_schema.exp schemas/resources/approval_schema/approval_schema.exp
|
|
610
|
+
|
|
611
|
+
# Validate schemas from a schema manifest YAML
|
|
612
|
+
expressir validate load schemas.yml
|
|
613
|
+
----
|
|
614
|
+
|
|
615
|
+
The command reports any schemas that:
|
|
616
|
+
|
|
617
|
+
* Failed to parse into the EXPRESS data model
|
|
618
|
+
* Are missing a version string
|
|
619
|
+
|
|
620
|
+
If all validations pass, it will display "Validation passed for all EXPRESS schemas."
|
|
621
|
+
|
|
622
|
+
=== Validate semantic checks (eeng check-p11)
|
|
623
|
+
|
|
624
|
+
The `validate check` command runs the eeng `check-p11` note subset
|
|
625
|
+
implemented in `Expressir::Express::Checker`: redundant interfaces,
|
|
626
|
+
duplicate interface resources, unresolved interface schema/resource
|
|
627
|
+
refs, SUBTYPE OF targets, SELECT/ENUM BASED_ON targets, and WHERE/UNIQUE
|
|
628
|
+
label patterns.
|
|
629
|
+
|
|
630
|
+
[source, sh]
|
|
631
|
+
----
|
|
632
|
+
# Check a single file
|
|
633
|
+
expressir validate check schemas/resources/action_schema/action_schema.exp
|
|
634
|
+
|
|
635
|
+
# Check all .exp files under a directory
|
|
636
|
+
expressir validate check schemas/resources/
|
|
637
|
+
|
|
638
|
+
# Resolve the closure through an ELF schema manifest (or --stepmod DIR)
|
|
639
|
+
expressir validate check modules/description_assignment/mim.exp \
|
|
640
|
+
--manifest schemas-srl.yaml
|
|
641
|
+
|
|
642
|
+
# Exit 1 when any :error note fires
|
|
643
|
+
expressir validate check schemas/resources/action_schema/action_schema.exp
|
|
644
|
+
----
|
|
645
|
+
|
|
646
|
+
=== Validate ASCII content
|
|
647
|
+
|
|
648
|
+
The `validate ascii` command validates that EXPRESS schema files contain only
|
|
649
|
+
ASCII characters outside of remarks. This ensures compatibility with systems
|
|
650
|
+
that don't support Unicode, while allowing Unicode in documentation comments.
|
|
651
|
+
|
|
652
|
+
[source, sh]
|
|
653
|
+
----
|
|
654
|
+
# Validate a single file
|
|
655
|
+
expressir validate ascii schema.exp
|
|
656
|
+
|
|
657
|
+
# Validate schema manifest YAML
|
|
658
|
+
expressir validate ascii schemas.yml
|
|
659
|
+
|
|
660
|
+
# Validate directory (non-recursive)
|
|
661
|
+
expressir validate ascii schemas/
|
|
662
|
+
|
|
663
|
+
# Validate directory recursively
|
|
664
|
+
expressir validate ascii schemas/ --recursive
|
|
665
|
+
|
|
666
|
+
# Output in YAML format
|
|
667
|
+
expressir validate ascii schemas/ --yaml
|
|
668
|
+
|
|
669
|
+
# Check remarks as well (include remarks in validation)
|
|
670
|
+
expressir validate ascii schema.exp --check-remarks
|
|
671
|
+
----
|
|
672
|
+
|
|
673
|
+
The command checks that all EXPRESS code (excluding remarks) contains only
|
|
674
|
+
7-bit ASCII characters. Tagged remarks (both embedded `(* ... *)` and tail
|
|
675
|
+
`-- ...` comments) are excluded from validation, allowing documentation to
|
|
676
|
+
contain Unicode without triggering errors.
|
|
677
|
+
|
|
678
|
+
[options="header"]
|
|
679
|
+
|===
|
|
680
|
+
| Option | Description
|
|
681
|
+
|
|
682
|
+
| `--recursive`, `-r`
|
|
683
|
+
| Validate EXPRESS files under the specified path recursively
|
|
684
|
+
|
|
685
|
+
| `--yaml`, `-y`
|
|
686
|
+
| Output results in YAML format for programmatic processing
|
|
687
|
+
|
|
688
|
+
| `--check-remarks`
|
|
689
|
+
| Include remarks in ASCII validation (default: false, remarks are excluded)
|
|
690
|
+
|===
|
|
691
|
+
|
|
692
|
+
The validator provides:
|
|
693
|
+
|
|
694
|
+
* Detailed violation reports with line and column numbers
|
|
695
|
+
* Replacement suggestions (AsciiMath for math symbols, ISO 10303-11 encoding for others)
|
|
696
|
+
* Summary statistics
|
|
697
|
+
* Visual indicators for non-ASCII sequences
|
|
698
|
+
|
|
699
|
+
This command is particularly useful before exporting schemas to formats that
|
|
700
|
+
don't support Unicode, such as EEP (Express Engine Parser) and eengine (Express
|
|
701
|
+
Engine).
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
[example]
|
|
705
|
+
====
|
|
706
|
+
[source, sh]
|
|
707
|
+
----
|
|
708
|
+
$ expressir validate ascii spec/fixtures/validate_ascii/non_ascii_in_code.exp
|
|
709
|
+
|
|
710
|
+
spec/fixtures/validate_ascii/non_ascii_in_code.exp:
|
|
711
|
+
Line 3, Column 9:
|
|
712
|
+
ENTITY 製品;
|
|
713
|
+
^^ Non-ASCII sequence
|
|
714
|
+
"製" - Hex: 0x88fd, UTF-8 bytes: 0xe8 0xa3 0xbd
|
|
715
|
+
Replacement: ISO 10303-11: "000088FD"
|
|
716
|
+
"品" - Hex: 0x54c1, UTF-8 bytes: 0xe5 0x93 0x81
|
|
717
|
+
Replacement: ISO 10303-11: "000054C1"
|
|
718
|
+
|
|
719
|
+
...
|
|
720
|
+
Line 10, Column 24:
|
|
721
|
+
symbol : STRING := 'μ';
|
|
722
|
+
^ Non-ASCII sequence
|
|
723
|
+
"μ" - Hex: 0x3bc, UTF-8 bytes: 0xce 0xbc
|
|
724
|
+
Replacement: AsciiMath: mu
|
|
725
|
+
|
|
726
|
+
...
|
|
727
|
+
|
|
728
|
+
Found 7 non-ASCII sequence(s) in non_ascii_in_code.exp
|
|
729
|
+
|
|
730
|
+
Summary:
|
|
731
|
+
Scanned 1 EXPRESS file(s)
|
|
732
|
+
Found 7 non-ASCII sequence(s) in 1 file(s)
|
|
733
|
+
|
|
734
|
+
╭──────────────────────────────────────────────────────────────────────────╮
|
|
735
|
+
│ Non-ASCII Characters Summary │
|
|
736
|
+
├──────────────────────────┬─────────────┬────────────────────┬────────────┤
|
|
737
|
+
│ File │ Symbol │ Replacement │ Occurrenc… │
|
|
738
|
+
├──────────────────────────┼─────────────┼────────────────────┼────────────┤
|
|
739
|
+
│ validate_ascii/non_asci… │ "製" (0x88… │ ISO 10303-11: "00… │ 1 │
|
|
740
|
+
│ validate_ascii/non_asci… │ "品" (0x54… │ ISO 10303-11: "00… │ 1 │
|
|
741
|
+
│ ... │ │ │ │
|
|
742
|
+
│ validate_ascii/non_asci… │ "μ" (0x3bc) │ AsciiMath: mu │ 1 │
|
|
743
|
+
│ ... │ │ │ │
|
|
744
|
+
│ TOTAL │ 10 unique │ — │ 11 │
|
|
745
|
+
╰──────────────────────────┴─────────────┴────────────────────┴────────────╯
|
|
746
|
+
----
|
|
747
|
+
====
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
=== Version
|
|
751
|
+
|
|
752
|
+
The `version` command displays the current version of the Expressir gem.
|
|
753
|
+
|
|
754
|
+
[source, sh]
|
|
755
|
+
----
|
|
756
|
+
expressir version
|
|
757
|
+
----
|
|
758
|
+
|
|
759
|
+
=== Benchmarking
|
|
760
|
+
|
|
761
|
+
Expressir includes powerful benchmarking capabilities for measuring schema
|
|
762
|
+
loading performance. You can benchmark individual files or multiple files listed
|
|
763
|
+
in a YAML configuration.
|
|
764
|
+
|
|
765
|
+
==== Benchmark a single file
|
|
766
|
+
|
|
767
|
+
[source, sh]
|
|
768
|
+
----
|
|
769
|
+
# Basic benchmarking
|
|
770
|
+
expressir benchmark schemas/resources/action_schema/action_schema.exp
|
|
771
|
+
|
|
772
|
+
# With detailed output
|
|
773
|
+
expressir benchmark schemas/resources/action_schema/action_schema.exp --verbose
|
|
774
|
+
|
|
775
|
+
# Using benchmark-ips for more detailed statistics
|
|
776
|
+
expressir benchmark schemas/resources/action_schema/action_schema.exp --ips
|
|
777
|
+
|
|
778
|
+
# With specific output format
|
|
779
|
+
expressir benchmark schemas/resources/action_schema/action_schema.exp --format json
|
|
780
|
+
----
|
|
781
|
+
|
|
782
|
+
==== Benchmark multiple files from schema manifest
|
|
783
|
+
|
|
784
|
+
Create a schema manifest YAML file with a list of schema paths:
|
|
785
|
+
|
|
786
|
+
.schemas.yml
|
|
787
|
+
[source, yaml]
|
|
788
|
+
----
|
|
789
|
+
schemas:
|
|
790
|
+
- path: schemas/resources/action_schema/action_schema.exp
|
|
791
|
+
- path: schemas/resources/approval_schema/approval_schema.exp
|
|
792
|
+
- path: schemas/resources/date_time_schema/date_time_schema.exp
|
|
793
|
+
----
|
|
794
|
+
|
|
795
|
+
Then benchmark all schemas at once:
|
|
796
|
+
|
|
797
|
+
[source, sh]
|
|
798
|
+
----
|
|
799
|
+
expressir benchmark schemas.yml --verbose
|
|
800
|
+
----
|
|
801
|
+
|
|
802
|
+
==== Benchmark with caching
|
|
803
|
+
|
|
804
|
+
You can also benchmark schema loading with caching to measure parsing time,
|
|
805
|
+
cache writing time, and cache reading time:
|
|
806
|
+
|
|
807
|
+
[source, sh]
|
|
808
|
+
----
|
|
809
|
+
# Benchmark a single file with caching
|
|
810
|
+
expressir benchmark-cache schemas/resources/action_schema/action_schema.exp
|
|
811
|
+
|
|
812
|
+
# With custom cache location
|
|
813
|
+
expressir benchmark-cache schemas/resources/action_schema/action_schema.exp --cache_path /tmp/schema_cache.bin
|
|
814
|
+
|
|
815
|
+
# Benchmark multiple files from YAML with caching
|
|
816
|
+
expressir benchmark-cache schemas.yml --verbose
|
|
817
|
+
----
|
|
818
|
+
|
|
819
|
+
==== Benchmark options
|
|
820
|
+
|
|
821
|
+
The benchmark commands support several options:
|
|
822
|
+
|
|
823
|
+
[options="header"]
|
|
824
|
+
|===
|
|
825
|
+
| Option | Description
|
|
826
|
+
| `--ips` | Use benchmark-ips for detailed statistics
|
|
827
|
+
| `--verbose` | Show detailed output
|
|
828
|
+
| `--save` | Save benchmark results to file
|
|
829
|
+
| `--format FORMAT` | Output format: json, csv, or default
|
|
830
|
+
| `--cache_path PATH` | (benchmark-cache only) Path to store the cache file
|
|
831
|
+
|===
|
|
832
|
+
|
|
833
|
+
When using the `--format json` option, results will be output in JSON format,
|
|
834
|
+
making it easy to parse for further analysis or visualization.
|
|
835
|
+
|
|
836
|
+
=== Documentation coverage
|
|
837
|
+
|
|
838
|
+
Expressir can analyze EXPRESS schemas to check for documentation coverage. This helps
|
|
839
|
+
identify which entities are properly documented with remarks and which ones require
|
|
840
|
+
documentation.
|
|
841
|
+
|
|
842
|
+
==== Analyzing documentation coverage
|
|
843
|
+
|
|
844
|
+
Use the `coverage` command to check documentation coverage of EXPRESS schemas:
|
|
845
|
+
|
|
846
|
+
[source, sh]
|
|
847
|
+
----
|
|
848
|
+
# Analyze a single EXPRESS file
|
|
849
|
+
expressir coverage schemas/resources/action_schema/action_schema.exp
|
|
850
|
+
|
|
851
|
+
# Analyze multiple EXPRESS files
|
|
852
|
+
expressir coverage schemas/resources/action_schema/action_schema.exp schemas/resources/approval_schema/approval_schema.exp
|
|
853
|
+
|
|
854
|
+
# Analyze all EXPRESS files in a directory (recursively)
|
|
855
|
+
expressir coverage schemas/resources/
|
|
856
|
+
|
|
857
|
+
# Analyze files specified in a YAML file
|
|
858
|
+
expressir coverage schemas.yml
|
|
859
|
+
----
|
|
860
|
+
|
|
861
|
+
The output shows which entities are missing documentation, calculates coverage percentages,
|
|
862
|
+
and provides an overall documentation coverage summary.
|
|
863
|
+
|
|
864
|
+
==== Coverage options
|
|
865
|
+
|
|
866
|
+
The coverage command supports different output formats and exclusion options:
|
|
867
|
+
|
|
868
|
+
[options="header"]
|
|
869
|
+
|===
|
|
870
|
+
| Option | Description
|
|
871
|
+
| `--format text` | (Default) Display a human-readable table with coverage information
|
|
872
|
+
| `--format json` | Output in JSON format for programmatic processing
|
|
873
|
+
| `--format yaml` | Output in YAML format for programmatic processing
|
|
874
|
+
| `--exclude TYPES` | Comma-separated list of EXPRESS entity types to exclude from coverage analysis
|
|
875
|
+
| `--ignore-files PATH` | Path to YAML file containing array of files to ignore from overall coverage calculation
|
|
876
|
+
|===
|
|
877
|
+
|
|
878
|
+
==== Excluding entity types from coverage
|
|
879
|
+
|
|
880
|
+
You can exclude specific EXPRESS entity types from coverage analysis using the
|
|
881
|
+
`--exclude` option.
|
|
882
|
+
|
|
883
|
+
This is useful when certain entity types don't require documentation coverage,
|
|
884
|
+
such as TYPE entities whose descriptions are generated by template strings.
|
|
885
|
+
|
|
886
|
+
[source, sh]
|
|
887
|
+
----
|
|
888
|
+
# Exclude TYPE entities from coverage analysis
|
|
889
|
+
expressir coverage --exclude=TYPE schemas/resources/action_schema/action_schema.exp
|
|
890
|
+
|
|
891
|
+
# Exclude only SELECT type definitions (useful since TYPE descriptions are often template-generated)
|
|
892
|
+
expressir coverage --exclude=TYPE:SELECT schemas/resources/action_schema/action_schema.exp
|
|
893
|
+
|
|
894
|
+
# Exclude multiple entity types
|
|
895
|
+
expressir coverage --exclude=TYPE,CONSTANT,FUNCTION schemas/resources/action_schema/action_schema.exp
|
|
896
|
+
|
|
897
|
+
# Exclude parameters and variables (often don't require individual documentation)
|
|
898
|
+
expressir coverage --exclude=PARAMETER,VARIABLE schemas/resources/action_schema/action_schema.exp
|
|
899
|
+
|
|
900
|
+
# Combine with output format options
|
|
901
|
+
expressir coverage --exclude=TYPE:SELECT --format=json schemas/resources/action_schema/action_schema.exp
|
|
902
|
+
----
|
|
903
|
+
|
|
904
|
+
==== Elements checked in documentation coverage
|
|
905
|
+
|
|
906
|
+
Expressir checks documentation coverage for all EXPRESS elements (ModelElement
|
|
907
|
+
subclasses), including:
|
|
908
|
+
|
|
909
|
+
Schema-level entities:
|
|
910
|
+
|
|
911
|
+
`TYPE`:: Type definitions (supports subtype exclusion, see below)
|
|
912
|
+
`ENTITY`:: Entity definitions
|
|
913
|
+
`CONSTANT`:: Constant definitions
|
|
914
|
+
`FUNCTION`:: Function definitions
|
|
915
|
+
`RULE`:: Rule definitions
|
|
916
|
+
`PROCEDURE`:: Procedure definitions
|
|
917
|
+
`SUBTYPE_CONSTRAINT`:: Subtype constraint definitions
|
|
918
|
+
`INTERFACE`:: Interface definitions
|
|
919
|
+
|
|
920
|
+
Nested entities within other constructs:
|
|
921
|
+
|
|
922
|
+
`PARAMETER`:: Function and procedure parameters
|
|
923
|
+
`VARIABLE`:: Variables within functions, rules, and procedures
|
|
924
|
+
`ATTRIBUTE`:: Entity attributes
|
|
925
|
+
`DERIVED_ATTRIBUTE`:: Derived attributes in entities
|
|
926
|
+
`INVERSE_ATTRIBUTE`:: Inverse attributes in entities
|
|
927
|
+
`UNIQUE_RULE`:: Unique rules within entities
|
|
928
|
+
`WHERE_RULE`:: Where rules within entities and types
|
|
929
|
+
`ENUMERATION_ITEM`:: Items within enumeration types
|
|
930
|
+
`INTERFACE_ITEM`:: Items within interfaces
|
|
931
|
+
`INTERFACED_ITEM`:: Interfaced items
|
|
932
|
+
`SCHEMA_VERSION`:: Schema version information
|
|
933
|
+
`SCHEMA_VERSION_ITEM`:: Schema version items
|
|
934
|
+
|
|
935
|
+
==== TYPE subtype exclusion
|
|
936
|
+
|
|
937
|
+
For TYPE elements, you can exclude specific subtypes using the `TYPE:SUBTYPE`
|
|
938
|
+
syntax:
|
|
939
|
+
|
|
940
|
+
[source, sh]
|
|
941
|
+
----
|
|
942
|
+
# Exclude only SELECT types
|
|
943
|
+
expressir coverage --exclude=TYPE:SELECT schemas/resources/action_schema/action_schema.exp
|
|
944
|
+
|
|
945
|
+
# Exclude multiple TYPE subtypes
|
|
946
|
+
expressir coverage --exclude=TYPE:SELECT,TYPE:ENUMERATION schemas/resources/action_schema/action_schema.exp
|
|
947
|
+
----
|
|
948
|
+
|
|
949
|
+
==== FUNCTION subtype exclusion
|
|
950
|
+
|
|
951
|
+
For FUNCTION elements, you can exclude inner functions (functions nested within
|
|
952
|
+
other functions, rules, or procedures) using the `FUNCTION:INNER` syntax:
|
|
953
|
+
|
|
954
|
+
[source, sh]
|
|
955
|
+
----
|
|
956
|
+
# Exclude inner functions from coverage analysis
|
|
957
|
+
expressir coverage --exclude=FUNCTION:INNER schemas/resources/action_schema/action_schema.exp
|
|
958
|
+
|
|
959
|
+
# Combine with other exclusions
|
|
960
|
+
expressir coverage --exclude=TYPE:SELECT,FUNCTION:INNER schemas/resources/action_schema/action_schema.exp
|
|
961
|
+
----
|
|
962
|
+
|
|
963
|
+
This is useful when you want to focus documentation coverage on top-level
|
|
964
|
+
functions while excluding nested helper functions that may not require
|
|
965
|
+
individual documentation. The exclusion works recursively, excluding functions
|
|
966
|
+
at any nesting level within other constructs.
|
|
967
|
+
|
|
968
|
+
Valid FUNCTION subtypes that can be excluded:
|
|
969
|
+
|
|
970
|
+
`INNER`:: Inner functions nested within other functions, rules, or procedures (at any depth)
|
|
971
|
+
+
|
|
972
|
+
[example]
|
|
973
|
+
====
|
|
974
|
+
----
|
|
975
|
+
FUNCTION outer_function : BOOLEAN;
|
|
976
|
+
-- This inner function would be excluded with FUNCTION:INNER
|
|
977
|
+
FUNCTION inner_helper_function : BOOLEAN;
|
|
978
|
+
-- Even deeply nested functions are excluded
|
|
979
|
+
FUNCTION deeply_nested_function : BOOLEAN;
|
|
980
|
+
RETURN (TRUE);
|
|
981
|
+
END_FUNCTION;
|
|
982
|
+
RETURN (TRUE);
|
|
983
|
+
END_FUNCTION;
|
|
984
|
+
|
|
985
|
+
RETURN (TRUE);
|
|
986
|
+
END_FUNCTION;
|
|
987
|
+
|
|
988
|
+
RULE example_rule FOR (some_entity);
|
|
989
|
+
-- Inner functions in rules are also excluded
|
|
990
|
+
FUNCTION inner_function_in_rule : BOOLEAN;
|
|
991
|
+
RETURN (TRUE);
|
|
992
|
+
END_FUNCTION;
|
|
993
|
+
WHERE
|
|
994
|
+
WR1: inner_function_in_rule();
|
|
995
|
+
END_RULE;
|
|
996
|
+
|
|
997
|
+
PROCEDURE example_procedure;
|
|
998
|
+
-- Inner functions in procedures are also excluded
|
|
999
|
+
FUNCTION inner_function_in_procedure : BOOLEAN;
|
|
1000
|
+
RETURN (TRUE);
|
|
1001
|
+
END_FUNCTION;
|
|
1002
|
+
END_PROCEDURE;
|
|
1003
|
+
----
|
|
1004
|
+
====
|
|
1005
|
+
|
|
1006
|
+
The `FUNCTION:INNER` exclusion helps maintain focus on documenting the primary
|
|
1007
|
+
API functions while ignoring implementation details of nested helper functions.
|
|
1008
|
+
|
|
1009
|
+
==== Ignoring files from coverage calculation
|
|
1010
|
+
|
|
1011
|
+
You can exclude entire files from the overall coverage calculation using the
|
|
1012
|
+
`--ignore-files` option. This is useful when you have files that should not
|
|
1013
|
+
contribute to the overall documentation coverage statistics, such as test
|
|
1014
|
+
schemas, example files, or legacy schemas.
|
|
1015
|
+
|
|
1016
|
+
[source, sh]
|
|
1017
|
+
----
|
|
1018
|
+
# Use ignore files to exclude specific files from coverage calculation
|
|
1019
|
+
expressir coverage --ignore-files ignore_list.yaml schemas/resources/
|
|
1020
|
+
|
|
1021
|
+
# Combine with other options
|
|
1022
|
+
expressir coverage --ignore-files ignore_list.yaml --exclude=TYPE:SELECT --format=json schemas/resources/
|
|
1023
|
+
----
|
|
1024
|
+
|
|
1025
|
+
===== Ignore files YAML format
|
|
1026
|
+
|
|
1027
|
+
The ignore files YAML should contain an array of file patterns. Each pattern
|
|
1028
|
+
can be either an exact file path or use glob patterns for matching multiple files.
|
|
1029
|
+
|
|
1030
|
+
.ignore_list.yaml
|
|
1031
|
+
[source, yaml]
|
|
1032
|
+
----
|
|
1033
|
+
# Array of file patterns to ignore
|
|
1034
|
+
- examples/test_schema.exp # Exact file path
|
|
1035
|
+
- examples/*_test_*.exp # Glob pattern for test files
|
|
1036
|
+
- legacy/old_*.exp # Glob pattern for legacy files
|
|
1037
|
+
- temp/temporary_schema.exp # Another exact path
|
|
1038
|
+
----
|
|
1039
|
+
|
|
1040
|
+
===== Pattern matching behavior
|
|
1041
|
+
|
|
1042
|
+
File patterns in the ignore files YAML support:
|
|
1043
|
+
|
|
1044
|
+
* **Exact paths**: Match specific files exactly
|
|
1045
|
+
* **Glob patterns**: Use `*` for wildcard matching
|
|
1046
|
+
* **Relative paths**: Patterns are resolved relative to the YAML file's directory
|
|
1047
|
+
* **Absolute paths**: Full system paths are also supported
|
|
1048
|
+
|
|
1049
|
+
[source, yaml]
|
|
1050
|
+
----
|
|
1051
|
+
# Examples of different pattern types
|
|
1052
|
+
- schemas/action_schema/action_schema.exp # Exact relative path
|
|
1053
|
+
- /full/path/to/schema.exp # Absolute path
|
|
1054
|
+
- schemas/**/test_*.exp # Recursive glob pattern
|
|
1055
|
+
- temp/*.exp # All .exp files in temp directory
|
|
1056
|
+
----
|
|
1057
|
+
|
|
1058
|
+
===== Behavior of ignored files
|
|
1059
|
+
|
|
1060
|
+
When files are ignored using the `--ignore-files` option:
|
|
1061
|
+
|
|
1062
|
+
. **Excluded from overall statistics**: Ignored files do not contribute to the
|
|
1063
|
+
overall coverage percentage calculation
|
|
1064
|
+
|
|
1065
|
+
. **Still processed and reported**: Ignored files are still analyzed and appear
|
|
1066
|
+
in the output, but marked with an `ignored: true` flag
|
|
1067
|
+
|
|
1068
|
+
. **Separate reporting section**: In JSON/YAML output formats, ignored files
|
|
1069
|
+
appear in both the main `files` section (with the ignored flag) and in a
|
|
1070
|
+
separate `ignored_files` section
|
|
1071
|
+
|
|
1072
|
+
. **Overall statistics updated**: The overall statistics include additional
|
|
1073
|
+
fields showing the count of ignored files and entities
|
|
1074
|
+
|
|
1075
|
+
.Example JSON output with ignored files:
|
|
1076
|
+
[source, json]
|
|
1077
|
+
----
|
|
1078
|
+
{
|
|
1079
|
+
"overall": {
|
|
1080
|
+
"coverage_percentage": 75.0,
|
|
1081
|
+
"total_entities": 100,
|
|
1082
|
+
"documented_entities": 75,
|
|
1083
|
+
"undocumented_entities": 25,
|
|
1084
|
+
"ignored_files_count": 2,
|
|
1085
|
+
"ignored_entities_count": 15
|
|
1086
|
+
},
|
|
1087
|
+
"files": [
|
|
1088
|
+
{
|
|
1089
|
+
"file": "schemas/main_schema.exp",
|
|
1090
|
+
"ignored": false,
|
|
1091
|
+
"coverage": 80.0,
|
|
1092
|
+
"total": 50,
|
|
1093
|
+
"documented": 40,
|
|
1094
|
+
"undocumented": ["entity1", "entity2"]
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
"file": "examples/test_schema.exp",
|
|
1098
|
+
"ignored": true,
|
|
1099
|
+
"matched_pattern": "examples/*_test_*.exp",
|
|
1100
|
+
"coverage": 20.0,
|
|
1101
|
+
"total": 10,
|
|
1102
|
+
"documented": 2,
|
|
1103
|
+
"undocumented": ["test_entity1", "test_entity2"]
|
|
1104
|
+
}
|
|
1105
|
+
],
|
|
1106
|
+
"ignored_files": [
|
|
1107
|
+
{
|
|
1108
|
+
"file": "examples/test_schema.exp",
|
|
1109
|
+
"matched_pattern": "examples/*_test_*.exp",
|
|
1110
|
+
"coverage": 20.0,
|
|
1111
|
+
"total": 10,
|
|
1112
|
+
"documented": 2,
|
|
1113
|
+
"undocumented": ["test_entity1", "test_entity2"]
|
|
1114
|
+
}
|
|
1115
|
+
]
|
|
1116
|
+
}
|
|
1117
|
+
----
|
|
1118
|
+
|
|
1119
|
+
===== Error handling
|
|
1120
|
+
|
|
1121
|
+
The ignore files functionality handles various error conditions gracefully:
|
|
1122
|
+
|
|
1123
|
+
* **Missing YAML file**: If the specified ignore files YAML doesn't exist, a
|
|
1124
|
+
warning is displayed and coverage analysis continues normally
|
|
1125
|
+
|
|
1126
|
+
* **Invalid YAML format**: If the YAML file is malformed or doesn't contain an
|
|
1127
|
+
array, a warning is displayed and the file is ignored
|
|
1128
|
+
|
|
1129
|
+
* **Non-matching patterns**: Patterns that don't match any files are silently
|
|
1130
|
+
ignored (no error or warning)
|
|
1131
|
+
|
|
1132
|
+
* **Permission errors**: File access errors are reported as warnings
|
|
1133
|
+
|
|
1134
|
+
===== Use cases for ignore files
|
|
1135
|
+
|
|
1136
|
+
Common scenarios where ignore files are useful:
|
|
1137
|
+
|
|
1138
|
+
* **Test schemas**: Exclude test or example schemas from production coverage metrics
|
|
1139
|
+
* **Legacy files**: Ignore old schemas that are being phased out
|
|
1140
|
+
* **Generated files**: Exclude automatically generated schemas
|
|
1141
|
+
* **Work-in-progress**: Temporarily ignore files under development
|
|
1142
|
+
* **Different coverage standards**: Apply different documentation standards to different file sets
|
|
1143
|
+
|
|
1144
|
+
Valid TYPE subtypes that can be excluded:
|
|
1145
|
+
|
|
1146
|
+
`AGGREGATE`:: Aggregate type
|
|
1147
|
+
`ARRAY`:: Array type
|
|
1148
|
+
`BAG`:: Bag type
|
|
1149
|
+
`BINARY`:: Binary type
|
|
1150
|
+
`BOOLEAN`:: Boolean type
|
|
1151
|
+
`ENUMERATION`:: Enumeration type
|
|
1152
|
+
+
|
|
1153
|
+
[example]
|
|
1154
|
+
====
|
|
1155
|
+
----
|
|
1156
|
+
TYPE uuid_relationship_role = ENUMERATION OF
|
|
1157
|
+
(supersedes,
|
|
1158
|
+
merge,
|
|
1159
|
+
split,
|
|
1160
|
+
derive_from,
|
|
1161
|
+
same_as,
|
|
1162
|
+
similar_to);
|
|
1163
|
+
END_TYPE;
|
|
1164
|
+
----
|
|
1165
|
+
====
|
|
1166
|
+
|
|
1167
|
+
`GENERIC`:: Generic type
|
|
1168
|
+
`GENERIC_ENTITY`:: Generic entity type
|
|
1169
|
+
+
|
|
1170
|
+
[example]
|
|
1171
|
+
====
|
|
1172
|
+
----
|
|
1173
|
+
TYPE uuid_attribute_select = EXTENSIBLE GENERIC_ENTITY SELECT;
|
|
1174
|
+
END_TYPE;
|
|
1175
|
+
----
|
|
1176
|
+
====
|
|
1177
|
+
|
|
1178
|
+
`INTEGER`:: Integer type
|
|
1179
|
+
`LIST`:: List type
|
|
1180
|
+
+
|
|
1181
|
+
[example]
|
|
1182
|
+
====
|
|
1183
|
+
----
|
|
1184
|
+
TYPE uuid_list_item = LIST [1:?] OF UNIQUE LIST [1:?] OF UNIQUE uuid_attribute_select;
|
|
1185
|
+
END_TYPE;
|
|
1186
|
+
----
|
|
1187
|
+
====
|
|
1188
|
+
|
|
1189
|
+
`LOGICAL`:: Logical type
|
|
1190
|
+
`NUMBER`:: Number type
|
|
1191
|
+
`REAL`:: Real type
|
|
1192
|
+
`SELECT`:: Select type
|
|
1193
|
+
+
|
|
1194
|
+
[example]
|
|
1195
|
+
====
|
|
1196
|
+
----
|
|
1197
|
+
TYPE uuid_set_or_list_attribute_select = SELECT
|
|
1198
|
+
(uuid_list_item,
|
|
1199
|
+
uuid_set_item);
|
|
1200
|
+
END_TYPE;
|
|
1201
|
+
----
|
|
1202
|
+
====
|
|
1203
|
+
|
|
1204
|
+
`SET`:: Set type
|
|
1205
|
+
+
|
|
1206
|
+
[example]
|
|
1207
|
+
====
|
|
1208
|
+
----
|
|
1209
|
+
TYPE uuid_set_item = SET [1:?] OF uuid_attribute_select;
|
|
1210
|
+
END_TYPE;
|
|
1211
|
+
----
|
|
1212
|
+
====
|
|
1213
|
+
|
|
1214
|
+
`STRING`::
|
|
1215
|
+
String type
|
|
1216
|
+
+
|
|
1217
|
+
[example]
|
|
1218
|
+
====
|
|
1219
|
+
----
|
|
1220
|
+
TYPE uuid = STRING (36) FIXED;
|
|
1221
|
+
END_TYPE;
|
|
1222
|
+
----
|
|
1223
|
+
====
|
|
1224
|
+
|
|
1225
|
+
This is particularly useful since TYPE entities with certain subtypes (like
|
|
1226
|
+
SELECT) often have descriptions generated by template strings and may not
|
|
1227
|
+
require individual remark item coverage.
|
|
1228
|
+
|
|
1229
|
+
NOTE: ISO 10303 excludes documentation coverage for TYPE:SELECT and
|
|
1230
|
+
TYPE:ENUMERATION.
|
|
1231
|
+
|
|
1232
|
+
If you specify an invalid entity type or subtype, the command will display an
|
|
1233
|
+
error message with the list of valid options.
|
|
1234
|
+
|
|
1235
|
+
.Example with JSON output:
|
|
1236
|
+
[example]
|
|
1237
|
+
====
|
|
1238
|
+
[source, sh]
|
|
1239
|
+
----
|
|
1240
|
+
expressir coverage schemas/resources/ --format json
|
|
1241
|
+
----
|
|
1242
|
+
====
|
|
1243
|
+
|
|
1244
|
+
When using JSON or YAML output formats, all file and directory paths are
|
|
1245
|
+
displayed relative to the current working directory:
|
|
1246
|
+
|
|
1247
|
+
[source, yaml]
|
|
1248
|
+
----
|
|
1249
|
+
- file: "schemas/resources/action_schema/action_schema.exp"
|
|
1250
|
+
file_basename: action_schema.exp
|
|
1251
|
+
directory: "schemas/resources/action_schema"
|
|
1252
|
+
# ... other fields
|
|
1253
|
+
----
|
|
1254
|
+
|
|
1255
|
+
==== Coverage output
|
|
1256
|
+
|
|
1257
|
+
The default text output displays:
|
|
1258
|
+
|
|
1259
|
+
. Directory coverage (when analyzing multiple directories)
|
|
1260
|
+
|
|
1261
|
+
. File coverage, showing:
|
|
1262
|
+
** File path
|
|
1263
|
+
** List of undocumented entities
|
|
1264
|
+
** Coverage percentage
|
|
1265
|
+
|
|
1266
|
+
. Overall documentation coverage statistics
|
|
1267
|
+
|
|
1268
|
+
This helps identify areas of your EXPRESS schemas that need documentation
|
|
1269
|
+
improvement.
|
|
1270
|
+
|
|
1271
|
+
=== Schema hyperlinked source faces
|
|
1272
|
+
|
|
1273
|
+
`Schema#source`, `Schema#source_hyperlinked`, and
|
|
1274
|
+
`Schema#formatted_hyperlinked(_adoc)` render a schema head or the full
|
|
1275
|
+
schema with cross-references either verbatim or as links (the adoc
|
|
1276
|
+
variant emits `<<schema.item,item>>` xref macros — render inside a
|
|
1277
|
+
`[source,subs="+macros"]` block for live links; see the
|
|
1278
|
+
`Expressir::Express::SmrlXml` and `Expressir::Express::Xsd` writers
|
|
1279
|
+
for the XML faces).
|
|
1280
|
+
|
|
1281
|
+
== MIM mapping validation (mapping.yaml)
|
|
1282
|
+
|
|
1283
|
+
`expressir mapping_validate PATH` loads a module `mapping.yaml`
|
|
1284
|
+
(lutaml-model typed: `Expressir::Mapping::Document`) and resolves every
|
|
1285
|
+
`<<express:SCHEMA.ITEM,ITEM>>` link against the ARM/MIM interface
|
|
1286
|
+
closure, reporting links whose schema or item is unknown.
|
|
1287
|
+
|
|
1288
|
+
== XML faces
|
|
1289
|
+
|
|
1290
|
+
- `Expressir::Express::SmrlXml.format(repository)` — the SMRL index
|
|
1291
|
+
block per schema (eeng wo-smrl-xml shape).
|
|
1292
|
+
- `Expressir::Express::Xsd.format(schema)` — an XML Schema rendering
|
|
1293
|
+
(entities as element/complexType, substitutionGroup for subtypes,
|
|
1294
|
+
enumeration facets).
|
|
1295
|
+
|
|
1296
|
+
== Lazy compiled-set access
|
|
1297
|
+
|
|
1298
|
+
`Expressir::Express::Core.lazy_set(artifact)` lists a compiled set's
|
|
1299
|
+
wire paths without hydrating and hydrates individual files on demand —
|
|
1300
|
+
renderers that touch one schema per page hydrate one schema per page.
|
|
1301
|
+
|
|
1302
|
+
== EXPRESS Changes files
|
|
1303
|
+
|
|
1304
|
+
Expressir provides commands for working with EXPRESS Changes files that track
|
|
1305
|
+
schema modifications across versions.
|
|
1306
|
+
|
|
1307
|
+
==== Validating change files
|
|
1308
|
+
|
|
1309
|
+
The `changes validate` command validates EXPRESS Changes YAML files and
|
|
1310
|
+
optionally normalizes them through round-trip serialization.
|
|
1311
|
+
|
|
1312
|
+
[source, sh]
|
|
1313
|
+
----
|
|
1314
|
+
# Validate a changes file
|
|
1315
|
+
expressir changes validate schema.changes.yaml
|
|
1316
|
+
|
|
1317
|
+
# Validate with verbose output
|
|
1318
|
+
expressir changes validate schema.changes.yaml --verbose
|
|
1319
|
+
|
|
1320
|
+
# Validate and normalize (outputs to stdout)
|
|
1321
|
+
expressir changes validate schema.changes.yaml --normalize
|
|
1322
|
+
|
|
1323
|
+
# Validate and normalize in-place
|
|
1324
|
+
expressir changes validate schema.changes.yaml --normalize --in-place
|
|
1325
|
+
|
|
1326
|
+
# Validate and save normalized output to a new file
|
|
1327
|
+
expressir changes validate schema.changes.yaml --normalize --output normalized.yaml
|
|
1328
|
+
----
|
|
1329
|
+
|
|
1330
|
+
[options="header"]
|
|
1331
|
+
|===
|
|
1332
|
+
| Option | Description
|
|
1333
|
+
| `--normalize` | Normalize file through round-trip serialization
|
|
1334
|
+
| `--in-place` | Update file in place (requires `--normalize`)
|
|
1335
|
+
| `--output PATH` | Output file path for normalized output
|
|
1336
|
+
| `--verbose` | Show verbose output with validation details
|
|
1337
|
+
|===
|
|
1338
|
+
|
|
1339
|
+
The validate command performs the following checks:
|
|
1340
|
+
|
|
1341
|
+
. Verifies the YAML file can be parsed
|
|
1342
|
+
. Validates against the SchemaChange model structure
|
|
1343
|
+
. Ensures all required fields are present
|
|
1344
|
+
. Checks that change items have valid types
|
|
1345
|
+
|
|
1346
|
+
When using `--normalize`, the command:
|
|
1347
|
+
|
|
1348
|
+
. Loads the file and validates it
|
|
1349
|
+
. Serializes it back to YAML with consistent formatting
|
|
1350
|
+
. Either outputs to stdout, saves in-place, or writes to a new file
|
|
1351
|
+
|
|
1352
|
+
This is useful for:
|
|
1353
|
+
|
|
1354
|
+
* **Standardizing formatting**: Ensures consistent YAML structure
|
|
1355
|
+
* **Catching errors early**: Validates before committing changes
|
|
1356
|
+
* **Cleaning up files**: Removes inconsistencies in formatting
|
|
1357
|
+
|
|
1358
|
+
==== Importing from Express Engine comparison report XML
|
|
1359
|
+
|
|
1360
|
+
The `changes import-eengine` command converts Express Engine (eengine) comparison
|
|
1361
|
+
XML files to EXPRESS Changes YAML format.
|
|
1362
|
+
|
|
1363
|
+
The eengine compare XML format is created through
|
|
1364
|
+
`exp-engine-engine/kernel/compare.lisp` in the Express Engine code. Expressir is
|
|
1365
|
+
compatible with v5.2.7 of eengine output.
|
|
1366
|
+
|
|
1367
|
+
The import command:
|
|
1368
|
+
|
|
1369
|
+
. Parses the eengine XML comparison file
|
|
1370
|
+
. Automatically detects the XML mode (Schema/ARM/MIM)
|
|
1371
|
+
. Extracts additions, modifications, and deletions
|
|
1372
|
+
. Converts modified objects to EXPRESS Changes item format
|
|
1373
|
+
. Preserves interface change information (`interfaced.items`)
|
|
1374
|
+
. Creates or updates an EXPRESS Changes YAML file
|
|
1375
|
+
. Supports appending new versions to existing files
|
|
1376
|
+
|
|
1377
|
+
When the output file already exists:
|
|
1378
|
+
|
|
1379
|
+
* **Same version**: Replaces the existing version with that version
|
|
1380
|
+
* **New version**: Adds a new version to the file
|
|
1381
|
+
|
|
1382
|
+
This allows you to build up a complete change history incrementally across
|
|
1383
|
+
multiple schema versions.
|
|
1384
|
+
|
|
1385
|
+
Syntax:
|
|
1386
|
+
|
|
1387
|
+
[source, sh]
|
|
1388
|
+
----
|
|
1389
|
+
# Basic syntax
|
|
1390
|
+
expressir changes import-eengine INPUT_XML SCHEMA_NAME VERSION [options]
|
|
1391
|
+
|
|
1392
|
+
# Import and output to stdout
|
|
1393
|
+
expressir changes import-eengine comparison.xml schema_name "2"
|
|
1394
|
+
|
|
1395
|
+
# Import and save to file
|
|
1396
|
+
expressir changes import-eengine comparison.xml schema_name "2" -o output.yaml
|
|
1397
|
+
|
|
1398
|
+
# Import with verbose output
|
|
1399
|
+
expressir changes import-eengine comparison.xml schema_name "2" -o output.yaml --verbose
|
|
1400
|
+
|
|
1401
|
+
# Append to existing changes file
|
|
1402
|
+
expressir changes import-eengine comparison.xml schema_name "3" -o existing.yaml
|
|
1403
|
+
----
|
|
1404
|
+
|
|
1405
|
+
Where:
|
|
1406
|
+
|
|
1407
|
+
`INPUT_XML`:: Path to the eengine comparison XML file
|
|
1408
|
+
`SCHEMA_NAME`:: Name of the schema being tracked (e.g., `aic_csg`, `action_schema`)
|
|
1409
|
+
`VERSION`:: Version number for this set of changes (e.g., `"2"`, `"3"`)
|
|
1410
|
+
|
|
1411
|
+
Options:
|
|
1412
|
+
|
|
1413
|
+
`-o, --output PATH`:: Output YAML file path (stdout if not specified)
|
|
1414
|
+
`--verbose`:: Show verbose output including parsed items
|
|
1415
|
+
|
|
1416
|
+
The command automatically detects and handles all three eengine XML comparison
|
|
1417
|
+
formats:
|
|
1418
|
+
|
|
1419
|
+
Schema mode:: `<schema.changes>` root element with `<schema.additions>`,
|
|
1420
|
+
`<schema.modifications>`, and `<schema.deletions>` sections. See API docs for
|
|
1421
|
+
details.
|
|
1422
|
+
|
|
1423
|
+
Example workflow for importing changes from multiple versions:
|
|
1424
|
+
|
|
1425
|
+
.Importing multiple versions incrementally
|
|
1426
|
+
[example]
|
|
1427
|
+
[source, sh]
|
|
1428
|
+
----
|
|
1429
|
+
# Import version 2 changes
|
|
1430
|
+
expressir changes import-eengine v2_comparison.xml action_schema "2" \
|
|
1431
|
+
-o action_schema.changes.yaml
|
|
1432
|
+
|
|
1433
|
+
# Import version 3 changes (appends to existing file)
|
|
1434
|
+
expressir changes import-eengine v3_comparison.xml action_schema "3" \
|
|
1435
|
+
-o action_schema.changes.yaml
|
|
1436
|
+
|
|
1437
|
+
# Import version 4 changes (appends to existing file)
|
|
1438
|
+
expressir changes import-eengine v4_comparison.xml action_schema "4" \
|
|
1439
|
+
-o action_schema.changes.yaml
|
|
1440
|
+
|
|
1441
|
+
# Verify the result
|
|
1442
|
+
cat action_schema.changes.yaml
|
|
1443
|
+
----
|
|
1444
|
+
|
|
1445
|
+
This creates a single YAML file tracking changes across all three versions:
|
|
1446
|
+
|
|
1447
|
+
[source,yaml]
|
|
1448
|
+
----
|
|
1449
|
+
schema: action_schema
|
|
1450
|
+
versions:
|
|
1451
|
+
- version: 2
|
|
1452
|
+
description: Changes from eengine comparison
|
|
1453
|
+
additions: [...]
|
|
1454
|
+
- version: 3
|
|
1455
|
+
description: Changes from eengine comparison
|
|
1456
|
+
additions: [...]
|
|
1457
|
+
- version: 4
|
|
1458
|
+
description: Changes from eengine comparison
|
|
1459
|
+
additions: [...]
|
|
1460
|
+
----
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
== Usage: Ruby
|
|
1464
|
+
|
|
1465
|
+
=== Parsing EXPRESS schema files
|
|
1466
|
+
|
|
1467
|
+
==== General
|
|
1468
|
+
|
|
1469
|
+
The library provides two main methods for parsing EXPRESS files.
|
|
1470
|
+
|
|
1471
|
+
==== Parsing a single file
|
|
1472
|
+
|
|
1473
|
+
Use the `from_file` method to parse a single EXPRESS schema file.
|
|
1474
|
+
This returns an `ExpFile` object containing the parsed schemas:
|
|
1475
|
+
|
|
1476
|
+
[source,ruby]
|
|
1477
|
+
----
|
|
1478
|
+
# Parse a single file - returns ExpFile
|
|
1479
|
+
exp_file = Expressir::Express::Parser.from_file("path/to/schema.exp")
|
|
1480
|
+
|
|
1481
|
+
# Access schemas from the file
|
|
1482
|
+
schema = exp_file.schemas.first
|
|
1483
|
+
|
|
1484
|
+
# With options
|
|
1485
|
+
exp_file = Expressir::Express::Parser.from_file(
|
|
1486
|
+
"path/to/schema.exp",
|
|
1487
|
+
skip_references: false, # Set to true to skip resolving references
|
|
1488
|
+
include_source: true, # Set to true to include original source in the model
|
|
1489
|
+
root_path: "/base/path" # Optional base path for relative paths
|
|
1490
|
+
)
|
|
1491
|
+
----
|
|
1492
|
+
|
|
1493
|
+
The `from_file` method will raise a `SchemaParseFailure` exception if the schema
|
|
1494
|
+
fails to parse, providing information about the specific file and the parsing
|
|
1495
|
+
error:
|
|
1496
|
+
|
|
1497
|
+
[source,ruby]
|
|
1498
|
+
----
|
|
1499
|
+
begin
|
|
1500
|
+
exp_file = Expressir::Express::Parser.from_file("path/to/schema.exp")
|
|
1501
|
+
rescue Expressir::Express::Error::SchemaParseFailure => e
|
|
1502
|
+
puts "Failed to parse schema: #{e.message}"
|
|
1503
|
+
puts "Filename: #{e.filename}"
|
|
1504
|
+
puts "Error details: #{e.parse_failure_cause.ascii_tree}"
|
|
1505
|
+
end
|
|
1506
|
+
----
|
|
1507
|
+
|
|
1508
|
+
==== Parsing multiple files
|
|
1509
|
+
|
|
1510
|
+
Use the `from_files` method to parse multiple EXPRESS schema files.
|
|
1511
|
+
This returns a `Repository` object containing all parsed files:
|
|
1512
|
+
|
|
1513
|
+
[source,ruby]
|
|
1514
|
+
----
|
|
1515
|
+
# Parse multiple files - returns Repository
|
|
1516
|
+
files = ["schema1.exp", "schema2.exp", "schema3.exp"]
|
|
1517
|
+
repository = Expressir::Express::Parser.from_files(files)
|
|
1518
|
+
|
|
1519
|
+
# Access all schemas across all files
|
|
1520
|
+
repository.schemas.each do |schema|
|
|
1521
|
+
puts "Schema: #{schema.id}"
|
|
1522
|
+
end
|
|
1523
|
+
----
|
|
1524
|
+
|
|
1525
|
+
You can provide a block to track loading progress and handle errors:
|
|
1526
|
+
|
|
1527
|
+
[source,ruby]
|
|
1528
|
+
----
|
|
1529
|
+
files = ["schema1.exp", "schema2.exp", "schema3.exp"]
|
|
1530
|
+
repository = Expressir::Express::Parser.from_files(files) do |filename, schemas, error|
|
|
1531
|
+
if error
|
|
1532
|
+
puts "Error loading #{filename}: #{error.message}"
|
|
1533
|
+
# Skip the file with an error or take other action
|
|
1534
|
+
else
|
|
1535
|
+
puts "Successfully loaded #{schemas.length} schemas from #{filename}"
|
|
1536
|
+
end
|
|
1537
|
+
end
|
|
1538
|
+
----
|
|
1539
|
+
|
|
1540
|
+
=== Filtering out schemas
|
|
1541
|
+
|
|
1542
|
+
You can filter out specific schemas from the repository easily since
|
|
1543
|
+
`Expressir::Model::Repository` implements `Enumerable`.
|
|
1544
|
+
|
|
1545
|
+
[source,ruby]
|
|
1546
|
+
----
|
|
1547
|
+
schema_yaml = YAML.load_file('documents/iso-10303-41/schemas.yaml')
|
|
1548
|
+
schema_paths = schema_yaml['schemas'].map {|x,y| y['path'].gsub("../../", "")}
|
|
1549
|
+
|
|
1550
|
+
repo = Expressir::Express::Parser.from_files(schema_paths)
|
|
1551
|
+
|
|
1552
|
+
filtered_schemas = ["action_schema", "date_time_schema"]
|
|
1553
|
+
repo.select do |schema|
|
|
1554
|
+
filtered_schemas.include?(schema.name)
|
|
1555
|
+
end.each do |schema|
|
|
1556
|
+
puts "Schema name: #{schema.name}"
|
|
1557
|
+
puts "Schema file: #{schema.file}"
|
|
1558
|
+
puts "Schema version: #{schema.version}"
|
|
1559
|
+
end
|
|
1560
|
+
----
|
|
1561
|
+
|
|
1562
|
+
=== Convert models to Liquid
|
|
1563
|
+
|
|
1564
|
+
Use `to_liquid` method to convert the models of `Expressir::Model::*` to liquid
|
|
1565
|
+
drop models (`Expressir::Liquid::*`).
|
|
1566
|
+
|
|
1567
|
+
Example:
|
|
1568
|
+
|
|
1569
|
+
[source,ruby]
|
|
1570
|
+
----
|
|
1571
|
+
# Single file (ExpFile)
|
|
1572
|
+
exp_file = Expressir::Express::Parser.from_file("path/to/file.exp")
|
|
1573
|
+
file_drop = exp_file.to_liquid
|
|
1574
|
+
|
|
1575
|
+
# Multiple files (Repository)
|
|
1576
|
+
repo = Expressir::Express::Parser.from_files(["file1.exp", "file2.exp"])
|
|
1577
|
+
repo_drop = repo.to_liquid
|
|
1578
|
+
----
|
|
1579
|
+
|
|
1580
|
+
where `repo` is an instance of `Expressir::Model::Repository` and
|
|
1581
|
+
`repo_drop` is an instance of `Expressir::Liquid::RepositoryDrop`.
|
|
1582
|
+
|
|
1583
|
+
The Liquid drop models of `Expressir::Liquid::*` have the same attributes
|
|
1584
|
+
(`model_attr`) as the models of `Expressir::Model::*`.
|
|
1585
|
+
|
|
1586
|
+
For example, `Expressir::Model::Repository` has the following attributes:
|
|
1587
|
+
|
|
1588
|
+
* `schemas`
|
|
1589
|
+
|
|
1590
|
+
and each `Expressir::Model::Declarations::Schema` has the following attributes:
|
|
1591
|
+
|
|
1592
|
+
* `file`
|
|
1593
|
+
* `version`
|
|
1594
|
+
* `interfaces`
|
|
1595
|
+
* `constants`
|
|
1596
|
+
* `entities`
|
|
1597
|
+
* `subtype_constraints`
|
|
1598
|
+
* `functions`
|
|
1599
|
+
* `rules`
|
|
1600
|
+
* `procedures`
|
|
1601
|
+
|
|
1602
|
+
Thus, `Expressir::Liquid::Repository` has the same attribute `schemas`
|
|
1603
|
+
and `Expressir::Liquid::Declarations::SchemaDrop` has same attribute `file`.
|
|
1604
|
+
|
|
1605
|
+
[source,ruby]
|
|
1606
|
+
----
|
|
1607
|
+
# Parse file (returns ExpFile)
|
|
1608
|
+
exp_file = Expressir::Express::Parser.from_file("path/to/file.exp")
|
|
1609
|
+
file_drop = exp_file.to_liquid
|
|
1610
|
+
schema = file_drop.schemas.first
|
|
1611
|
+
schema.file = "path/to/file.exp"
|
|
1612
|
+
|
|
1613
|
+
# Or parse multiple files (returns Repository)
|
|
1614
|
+
repo = Expressir::Express::Parser.from_files(["file1.exp", "file2.exp"])
|
|
1615
|
+
repo_drop = repo.to_liquid
|
|
1616
|
+
----
|
|
1617
|
+
|
|
1618
|
+
=== Documentation coverage analysis
|
|
1619
|
+
|
|
1620
|
+
Expressir's documentation coverage feature can be used programmatically to
|
|
1621
|
+
analyze and report on documentation coverage of EXPRESS schemas.
|
|
1622
|
+
|
|
1623
|
+
[source,ruby]
|
|
1624
|
+
----
|
|
1625
|
+
# Create a coverage report from a file
|
|
1626
|
+
report = Expressir::Coverage::Report.from_file("path/to/schema.exp")
|
|
1627
|
+
|
|
1628
|
+
# Or create a report from an ExpFile
|
|
1629
|
+
exp_file = Expressir::Express::Parser.from_file("path/to/schema.exp")
|
|
1630
|
+
report = Expressir::Coverage::Report.from_exp_file(exp_file)
|
|
1631
|
+
|
|
1632
|
+
# Or create a report from a repository
|
|
1633
|
+
repo = Expressir::Express::Parser.from_files(["schema1.exp", "schema2.exp"])
|
|
1634
|
+
report = Expressir::Coverage::Report.from_repository(repo)
|
|
1635
|
+
|
|
1636
|
+
# Access overall statistics
|
|
1637
|
+
puts "Overall coverage: #{report.coverage_percentage}%"
|
|
1638
|
+
puts "Total entities: #{report.total_entities.size}"
|
|
1639
|
+
puts "Documented entities: #{report.documented_entities.size}"
|
|
1640
|
+
puts "Undocumented entities: #{report.undocumented_entities.size}"
|
|
1641
|
+
|
|
1642
|
+
# Access file-level reports
|
|
1643
|
+
report.file_reports.each do |file_report|
|
|
1644
|
+
puts "File: #{file_report[:file]}"
|
|
1645
|
+
puts " Coverage: #{file_report[:coverage]}%"
|
|
1646
|
+
puts " Total entities: #{file_report[:total]}"
|
|
1647
|
+
puts " Documented entities: #{file_report[:documented]}"
|
|
1648
|
+
puts " Undocumented entities: #{file_report[:undocumented].join(', ')}"
|
|
1649
|
+
end
|
|
1650
|
+
|
|
1651
|
+
# Access directory-level reports
|
|
1652
|
+
report.directory_reports.each do |dir_report|
|
|
1653
|
+
puts "Directory: #{dir_report[:directory]}"
|
|
1654
|
+
puts " Coverage: #{dir_report[:coverage]}%"
|
|
1655
|
+
puts " Total entities: #{dir_report[:total]}"
|
|
1656
|
+
puts " Documented entities: #{dir_report[:documented]}"
|
|
1657
|
+
puts " Undocumented entities: #{dir_report[:undocumented]}"
|
|
1658
|
+
puts " Number of files: #{dir_report[:files]}"
|
|
1659
|
+
end
|
|
1660
|
+
|
|
1661
|
+
# Generate a structured hash representation
|
|
1662
|
+
report_hash = report.to_h # Contains overall, directories and files sections
|
|
1663
|
+
----
|
|
1664
|
+
|
|
1665
|
+
You can also use the core methods directly to check documentation status:
|
|
1666
|
+
|
|
1667
|
+
[source,ruby]
|
|
1668
|
+
----
|
|
1669
|
+
# Check if an entity has documentation
|
|
1670
|
+
schema = repository.schemas.first
|
|
1671
|
+
entity = schema.entities.first
|
|
1672
|
+
|
|
1673
|
+
if Expressir::Coverage.entity_documented?(entity)
|
|
1674
|
+
puts "Entity #{entity.id} is documented"
|
|
1675
|
+
else
|
|
1676
|
+
puts "Entity #{entity.id} is not documented"
|
|
1677
|
+
end
|
|
1678
|
+
|
|
1679
|
+
# Find all entities in a schema
|
|
1680
|
+
all_entities = Expressir::Coverage.find_entities(schema)
|
|
1681
|
+
puts "Found #{all_entities.size} entities in schema #{schema.id}"
|
|
1682
|
+
----
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
== EXPRESS schema manifests
|
|
1686
|
+
|
|
1687
|
+
=== General
|
|
1688
|
+
|
|
1689
|
+
The EXPRESS schema manifest is a file format defined by ELF at
|
|
1690
|
+
https://www.expresslang.org/docs[EXPRESS schema manifest specification].
|
|
1691
|
+
|
|
1692
|
+
Expressir provides a `SchemaManifest` class for managing collections of EXPRESS
|
|
1693
|
+
schema files. This is particularly useful when working with multiple related
|
|
1694
|
+
schemas or when you need to organize schema files in a structured way.
|
|
1695
|
+
|
|
1696
|
+
The `SchemaManifest` class allows you to:
|
|
1697
|
+
|
|
1698
|
+
* Load schema file lists from YAML manifest files
|
|
1699
|
+
* Manage schema metadata and paths
|
|
1700
|
+
* Programmatically create and manipulate schema collections
|
|
1701
|
+
* Save manifest configurations to files
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
=== File format
|
|
1705
|
+
|
|
1706
|
+
The schema manifest uses a structured YAML format:
|
|
1707
|
+
|
|
1708
|
+
[source,yaml]
|
|
1709
|
+
----
|
|
1710
|
+
schemas:
|
|
1711
|
+
- path: schemas/resources/action_schema/action_schema.exp
|
|
1712
|
+
id: action_schema
|
|
1713
|
+
- path: schemas/resources/approval_schema/approval_schema.exp
|
|
1714
|
+
id: approval_schema
|
|
1715
|
+
- path: schemas/resources/date_time_schema/date_time_schema.exp
|
|
1716
|
+
id: date_time_schema
|
|
1717
|
+
----
|
|
1718
|
+
|
|
1719
|
+
Each schema entry in the manifest can have the following attributes:
|
|
1720
|
+
|
|
1721
|
+
`path`:: (Required) The file path to the EXPRESS schema file
|
|
1722
|
+
`id`:: (Optional) A unique identifier for the schema
|
|
1723
|
+
`container_path`:: (Optional) Container path information
|
|
1724
|
+
|
|
1725
|
+
|
|
1726
|
+
[example]
|
|
1727
|
+
.Example project structure with schema manifest
|
|
1728
|
+
====
|
|
1729
|
+
[source]
|
|
1730
|
+
----
|
|
1731
|
+
project/
|
|
1732
|
+
├── schemas.yml # Schema manifest
|
|
1733
|
+
└── schemas/
|
|
1734
|
+
├── core/
|
|
1735
|
+
│ ├── action_schema.exp
|
|
1736
|
+
│ └── approval_schema.exp
|
|
1737
|
+
└── extensions/
|
|
1738
|
+
└── date_time_schema.exp
|
|
1739
|
+
----
|
|
1740
|
+
|
|
1741
|
+
.schemas.yml
|
|
1742
|
+
[source,yaml]
|
|
1743
|
+
----
|
|
1744
|
+
schemas:
|
|
1745
|
+
- path: schemas/core/action_schema.exp
|
|
1746
|
+
id: action_schema
|
|
1747
|
+
- path: schemas/core/approval_schema.exp
|
|
1748
|
+
id: approval_schema
|
|
1749
|
+
- path: schemas/extensions/date_time_schema.exp
|
|
1750
|
+
id: date_time_schema
|
|
1751
|
+
----
|
|
1752
|
+
====
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
=== Commands for schema manifests
|
|
1756
|
+
|
|
1757
|
+
==== Creating a manifest from a root schema
|
|
1758
|
+
|
|
1759
|
+
The `manifest create` command generates a schema manifest YAML file by
|
|
1760
|
+
resolving all referenced schemas starting from a specified root schema file.
|
|
1761
|
+
|
|
1762
|
+
.`manifest create` - Generate schema manifest
|
|
1763
|
+
[source,sh]
|
|
1764
|
+
----
|
|
1765
|
+
Usage:
|
|
1766
|
+
expressir manifest create ROOT_SCHEMA [MORE_SCHEMAS...] -o, --output=OUTPUT
|
|
1767
|
+
|
|
1768
|
+
Options:
|
|
1769
|
+
-o, --output=OUTPUT # Output YAML file path
|
|
1770
|
+
[--base-dirs=BASE_DIRS] # Comma-separated base directories for schema resolution
|
|
1771
|
+
[--verbose], [--no-verbose], [--skip-verbose] # Show detailed output
|
|
1772
|
+
# Default: false
|
|
1773
|
+
|
|
1774
|
+
Description:
|
|
1775
|
+
Generate a YAML manifest of all schemas required for packaging.
|
|
1776
|
+
|
|
1777
|
+
The manifest uses the existing SchemaManifest format: schemas: schema_id: path:
|
|
1778
|
+
/path/to/schema.exp
|
|
1779
|
+
|
|
1780
|
+
Workflow: 1. Create manifest from root schema 2. Edit manifest to add paths for
|
|
1781
|
+
schemas with null paths 3. Validate manifest 4. Build package using manifest
|
|
1782
|
+
|
|
1783
|
+
Example: expressir manifest create schemas/activity/mim.exp \ -o
|
|
1784
|
+
activity_manifest.yaml \ --base-dirs /path/to/schemas
|
|
1785
|
+
----
|
|
1786
|
+
|
|
1787
|
+
Options:
|
|
1788
|
+
|
|
1789
|
+
`--output, -o FILE`:: (Required) Output YAML file path
|
|
1790
|
+
|
|
1791
|
+
`--base-dirs DIRS`:: Base directories for schema resolution (space-separated). Also supports comma-separated for backward compatibility.
|
|
1792
|
+
+
|
|
1793
|
+
Searches for schema files using these patterns:
|
|
1794
|
+
schema files named according to schema ID::: `<SCHEMA_ID>.exp`
|
|
1795
|
+
schema files named in the STEP module pattern::: `<LOWERCASE_SCHEMA_WO_MIMARM>/{mim,arm}.exp`
|
|
1796
|
+
+
|
|
1797
|
+
[source,sh]
|
|
1798
|
+
----
|
|
1799
|
+
# Space-separated (preferred)
|
|
1800
|
+
--base-dirs /path/to/schemas /another/path
|
|
1801
|
+
|
|
1802
|
+
# Comma-separated (backward compatible)
|
|
1803
|
+
--base-dirs /path/to/schemas,/another/path
|
|
1804
|
+
----
|
|
1805
|
+
|
|
1806
|
+
`--verbose`:: Show detailed output
|
|
1807
|
+
|
|
1808
|
+
Base directories can be provided to help locate schema files:
|
|
1809
|
+
|
|
1810
|
+
* During the resolving process, Expressir will search these directories for
|
|
1811
|
+
schema files matching known naming patterns.
|
|
1812
|
+
* Once a referenced schema is found, it will indicate from which source they
|
|
1813
|
+
were resolved.
|
|
1814
|
+
* If multiple matches are found, the first one encountered will be used, and a
|
|
1815
|
+
warning will be displayed for the user to manually edit the manifest if a
|
|
1816
|
+
different path is desired.
|
|
1817
|
+
|
|
1818
|
+
In the case of unresolved schemas, the created manifest will include entries
|
|
1819
|
+
without the `path:` field. The manifest can then be edited manually to add the
|
|
1820
|
+
correct paths.
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
.Creating a manifest from a root schema
|
|
1824
|
+
[example]
|
|
1825
|
+
====
|
|
1826
|
+
The following command creates a manifest starting from the
|
|
1827
|
+
`schemas/modules/activity/mim.exp` root schema, searching for referenced schemas
|
|
1828
|
+
in the `schemas/resources` and `schemas/modules` base directories.
|
|
1829
|
+
|
|
1830
|
+
[source,sh]
|
|
1831
|
+
----
|
|
1832
|
+
$ expressir manifest create \
|
|
1833
|
+
schemas/modules/activity/mim.exp \
|
|
1834
|
+
-o new.yaml \
|
|
1835
|
+
--base-dirs schemas/modules schemas/resources/ \
|
|
1836
|
+
--verbose
|
|
1837
|
+
|
|
1838
|
+
Creating manifest from 1 root schema(s)...
|
|
1839
|
+
Base directories:
|
|
1840
|
+
- [source 1]: ~/src/mn/iso-10303/schemas/modules
|
|
1841
|
+
- [source 2]: ~/src/mn/iso-10303/schemas/resources/
|
|
1842
|
+
Resolving dependencies...
|
|
1843
|
+
USE FROM action_schema (in mim): ✓ [source 2] action_schema/action_schema.exp
|
|
1844
|
+
REFERENCE FROM basic_attribute_schema (in action_schema): ✓ [source 2] basic_attribute_schema/basic_attribute_schema.exp
|
|
1845
|
+
REFERENCE FROM support_resource_schema (in basic_attribute_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
1846
|
+
REFERENCE FROM support_resource_schema (in action_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
1847
|
+
USE FROM Activity_method_mim (in mim): ✓ [source 1] activity_method/mim.exp
|
|
1848
|
+
...
|
|
1849
|
+
REFERENCE FROM support_resource_schema (in management_resources_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
1850
|
+
✓ Manifest created: new.yaml
|
|
1851
|
+
Resolved schemas: 42
|
|
1852
|
+
All schemas resolved successfully!
|
|
1853
|
+
----
|
|
1854
|
+
====
|
|
1855
|
+
|
|
1856
|
+
.Creating a manifest from a root schema with unresolved schemas
|
|
1857
|
+
[example]
|
|
1858
|
+
====
|
|
1859
|
+
The following command creates a manifest starting from the
|
|
1860
|
+
`schemas/modules/activity/mim.exp` root schema, searching for referenced schemas
|
|
1861
|
+
in the `schemas/resources` base directory only (i.e. it will miss schemas
|
|
1862
|
+
in `schemas/modules`).
|
|
1863
|
+
|
|
1864
|
+
[source,sh]
|
|
1865
|
+
----
|
|
1866
|
+
$ expressir manifest create \
|
|
1867
|
+
-o manifest.yaml \
|
|
1868
|
+
--base-dirs schemas/resources \
|
|
1869
|
+
--verbose \
|
|
1870
|
+
schemas/modules/activity/mim.exp
|
|
1871
|
+
|
|
1872
|
+
Creating manifest from 1 root schema(s)...
|
|
1873
|
+
Base directories:
|
|
1874
|
+
- [source 1]: ~/src/mn/iso-10303/schemas/resources
|
|
1875
|
+
Resolving dependencies...
|
|
1876
|
+
USE FROM action_schema (in mim): ✓ [source 1] action_schema/action_schema.exp
|
|
1877
|
+
REFERENCE FROM basic_attribute_schema (in action_schema): ✓ [source 1] basic_attribute_schema/basic_attribute_schema.exp
|
|
1878
|
+
REFERENCE FROM support_resource_schema (in basic_attribute_schema): ✓ [source 1] support_resource_schema/support_resource_schema.exp
|
|
1879
|
+
REFERENCE FROM support_resource_schema (in action_schema): ✓ [source 1] support_resource_schema/support_resource_schema.exp
|
|
1880
|
+
USE FROM Activity_method_mim (in mim): ✗ not found
|
|
1881
|
+
...
|
|
1882
|
+
REFERENCE FROM support_resource_schema (in management_resources_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
1883
|
+
✓ Manifest created: manifest.yaml
|
|
1884
|
+
Resolved schemas: 41
|
|
1885
|
+
|
|
1886
|
+
⚠ Unresolved schemas (1):
|
|
1887
|
+
- Activity_method_mim
|
|
1888
|
+
|
|
1889
|
+
Please edit manifest.yaml and set 'path:' for unresolved schemas
|
|
1890
|
+
Then validate with: expressir manifest validate manifest.yaml
|
|
1891
|
+
----
|
|
1892
|
+
====
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
==== Resolving schemas from a manifest
|
|
1897
|
+
|
|
1898
|
+
A schema manifest can be used as input to resolve and load all referenced
|
|
1899
|
+
schemas into a new manifest.
|
|
1900
|
+
|
|
1901
|
+
|
|
1902
|
+
[source,sh]
|
|
1903
|
+
----
|
|
1904
|
+
expressir manifest resolve MANIFEST -o, --output=OUTPUT
|
|
1905
|
+
----
|
|
1906
|
+
|
|
1907
|
+
[source,sh]
|
|
1908
|
+
----
|
|
1909
|
+
Usage:
|
|
1910
|
+
expressir manifest resolve MANIFEST -o, --output=OUTPUT
|
|
1911
|
+
|
|
1912
|
+
Options:
|
|
1913
|
+
-o, --output=OUTPUT # Output file path for resolved manifest
|
|
1914
|
+
[--base-dirs=one two three] # Base directories for schema search (can be specified multiple times)
|
|
1915
|
+
[--verbose], [--no-verbose], [--skip-verbose] # Show detailed resolution progress
|
|
1916
|
+
# Default: false
|
|
1917
|
+
|
|
1918
|
+
Description:
|
|
1919
|
+
Resolve missing or incomplete schema paths in a manifest file.
|
|
1920
|
+
|
|
1921
|
+
This command attempts to find file paths for schemas with missing or empty
|
|
1922
|
+
paths by searching in base directories using naming patterns:
|
|
1923
|
+
|
|
1924
|
+
Supported patterns:
|
|
1925
|
+
- Resource schemas: {schema_name}.exp
|
|
1926
|
+
- Module ARM/MIM: {module_name}/{arm|mim}.exp
|
|
1927
|
+
Example: Activity_method_mim -> activity_method/mim.exp
|
|
1928
|
+
|
|
1929
|
+
The resolved manifest is written to the output file, leaving the original
|
|
1930
|
+
unchanged.
|
|
1931
|
+
|
|
1932
|
+
Use this command after 'expressir manifest validate --check-references' fails
|
|
1933
|
+
to automatically resolve missing schema paths.
|
|
1934
|
+
|
|
1935
|
+
Examples: # Resolve paths using manifest's existing base directories expressir
|
|
1936
|
+
manifest resolve manifest.yaml -o resolved_manifest.yaml
|
|
1937
|
+
# Resolve with explicit base directories
|
|
1938
|
+
expressir manifest resolve manifest.yaml -o resolved.yaml \
|
|
1939
|
+
--base-dirs /path/to/schemas,/another/path
|
|
1940
|
+
# With verbose output
|
|
1941
|
+
expressir manifest resolve manifest.yaml -o resolved.yaml --verbose
|
|
1942
|
+
----
|
|
1943
|
+
|
|
1944
|
+
Options:
|
|
1945
|
+
|
|
1946
|
+
`--output, -o FILE`:: (Required) Output file path for resolved manifest
|
|
1947
|
+
|
|
1948
|
+
`--base-dirs DIRS`:: Base directories for schema search (space-separated). Also
|
|
1949
|
+
supports comma-separated for backward compatibility.
|
|
1950
|
+
+
|
|
1951
|
+
Searches for schema files using these patterns:
|
|
1952
|
+
schema files named according to schema ID::: `<SCHEMA_ID>.exp`
|
|
1953
|
+
schema files named in the STEP module pattern::: `<LOWERCASE_SCHEMA_WO_MIMARM>/{mim,arm}.exp`
|
|
1954
|
+
+
|
|
1955
|
+
[source,sh]
|
|
1956
|
+
----
|
|
1957
|
+
# Space-separated (preferred)
|
|
1958
|
+
--base-dirs /path/to/schemas /another/path
|
|
1959
|
+
|
|
1960
|
+
# Comma-separated (backward compatible)
|
|
1961
|
+
--base-dirs /path/to/schemas,/another/path
|
|
1962
|
+
----
|
|
1963
|
+
|
|
1964
|
+
`--verbose`:: Show detailed resolution progress
|
|
1965
|
+
|
|
1966
|
+
.Fully resolving a schema manifest
|
|
1967
|
+
[example]
|
|
1968
|
+
====
|
|
1969
|
+
The following command resolves all schemas in the `manifest.yaml` file and writes the
|
|
1970
|
+
fully resolved manifest to `resolved_manifest.yaml`.
|
|
1971
|
+
|
|
1972
|
+
[source,sh]
|
|
1973
|
+
----
|
|
1974
|
+
$ expressir manifest resolve manifest.yaml -o resolved.yaml --verbose
|
|
1975
|
+
|
|
1976
|
+
Resolving schema paths in: manifest.yaml...
|
|
1977
|
+
Using base directories:
|
|
1978
|
+
- [source 1] ~/src/mn/iso-10303/schemas/
|
|
1979
|
+
Attempting to resolve paths...
|
|
1980
|
+
Resolving dependencies from 1 root schema(s)...
|
|
1981
|
+
USE FROM action_schema (in mim): ✓ [source 1] resources/action_schema/action_schema.exp
|
|
1982
|
+
REFERENCE FROM basic_attribute_schema (in action_schema): ✓ [source 1] resources/basic_attribute_schema/basic_attribute_schema.exp
|
|
1983
|
+
REFERENCE FROM support_resource_schema (in basic_attribute_schema): ✓ [source 1] resources/support_resource_schema/support_resource_schema.exp
|
|
1984
|
+
REFERENCE FROM support_resource_schema (in action_schema): ✓ [source 1] resources/support_resource_schema/support_resource_schema.exp
|
|
1985
|
+
USE FROM Activity_method_mim (in mim): ✗ not found
|
|
1986
|
+
USE FROM basic_attribute_schema (in mim): ✓ [source 1] resources/basic_attribute_schema/basic_attribute_schema.exp
|
|
1987
|
+
USE FROM management_resources_schema (in mim): ✓ [source 1] resources/management_resources_schema/management_resources_schema.exp
|
|
1988
|
+
...
|
|
1989
|
+
REFERENCE FROM support_resource_schema (in management_resources_schema): ✓ [source 1] resources/support_resource_schema/support_resource_schema.exp
|
|
1990
|
+
✓ Manifest resolved: resolved.yaml
|
|
1991
|
+
Total schemas: 42
|
|
1992
|
+
Resolved schemas: 41
|
|
1993
|
+
|
|
1994
|
+
⚠ Unresolved schemas (1):
|
|
1995
|
+
- Activity_method_mim
|
|
1996
|
+
|
|
1997
|
+
These schemas could not be found in the search directories.
|
|
1998
|
+
You may need to:
|
|
1999
|
+
1. Add more base directories with --base-dirs
|
|
2000
|
+
2. Manually edit resolved.yaml and set their paths
|
|
2001
|
+
----
|
|
2002
|
+
====
|
|
2003
|
+
|
|
2004
|
+
.Resolving a manifest with multiple base directories
|
|
2005
|
+
[example]
|
|
2006
|
+
====
|
|
2007
|
+
[source,sh]
|
|
2008
|
+
----
|
|
2009
|
+
$ expressir manifest resolve manifest.yaml \
|
|
2010
|
+
-o resolved.yaml \
|
|
2011
|
+
--base-dirs ~/src/mn/iso-10303/schemas/modules \
|
|
2012
|
+
~/src/mn/iso-10303/schemas/resources/ --verbose
|
|
2013
|
+
|
|
2014
|
+
Resolving schema paths in: manifest.yaml...
|
|
2015
|
+
Using base directories:
|
|
2016
|
+
- [source 1]: ~/src/mn/iso-10303/schemas/modules
|
|
2017
|
+
- [source 2]: ~/src/mn/iso-10303/schemas/resources/
|
|
2018
|
+
Attempting to resolve paths...
|
|
2019
|
+
Resolving dependencies from 1 root schema(s)...
|
|
2020
|
+
Using base directories:
|
|
2021
|
+
- [source 1]: ~/src/mn/iso-10303/schemas/modules
|
|
2022
|
+
- [source 2]: ~/src/mn/iso-10303/schemas/resources
|
|
2023
|
+
USE FROM action_schema (in mim): ✓ [source 2] action_schema/action_schema.exp
|
|
2024
|
+
REFERENCE FROM basic_attribute_schema (in action_schema): ✓ [source 2] basic_attribute_schema/basic_attribute_schema.exp
|
|
2025
|
+
REFERENCE FROM support_resource_schema (in basic_attribute_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
2026
|
+
REFERENCE FROM support_resource_schema (in action_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
2027
|
+
USE FROM Activity_method_mim (in mim): ✓ [source 1] activity_method/mim.exp
|
|
2028
|
+
...
|
|
2029
|
+
REFERENCE FROM support_resource_schema (in management_resources_schema): ✓ [source 2] support_resource_schema/support_resource_schema.exp
|
|
2030
|
+
✓ Manifest resolved: resolved.yaml
|
|
2031
|
+
Total schemas: 42
|
|
2032
|
+
Resolved schemas: 42
|
|
2033
|
+
All schema paths resolved successfully!
|
|
2034
|
+
----
|
|
2035
|
+
====
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
==== Validating a manifest
|
|
2039
|
+
|
|
2040
|
+
A schema manifest can be validated to ensure all referenced schemas are fully
|
|
2041
|
+
resolvable and correctly defined.
|
|
2042
|
+
|
|
2043
|
+
.`manifest validate` - Validate manifest
|
|
2044
|
+
[source,sh]
|
|
2045
|
+
----
|
|
2046
|
+
expressir manifest validate MANIFEST.yaml [OPTIONS]
|
|
2047
|
+
----
|
|
2048
|
+
|
|
2049
|
+
[source,sh]
|
|
2050
|
+
----
|
|
2051
|
+
Usage:
|
|
2052
|
+
expressir manifest validate MANIFEST
|
|
2053
|
+
|
|
2054
|
+
Options:
|
|
2055
|
+
[--verbose], [--no-verbose], [--skip-verbose] # Show detailed validation results
|
|
2056
|
+
# Default: false
|
|
2057
|
+
[--check-references], [--no-check-references], [--skip-check-references] # Validate referential integrity using dependency resolver
|
|
2058
|
+
# Default: false
|
|
2059
|
+
|
|
2060
|
+
Description:
|
|
2061
|
+
Validate a schema manifest file.
|
|
2062
|
+
|
|
2063
|
+
Validation types: - File existence: All schema paths exist on disk - Path
|
|
2064
|
+
completeness: All schemas have paths specified (warnings) - Referential integrity
|
|
2065
|
+
(--check-references): All USE/REFERENCE FROM resolve
|
|
2066
|
+
|
|
2067
|
+
Examples: # Basic validation (file existence and path completeness) expressir manifest
|
|
2068
|
+
validate activity_manifest.yaml # With referential integrity checking expressir
|
|
2069
|
+
manifest validate activity_manifest.yaml --check-references # With verbose output
|
|
2070
|
+
expressir manifest validate activity_manifest.yaml --check-references --verbose
|
|
2071
|
+
----
|
|
2072
|
+
|
|
2073
|
+
Options:
|
|
2074
|
+
|
|
2075
|
+
`--verbose`:: Show detailed validation results
|
|
2076
|
+
|
|
2077
|
+
`--check-references`:: Validate referential integrity using dependency resolver
|
|
2078
|
+
|
|
2079
|
+
.Validating a manifest to ensure all dependencies are defined
|
|
2080
|
+
[example]
|
|
2081
|
+
====
|
|
2082
|
+
Checking `REFERENCE FROM` and `USE FROM` references to ensure all dependencies
|
|
2083
|
+
are defined in EXPRESS schemas included in the manifest:
|
|
2084
|
+
|
|
2085
|
+
[source,sh]
|
|
2086
|
+
----
|
|
2087
|
+
$ expressir manifest validate manifest.yaml --check-references --verbose
|
|
2088
|
+
|
|
2089
|
+
Validating manifest: manifest.yaml...
|
|
2090
|
+
Checking referential integrity...
|
|
2091
|
+
Validating referential integrity for 42 schemas...
|
|
2092
|
+
|
|
2093
|
+
USE FROM action_schema (in Activity_method_mim): ✓ action_schema.exp
|
|
2094
|
+
REFERENCE FROM basic_attribute_schema (in action_schema): ✓ basic_attribute_schema.exp
|
|
2095
|
+
...
|
|
2096
|
+
USE FROM action_schema (in mim): ✓ action_schema.exp
|
|
2097
|
+
...
|
|
2098
|
+
REFERENCE FROM support_resource_schema (in topology_schema): ✓ support_resource_schema.exp
|
|
2099
|
+
✓ Manifest is valid
|
|
2100
|
+
Total schemas: 42
|
|
2101
|
+
Resolved schemas: 42
|
|
2102
|
+
----
|
|
2103
|
+
====
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
|
|
2107
|
+
=== Ruby API for schema manifests
|
|
2108
|
+
|
|
2109
|
+
==== Loading manifests
|
|
2110
|
+
|
|
2111
|
+
Load an existing schema manifest from a YAML file:
|
|
2112
|
+
|
|
2113
|
+
[source,ruby]
|
|
2114
|
+
----
|
|
2115
|
+
# Load manifest from file
|
|
2116
|
+
manifest = Expressir::SchemaManifest.from_file("schemas.yml")
|
|
2117
|
+
|
|
2118
|
+
# Access schema entries
|
|
2119
|
+
manifest.schemas.each do |schema_entry|
|
|
2120
|
+
puts "Schema path: #{schema_entry.path}"
|
|
2121
|
+
puts "Schema ID: #{schema_entry.id}" if schema_entry.id
|
|
2122
|
+
end
|
|
2123
|
+
|
|
2124
|
+
# Get all schema file paths
|
|
2125
|
+
schema_paths = manifest.schemas.map(&:path)
|
|
2126
|
+
----
|
|
2127
|
+
|
|
2128
|
+
==== Creating manifests
|
|
2129
|
+
|
|
2130
|
+
Create a new schema manifest programmatically:
|
|
2131
|
+
|
|
2132
|
+
[source,ruby]
|
|
2133
|
+
----
|
|
2134
|
+
# Create an empty manifest
|
|
2135
|
+
manifest = Expressir::SchemaManifest.new
|
|
2136
|
+
|
|
2137
|
+
# Add schema entries
|
|
2138
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
|
2139
|
+
path: "schemas/action_schema.exp",
|
|
2140
|
+
id: "action_schema"
|
|
2141
|
+
)
|
|
2142
|
+
|
|
2143
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
|
2144
|
+
path: "schemas/approval_schema.exp"
|
|
2145
|
+
)
|
|
2146
|
+
|
|
2147
|
+
# Set base path for the manifest
|
|
2148
|
+
manifest.base_path = "/path/to/schemas"
|
|
2149
|
+
----
|
|
2150
|
+
|
|
2151
|
+
==== Saving manifests
|
|
2152
|
+
|
|
2153
|
+
Save a manifest to a file:
|
|
2154
|
+
|
|
2155
|
+
[source,ruby]
|
|
2156
|
+
----
|
|
2157
|
+
# Save to a specific file
|
|
2158
|
+
manifest.to_file("output_schemas.yml")
|
|
2159
|
+
|
|
2160
|
+
# Save to a path with automatic filename
|
|
2161
|
+
manifest.save_to_path("/path/to/output/")
|
|
2162
|
+
----
|
|
2163
|
+
|
|
2164
|
+
==== Concatenating manifests
|
|
2165
|
+
|
|
2166
|
+
Combine multiple manifests:
|
|
2167
|
+
|
|
2168
|
+
[source,ruby]
|
|
2169
|
+
----
|
|
2170
|
+
manifest1 = Expressir::SchemaManifest.from_file("schemas1.yml")
|
|
2171
|
+
manifest2 = Expressir::SchemaManifest.from_file("schemas2.yml")
|
|
2172
|
+
|
|
2173
|
+
# Concatenate manifests
|
|
2174
|
+
combined_manifest = manifest1.concat(manifest2)
|
|
2175
|
+
|
|
2176
|
+
# Or use the + operator
|
|
2177
|
+
combined_manifest = manifest1 + manifest2
|
|
2178
|
+
----
|
|
2179
|
+
|
|
2180
|
+
==== Using manifests with parsers
|
|
2181
|
+
|
|
2182
|
+
Parse all schemas from a manifest:
|
|
2183
|
+
|
|
2184
|
+
[source,ruby]
|
|
2185
|
+
----
|
|
2186
|
+
# Load manifest
|
|
2187
|
+
manifest = Expressir::SchemaManifest.from_file("schemas.yml")
|
|
2188
|
+
|
|
2189
|
+
# Get schema file paths
|
|
2190
|
+
schema_paths = manifest.schemas.map(&:path)
|
|
2191
|
+
|
|
2192
|
+
# Parse all schemas
|
|
2193
|
+
repository = Expressir::Express::Parser.from_files(schema_paths)
|
|
2194
|
+
|
|
2195
|
+
# With progress tracking
|
|
2196
|
+
repository = Expressir::Express::Parser.from_files(schema_paths) do |filename, schemas, error|
|
|
2197
|
+
if error
|
|
2198
|
+
puts "Error loading #{filename}: #{error.message}"
|
|
2199
|
+
else
|
|
2200
|
+
puts "Successfully loaded #{schemas.length} schemas from #{filename}"
|
|
2201
|
+
end
|
|
2202
|
+
end
|
|
2203
|
+
----
|
|
2204
|
+
|
|
2205
|
+
|
|
2206
|
+
|
|
2207
|
+
== LER packages
|
|
2208
|
+
|
|
2209
|
+
=== General
|
|
2210
|
+
|
|
2211
|
+
LER (LutaML EXPRESS Repository) is a package format for distributing EXPRESS
|
|
2212
|
+
schemas and related resources in a single binary file.
|
|
2213
|
+
|
|
2214
|
+
EXPRESS schemas often utilize `REFERENCE FROM` or `USE FROM` statements to
|
|
2215
|
+
import definitions from other schemas, and those referenced schemas
|
|
2216
|
+
can deviate across different versions. Managing these dependencies
|
|
2217
|
+
is crucial for maintaining compatibility.
|
|
2218
|
+
|
|
2219
|
+
The LER package format helps encapsulate these dependencies, ensuring that all
|
|
2220
|
+
required schemas are included and versioned correctly, allowing the package
|
|
2221
|
+
to be used reliably in different environments.
|
|
2222
|
+
|
|
2223
|
+
LER packages have the `.ler` file extension and are essentially ZIP archives
|
|
2224
|
+
containing:
|
|
2225
|
+
|
|
2226
|
+
* EXPRESS schema files (`.exp`)
|
|
2227
|
+
* Metadata files (`metadata.yaml`)
|
|
2228
|
+
* pre-parsed model cache (serialized Ruby objects)
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
=== Creating a package
|
|
2232
|
+
|
|
2233
|
+
Expressir provides a command-line interface for creating LER packages from
|
|
2234
|
+
an EXPRESS manifest.
|
|
2235
|
+
|
|
2236
|
+
Expressir supports building LER packages from EXPRESS schemas using a
|
|
2237
|
+
manifest-based workflow.
|
|
2238
|
+
|
|
2239
|
+
**Using a manifest (recommended for production)**::
|
|
2240
|
+
|
|
2241
|
+
[source,sh]
|
|
2242
|
+
----
|
|
2243
|
+
# Build from validated manifest
|
|
2244
|
+
expressir package build --manifest activity_manifest.yaml activity.ler \
|
|
2245
|
+
--name "Activity Module" \
|
|
2246
|
+
--validate
|
|
2247
|
+
----
|
|
2248
|
+
|
|
2249
|
+
**Using auto-resolution (quick prototyping)**:
|
|
2250
|
+
|
|
2251
|
+
[source,sh]
|
|
2252
|
+
----
|
|
2253
|
+
# Build from root schema with auto-resolution
|
|
2254
|
+
expressir package build schemas/activity/mim.exp activity.ler \
|
|
2255
|
+
--base-dirs ~/schemas/resources ~/schemas/modules \
|
|
2256
|
+
--name "Activity Module" \
|
|
2257
|
+
--validate
|
|
2258
|
+
----
|
|
2259
|
+
|
|
2260
|
+
Complete manifest workflow:
|
|
2261
|
+
|
|
2262
|
+
[source,sh]
|
|
2263
|
+
----
|
|
2264
|
+
# 1. Create manifest from root schema
|
|
2265
|
+
expressir manifest create schemas/activity/mim.exp \
|
|
2266
|
+
-o activity_manifest.yaml \
|
|
2267
|
+
--base-dirs ~/iso-10303/schemas \
|
|
2268
|
+
--name "Activity Module"
|
|
2269
|
+
|
|
2270
|
+
# 2. Edit manifest to add missing schema paths
|
|
2271
|
+
|
|
2272
|
+
# 3. Validate manifest
|
|
2273
|
+
expressir manifest validate activity_manifest.yaml
|
|
2274
|
+
|
|
2275
|
+
# 4. Build package from manifest
|
|
2276
|
+
expressir package build --manifest activity_manifest.yaml activity.ler
|
|
2277
|
+
----
|
|
2278
|
+
|
|
2279
|
+
|
|
2280
|
+
Unresolved schemas appear without `path:` field. Edit the manifest to add missing paths.
|
|
2281
|
+
|
|
2282
|
+
[source,yaml]
|
|
2283
|
+
----
|
|
2284
|
+
schemas:
|
|
2285
|
+
- name: action_schema
|
|
2286
|
+
path: /path/to/action_schema.exp
|
|
2287
|
+
- name: Activity_method_mim # Unresolved - no path
|
|
2288
|
+
----
|
|
2289
|
+
|
|
2290
|
+
|
|
2291
|
+
.`package build --manifest` - Build from manifest
|
|
2292
|
+
[source,sh]
|
|
2293
|
+
----
|
|
2294
|
+
expressir package build --manifest MANIFEST.yaml OUTPUT.ler [OPTIONS]
|
|
2295
|
+
----
|
|
2296
|
+
|
|
2297
|
+
See link:docs/_pages/ler-packages#manifest-workflow[LER Packages documentation] for complete details.
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
== Benchmarking
|
|
2302
|
+
|
|
2303
|
+
=== General
|
|
2304
|
+
|
|
2305
|
+
Expressir includes benchmarking tools to measure the performance of parsing and
|
|
2306
|
+
processing EXPRESS schemas.
|
|
2307
|
+
|
|
2308
|
+
=== Benchmarking with manifests
|
|
2309
|
+
|
|
2310
|
+
[source,sh]
|
|
2311
|
+
----
|
|
2312
|
+
# Benchmark all schemas in a manifest
|
|
2313
|
+
expressir benchmark schemas.yml --verbose
|
|
2314
|
+
|
|
2315
|
+
# Benchmark with caching
|
|
2316
|
+
expressir benchmark-cache schemas.yml --cache_path /tmp/cache.bin
|
|
2317
|
+
----
|
|
2318
|
+
|
|
2319
|
+
|
|
2320
|
+
== Coverage reporting
|
|
2321
|
+
|
|
2322
|
+
=== General
|
|
2323
|
+
|
|
2324
|
+
Expressir provides coverage analysis tools to evaluate the documentation
|
|
2325
|
+
coverage of EXPRESS schemas.
|
|
2326
|
+
|
|
2327
|
+
=== Coverage analysis with manifests
|
|
2328
|
+
|
|
2329
|
+
[source,sh]
|
|
2330
|
+
----
|
|
2331
|
+
# Analyze coverage for all schemas in manifest
|
|
2332
|
+
expressir coverage schemas.yml
|
|
2333
|
+
|
|
2334
|
+
# With output format and exclusions
|
|
2335
|
+
expressir coverage schemas.yml --format json --exclude=TYPE:SELECT
|
|
2336
|
+
----
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
== EXPRESS Changes
|
|
2341
|
+
|
|
2342
|
+
=== General
|
|
2343
|
+
|
|
2344
|
+
Expressir provides the `Changes` module for managing and tracking changes to
|
|
2345
|
+
EXPRESS schemas across versions. This module implements the EXPRESS Changes YAML
|
|
2346
|
+
format defined by ELF (Express Language Foundation) (ELF 5005).
|
|
2347
|
+
|
|
2348
|
+
The Changes module enables:
|
|
2349
|
+
|
|
2350
|
+
* Loading and saving schema change records from/to YAML files
|
|
2351
|
+
* Programmatic creation and manipulation of change records
|
|
2352
|
+
* Smart version handling (replace same version, add new version)
|
|
2353
|
+
* Support for all change types: additions, modifications, deletions
|
|
2354
|
+
* Support for mapping changes in ARM/MIM schemas
|
|
2355
|
+
* Programmatic import from Express Engine comparison XML files
|
|
2356
|
+
|
|
2357
|
+
|
|
2358
|
+
=== Importing from Express Engine XML programmatically
|
|
2359
|
+
|
|
2360
|
+
==== General
|
|
2361
|
+
|
|
2362
|
+
Expressir provides programmatic API access for parsing Express Engine comparison XML
|
|
2363
|
+
and converting it to EXPRESS Changes format.
|
|
2364
|
+
|
|
2365
|
+
Parse Eengine XML into a structured object model:
|
|
2366
|
+
|
|
2367
|
+
[source,ruby]
|
|
2368
|
+
----
|
|
2369
|
+
require "expressir/eengine/compare_report"
|
|
2370
|
+
|
|
2371
|
+
# Parse from XML string
|
|
2372
|
+
xml_content = File.read("comparison.xml")
|
|
2373
|
+
report = Expressir::Eengine::CompareReport.from_xml(xml_content)
|
|
2374
|
+
|
|
2375
|
+
# Or parse from file
|
|
2376
|
+
report = Expressir::Eengine::CompareReport.from_file("comparison.xml")
|
|
2377
|
+
----
|
|
2378
|
+
|
|
2379
|
+
Convert Eengine XML directly to EXPRESS Changes format:
|
|
2380
|
+
|
|
2381
|
+
[source,ruby]
|
|
2382
|
+
----
|
|
2383
|
+
require "expressir/commands/changes_import_eengine"
|
|
2384
|
+
|
|
2385
|
+
# Parse XML and convert to SchemaChange in one step
|
|
2386
|
+
xml_content = File.read("comparison.xml")
|
|
2387
|
+
change_schema = Expressir::Commands::ChangesImportEengine.from_xml(
|
|
2388
|
+
xml_content,
|
|
2389
|
+
"aic_csg", # schema name
|
|
2390
|
+
"1.0" # version
|
|
2391
|
+
)
|
|
2392
|
+
|
|
2393
|
+
# Use the SchemaChange object
|
|
2394
|
+
change_schema.versions.first.additions.each do |item|
|
|
2395
|
+
puts "#{item.type}: #{item.name}"
|
|
2396
|
+
puts " interfaced_items: #{item.interfaced_items}" if item.interfaced_items
|
|
2397
|
+
end
|
|
2398
|
+
|
|
2399
|
+
# Save to file
|
|
2400
|
+
change_schema.to_file("output.changes.yaml")
|
|
2401
|
+
----
|
|
2402
|
+
|
|
2403
|
+
=== Compare modes
|
|
2404
|
+
|
|
2405
|
+
==== General
|
|
2406
|
+
|
|
2407
|
+
Expressir automatically detects and parses all three Eengine XML modes.
|
|
2408
|
+
|
|
2409
|
+
[source,ruby]
|
|
2410
|
+
----
|
|
2411
|
+
# All modes are handled automatically
|
|
2412
|
+
arm_report = Expressir::Eengine::CompareReport.from_file("arm_comparison.xml")
|
|
2413
|
+
mim_report = Expressir::Eengine::CompareReport.from_file("mim_comparison.xml")
|
|
2414
|
+
schema_report = Expressir::Eengine::CompareReport.from_file("schema_comparison.xml")
|
|
2415
|
+
|
|
2416
|
+
puts arm_report.mode # => "arm"
|
|
2417
|
+
puts mim_report.mode # => "mim"
|
|
2418
|
+
puts schema_report.mode # => "schema"
|
|
2419
|
+
----
|
|
2420
|
+
|
|
2421
|
+
==== Schema mode
|
|
2422
|
+
|
|
2423
|
+
`<schema.changes>` with `<schema.additions>`, `<schema.modifications>`, `<schema.deletions>`
|
|
2424
|
+
|
|
2425
|
+
[example]
|
|
2426
|
+
====
|
|
2427
|
+
[source,xml]
|
|
2428
|
+
----
|
|
2429
|
+
<schema.changes schema_name="aic_csg">
|
|
2430
|
+
<schema.additions>
|
|
2431
|
+
<modified.object type="ENTITY" name="new_entity" />
|
|
2432
|
+
</schema.additions>
|
|
2433
|
+
<schema.modifications>
|
|
2434
|
+
<modified.object type="TYPE" name="modified_type" />
|
|
2435
|
+
</schema.modifications>
|
|
2436
|
+
<schema.deletions>
|
|
2437
|
+
<modified.object type="FUNCTION" name="removed_function" />
|
|
2438
|
+
</schema.deletions>
|
|
2439
|
+
</schema.changes>
|
|
2440
|
+
----
|
|
2441
|
+
====
|
|
2442
|
+
|
|
2443
|
+
==== ARM mode
|
|
2444
|
+
|
|
2445
|
+
`<arm.changes>` root element with `<arm.additions>`,
|
|
2446
|
+
`<arm.modifications>`, and `<arm.deletions>` sections
|
|
2447
|
+
|
|
2448
|
+
[example]
|
|
2449
|
+
====
|
|
2450
|
+
[source,xml]
|
|
2451
|
+
----
|
|
2452
|
+
<arm.changes schema_name="example_arm">
|
|
2453
|
+
<arm.additions>
|
|
2454
|
+
<modified.object type="ENTITY" name="new_arm_entity" />
|
|
2455
|
+
</arm.additions>
|
|
2456
|
+
</arm.changes>
|
|
2457
|
+
----
|
|
2458
|
+
====
|
|
2459
|
+
|
|
2460
|
+
|
|
2461
|
+
==== MIM mode
|
|
2462
|
+
|
|
2463
|
+
`<mim.changes>` root element with `<mim.additions>`,
|
|
2464
|
+
`<mim.modifications>`, and `<mim.deletions>` sections
|
|
2465
|
+
|
|
2466
|
+
[example]
|
|
2467
|
+
====
|
|
2468
|
+
[source,xml]
|
|
2469
|
+
----
|
|
2470
|
+
<mim.changes schema_name="example_mim">
|
|
2471
|
+
<mim.additions>
|
|
2472
|
+
<modified.object type="ENTITY" name="new_mim_entity" />
|
|
2473
|
+
</mim.additions>
|
|
2474
|
+
</mim.changes>
|
|
2475
|
+
----
|
|
2476
|
+
====
|
|
2477
|
+
|
|
2478
|
+
=== Interface changes
|
|
2479
|
+
|
|
2480
|
+
The eengine XML format tracks interface changes (USE_FROM, REFERENCE_FROM) with
|
|
2481
|
+
the `interfaced.items` attribute. This attribute lists the specific items being
|
|
2482
|
+
imported or referenced from another schema.
|
|
2483
|
+
|
|
2484
|
+
.Example XML with interface changes
|
|
2485
|
+
[example]
|
|
2486
|
+
====
|
|
2487
|
+
[source,xml]
|
|
2488
|
+
----
|
|
2489
|
+
<schema.changes schema_name="aic_csg">
|
|
2490
|
+
<schema.additions>
|
|
2491
|
+
<modified.object type="USE_FROM" name="geometric_model_schema"
|
|
2492
|
+
interfaced.items="convex_hexahedron" />
|
|
2493
|
+
|
|
2494
|
+
<modified.object type="USE_FROM" name="geometric_model_schema"
|
|
2495
|
+
interfaced.items="cyclide_segment_solid" />
|
|
2496
|
+
|
|
2497
|
+
<modified.object type="REFERENCE_FROM" name="measure_schema"
|
|
2498
|
+
interfaced.items="length_measure" />
|
|
2499
|
+
</schema.additions>
|
|
2500
|
+
</schema.changes>
|
|
2501
|
+
----
|
|
2502
|
+
|
|
2503
|
+
This will be converted to EXPRESS Changes YAML as:
|
|
2504
|
+
|
|
2505
|
+
[source,yaml]
|
|
2506
|
+
----
|
|
2507
|
+
schema: aic_csg
|
|
2508
|
+
versions:
|
|
2509
|
+
- version: 2
|
|
2510
|
+
description: Changes from eengine comparison
|
|
2511
|
+
additions:
|
|
2512
|
+
- type: USE_FROM
|
|
2513
|
+
name: geometric_model_schema
|
|
2514
|
+
interfaced_items: convex_hexahedron
|
|
2515
|
+
- type: USE_FROM
|
|
2516
|
+
name: geometric_model_schema
|
|
2517
|
+
interfaced_items: cyclide_segment_solid
|
|
2518
|
+
- type: REFERENCE_FROM
|
|
2519
|
+
name: measure_schema
|
|
2520
|
+
interfaced_items: length_measure
|
|
2521
|
+
----
|
|
2522
|
+
====
|
|
2523
|
+
|
|
2524
|
+
Eengine XML files track interface changes (USE_FROM, REFERENCE_FROM) with the
|
|
2525
|
+
`interfaced.items` attribute:
|
|
2526
|
+
|
|
2527
|
+
[source,ruby]
|
|
2528
|
+
----
|
|
2529
|
+
report = Expressir::Eengine::CompareReport.from_file("comparison.xml")
|
|
2530
|
+
|
|
2531
|
+
# Find interface changes
|
|
2532
|
+
report.additions&.modified_objects&.each do |obj|
|
|
2533
|
+
if obj.type == "USE_FROM" || obj.type == "REFERENCE_FROM"
|
|
2534
|
+
puts "#{obj.type} #{obj.name}"
|
|
2535
|
+
puts " Items: #{obj.interfaced_items}" if obj.interfaced_items
|
|
2536
|
+
end
|
|
2537
|
+
end
|
|
2538
|
+
----
|
|
2539
|
+
|
|
2540
|
+
|
|
2541
|
+
=== Supported change types
|
|
2542
|
+
|
|
2543
|
+
The import command recognizes all standard EXPRESS construct types:
|
|
2544
|
+
|
|
2545
|
+
* `ENTITY` - Entity definitions
|
|
2546
|
+
* `TYPE` - Type definitions
|
|
2547
|
+
* `FUNCTION` - Function definitions
|
|
2548
|
+
* `PROCEDURE` - Procedure definitions
|
|
2549
|
+
* `RULE` - Rule definitions
|
|
2550
|
+
* `CONSTANT` - Constant definitions
|
|
2551
|
+
* `USE_FROM` - Interface imports (preserves `interfaced.items`)
|
|
2552
|
+
* `REFERENCE_FROM` - Interface references (preserves `interfaced.items`)
|
|
2553
|
+
|
|
2554
|
+
|
|
2555
|
+
=== Reading change files
|
|
2556
|
+
|
|
2557
|
+
Load an existing schema change file:
|
|
2558
|
+
|
|
2559
|
+
[source,ruby]
|
|
2560
|
+
----
|
|
2561
|
+
require "expressir/changes"
|
|
2562
|
+
|
|
2563
|
+
# Load from file
|
|
2564
|
+
change_schema = Expressir::Changes::SchemaChange.from_file("schema.changes.yaml")
|
|
2565
|
+
|
|
2566
|
+
# Access schema name
|
|
2567
|
+
puts "Schema: #{change_schema.schema}"
|
|
2568
|
+
|
|
2569
|
+
# Iterate through change versions
|
|
2570
|
+
change_schema.versions.each do |version|
|
|
2571
|
+
puts "Version #{version.version}: #{version.description}"
|
|
2572
|
+
|
|
2573
|
+
# Access changes by type
|
|
2574
|
+
puts " Additions: #{version.additions.size}" if version.additions
|
|
2575
|
+
puts " Modifications: #{version.modifications.size}" if version.modifications
|
|
2576
|
+
puts " Deletions: #{version.deletions.size}" if version.deletions
|
|
2577
|
+
end
|
|
2578
|
+
----
|
|
2579
|
+
|
|
2580
|
+
=== Creating change records
|
|
2581
|
+
|
|
2582
|
+
Create a new change schema programmatically:
|
|
2583
|
+
|
|
2584
|
+
[source,ruby]
|
|
2585
|
+
----
|
|
2586
|
+
# Create a new empty change schema
|
|
2587
|
+
change_schema = Expressir::Changes::SchemaChange.new(schema: "my_schema")
|
|
2588
|
+
|
|
2589
|
+
# Create change items
|
|
2590
|
+
new_entity = Expressir::Changes::ItemChange.new(
|
|
2591
|
+
type: "ENTITY",
|
|
2592
|
+
name: "new_entity_name"
|
|
2593
|
+
)
|
|
2594
|
+
|
|
2595
|
+
modified_function = Expressir::Changes::ItemChange.new(
|
|
2596
|
+
type: "FUNCTION",
|
|
2597
|
+
name: "modified_function",
|
|
2598
|
+
description: "Updated parameters"
|
|
2599
|
+
)
|
|
2600
|
+
|
|
2601
|
+
# Add a change version
|
|
2602
|
+
changes = {
|
|
2603
|
+
additions: [new_entity],
|
|
2604
|
+
modifications: [modified_function],
|
|
2605
|
+
deletions: []
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
change_schema.add_or_update_version(
|
|
2609
|
+
"2",
|
|
2610
|
+
"Added new entity and modified function",
|
|
2611
|
+
changes
|
|
2612
|
+
)
|
|
2613
|
+
|
|
2614
|
+
# Save to file
|
|
2615
|
+
change_schema.to_file("my_schema.changes.yaml")
|
|
2616
|
+
----
|
|
2617
|
+
|
|
2618
|
+
=== Updating existing change files
|
|
2619
|
+
|
|
2620
|
+
The `add_or_update_version` method provides smart handling:
|
|
2621
|
+
|
|
2622
|
+
* **Same version**: Replaces the existing version
|
|
2623
|
+
* **Different version**: Adds a new version
|
|
2624
|
+
|
|
2625
|
+
[source,ruby]
|
|
2626
|
+
----
|
|
2627
|
+
# Load existing change file
|
|
2628
|
+
change_schema = Expressir::Changes::SchemaChange.from_file("schema.changes.yaml")
|
|
2629
|
+
|
|
2630
|
+
# Add a new version
|
|
2631
|
+
changes = {
|
|
2632
|
+
modifications: [
|
|
2633
|
+
Expressir::Changes::ItemChange.new(type: "TYPE", name: "updated_type")
|
|
2634
|
+
]
|
|
2635
|
+
}
|
|
2636
|
+
change_schema.add_or_update_version("3", "Modified type definition", changes)
|
|
2637
|
+
|
|
2638
|
+
# Or replace existing version
|
|
2639
|
+
change_schema.add_or_update_version("2", "Revised description", changes)
|
|
2640
|
+
|
|
2641
|
+
# Save changes
|
|
2642
|
+
change_schema.to_file("schema.changes.yaml")
|
|
2643
|
+
----
|
|
2644
|
+
|
|
2645
|
+
=== Change item fields
|
|
2646
|
+
|
|
2647
|
+
Change items support the following fields:
|
|
2648
|
+
|
|
2649
|
+
`type`:: (Required) The EXPRESS construct type (ENTITY, TYPE, FUNCTION, etc.)
|
|
2650
|
+
`name`:: (Required) The name of the construct
|
|
2651
|
+
`description`:: (Optional) Additional details about the change
|
|
2652
|
+
`interfaced_items`:: (Optional) For REFERENCE_FROM items
|
|
2653
|
+
|
|
2654
|
+
[source,ruby]
|
|
2655
|
+
----
|
|
2656
|
+
item = Expressir::Changes::ItemChange.new(
|
|
2657
|
+
type: "REFERENCE_FROM",
|
|
2658
|
+
name: "measure_schema",
|
|
2659
|
+
interfaced_items: "length_measure"
|
|
2660
|
+
)
|
|
2661
|
+
----
|
|
2662
|
+
|
|
2663
|
+
=== Change version fields
|
|
2664
|
+
|
|
2665
|
+
Change versions support categorizing changes into:
|
|
2666
|
+
|
|
2667
|
+
`additions`:: New elements added to the schema
|
|
2668
|
+
`modifications`:: Existing elements that were modified
|
|
2669
|
+
`deletions`:: Elements removed from the schema
|
|
2670
|
+
`mappings`:: Mapping-related changes (for ARM/MIM modules)
|
|
2671
|
+
`changes`:: General changes (alternative to mapping)
|
|
2672
|
+
|
|
2673
|
+
[source,ruby]
|
|
2674
|
+
----
|
|
2675
|
+
version = Expressir::Changes::VersionChange.new(
|
|
2676
|
+
version: "2",
|
|
2677
|
+
description: "Added support for new functionality",
|
|
2678
|
+
additions: [item1, item2],
|
|
2679
|
+
modifications: [item3],
|
|
2680
|
+
deletions: [item4],
|
|
2681
|
+
mappings: [mapping_change]
|
|
2682
|
+
)
|
|
2683
|
+
----
|
|
2684
|
+
|
|
2685
|
+
=== Mapping changes
|
|
2686
|
+
|
|
2687
|
+
For ARM/MIM schema mappings, use `MappingChange`:
|
|
2688
|
+
|
|
2689
|
+
[source,ruby]
|
|
2690
|
+
----
|
|
2691
|
+
mapping_change = Expressir::Changes::MappingChange.new(
|
|
2692
|
+
change: "Entity_name ENTITY mapping updated"
|
|
2693
|
+
)
|
|
2694
|
+
----
|
|
2695
|
+
|
|
2696
|
+
=== Example change file format
|
|
2697
|
+
|
|
2698
|
+
[source,yaml]
|
|
2699
|
+
----
|
|
2700
|
+
---
|
|
2701
|
+
schema: support_resource_schema
|
|
2702
|
+
versions:
|
|
2703
|
+
- version: 2
|
|
2704
|
+
description: |-
|
|
2705
|
+
The definitions of the following EXPRESS entity data types were modified:
|
|
2706
|
+
|
|
2707
|
+
* action;
|
|
2708
|
+
* action_directive;
|
|
2709
|
+
* action_method.
|
|
2710
|
+
additions:
|
|
2711
|
+
- type: FUNCTION
|
|
2712
|
+
name: type_check_function
|
|
2713
|
+
modifications:
|
|
2714
|
+
- type: FUNCTION
|
|
2715
|
+
name: bag_to_set
|
|
2716
|
+
- version: 4
|
|
2717
|
+
description: |-
|
|
2718
|
+
Added support for external element references.
|
|
2719
|
+
additions:
|
|
2720
|
+
- type: ENTITY
|
|
2721
|
+
name: component_path_shape_aspect
|
|
2722
|
+
modifications:
|
|
2723
|
+
- type: FUNCTION
|
|
2724
|
+
name: type_check_function
|
|
2725
|
+
----
|
|
2726
|
+
|
|
2727
|
+
== Contributing
|
|
2728
|
+
|
|
2729
|
+
First, thank you for contributing! We love pull requests from everyone. By
|
|
2730
|
+
participating in this project, you hereby grant
|
|
2731
|
+
https://www.ribose.com[Ribose Inc.] the right to grant or transfer an unlimited
|
|
2732
|
+
number of non exclusive licenses or sub-licenses to third parties, under the
|
|
2733
|
+
copyright covering the contribution to use the contribution by all means.
|
|
2734
|
+
|
|
2735
|
+
Here are a few technical guidelines to follow:
|
|
2736
|
+
|
|
2737
|
+
* Open an https://github.com/lutaml/expressir/issues[issues] to discuss a new
|
|
2738
|
+
feature.
|
|
2739
|
+
* Write tests to support your new feature.
|
|
2740
|
+
* Make sure the entire test suite passes locally and on CI.
|
|
2741
|
+
* Open a Pull Request.
|
|
2742
|
+
* https://github.com/thoughtbot/guides/tree/master/protocol/git#write-a-feature[Squash your commits] after receiving feedback.
|
|
2743
|
+
* Party!
|
|
2744
|
+
|
|
2745
|
+
|
|
2746
|
+
== Documentation
|
|
2747
|
+
|
|
2748
|
+
Expressir provides detailed documentation on various aspects of its functionality:
|
|
2749
|
+
|
|
2750
|
+
* link:docs/benchmarking.adoc[Benchmarking]: Learn about Expressir's built-in
|
|
2751
|
+
capabilities for measuring schema loading performance, particularly useful for
|
|
2752
|
+
large schemas or when optimizing performance.
|
|
2753
|
+
|
|
2754
|
+
* link:docs/liquid_drops.adoc[Liquid Integration]: Documentation on how to use
|
|
2755
|
+
Expressir models with Liquid templates for flexible document generation.
|
|
2756
|
+
|
|
2757
|
+
== License
|
|
2758
|
+
|
|
2759
|
+
Expressir is distributed under the BSD 2-clause license.
|
|
2760
|
+
|
|
2761
|
+
NOTE: Expressir originally contained some code from the NIST Reeper project but no
|
|
2762
|
+
longer contains them.
|
|
2763
|
+
|
|
2764
|
+
The https://www.nist.gov/services-resources/software/reeper[NIST Reeper license]
|
|
2765
|
+
is reproduced below:
|
|
2766
|
+
|
|
2767
|
+
[quote]
|
|
2768
|
+
____
|
|
2769
|
+
This software was funded by NIST and developed by EuroSTEP.
|
|
2770
|
+
Pursuant to title 17 Section 105 of the United States Code this
|
|
2771
|
+
software is not subject to copyright protection and is in the public
|
|
2772
|
+
domain.
|
|
2773
|
+
|
|
2774
|
+
We would appreciate acknowledgment if the software is used. Links to
|
|
2775
|
+
non-Federal Government Web sites do not imply NIST endorsement of any
|
|
2776
|
+
particular product, service, organization, company, information
|
|
2777
|
+
provider, or content.
|
|
2778
|
+
____
|
|
2779
|
+
|
|
2780
|
+
|
|
2781
|
+
== Credits
|
|
2782
|
+
|
|
2783
|
+
Copyright Ribose Inc.
|