expressir 1.2.10-aarch64-linux → 2.4.29-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config.toml +3 -0
  3. data/.github/scripts/test_installed_gem.rb +34 -0
  4. data/.github/workflows/codeql.yml +35 -0
  5. data/.github/workflows/docs.yml +99 -0
  6. data/.github/workflows/links.yml +100 -0
  7. data/.github/workflows/native-gems.yml +201 -0
  8. data/.github/workflows/rake.yml +10 -296
  9. data/.github/workflows/release.yml +26 -114
  10. data/.github/workflows/rust-ext.yml +41 -0
  11. data/.github/workflows/stress.yml +36 -0
  12. data/.github/workflows/validate_schemas.yml +48 -0
  13. data/.github/workflows/verify_remarks.yml +33 -0
  14. data/.gitignore +33 -1
  15. data/.rubocop.yml +11 -11
  16. data/.rubocop_todo.yml +297 -0
  17. data/CHANGELOG.md +159 -0
  18. data/Gemfile +15 -1
  19. data/README.adoc +2675 -47
  20. data/Rakefile +34 -10
  21. data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
  22. data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
  23. data/TODO.bugs/03-builder-mutable-state.md +43 -0
  24. data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
  25. data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
  26. data/TODO.bugs/06-collection-registry-single-source.md +53 -0
  27. data/TODO.bugs/07-require-relative-cleanup.md +42 -0
  28. data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
  29. data/TODO.bugs/09-parser-split.md +53 -0
  30. data/TODO.bugs/10-to-s-override.md +42 -0
  31. data/TODO.bugs/11-parser-class-variables.md +39 -0
  32. data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
  33. data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
  34. data/TODO.bugs/14-model-formatting-leak.md +30 -0
  35. data/TODO.bugs/15-expression-children-macro.md +27 -0
  36. data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
  37. data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
  38. data/TODO.bugs/18-const-get-private-constants.md +30 -0
  39. data/TODO.bugs/19-format-methods-public.md +22 -0
  40. data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
  41. data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
  42. data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
  43. data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
  44. data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
  45. data/TODO.bugs/25-debug-puts-in-production.md +21 -0
  46. data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
  47. data/TODO.bugs/27-package-build-god-method.md +19 -0
  48. data/TODO.bugs/28-package-god-class.md +30 -0
  49. data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
  50. data/TODO.bugs/30-unicode-map-extraction.md +19 -0
  51. data/TODO.bugs/README.md +43 -0
  52. data/TODO.max-perf/01-restore-ci-green.md +36 -0
  53. data/TODO.max-perf/02-streaming-parse-path.md +31 -0
  54. data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
  55. data/TODO.max-perf/04-benchmark-harness.md +28 -0
  56. data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
  57. data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
  58. data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
  59. data/TODO.max-perf/08-builder-build-perf.md +45 -0
  60. data/TODO.max-perf/09-grammar-cold-start.md +25 -0
  61. data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
  62. data/TODO.max-perf/11-ci-green-closeout.md +25 -0
  63. data/TODO.max-perf/12-require-boot-profile.md +25 -0
  64. data/TODO.max-perf/13-key-conversion-specs.md +26 -0
  65. data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
  66. data/TODO.parity-ee/00-overview.md +76 -0
  67. data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
  68. data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
  69. data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
  70. data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
  71. data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
  72. data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
  73. data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
  74. data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
  75. data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
  76. data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
  77. data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
  78. data/TODO.parity-ee/12-full-check-catalog.md +67 -0
  79. data/TODO.parity-ee/13-population-p21.md +54 -0
  80. data/TODO.parity-ee/14-shtolo-completion.md +44 -0
  81. data/TODO.parity-ee/15-part28-xml.md +51 -0
  82. data/TODO.parity-ee/16-compare-patch.md +48 -0
  83. data/TODO.parity-ee/17-official-tests.md +42 -0
  84. data/TODO.parity-ee/18-mim-mapping.md +47 -0
  85. data/TODO.parity-ee/19-architecture.md +97 -0
  86. data/TODO.parity-ee/parity-matrix.md +108 -0
  87. data/TODO.refpath-v2/00-overview.md +64 -0
  88. data/TODO.suma-improvements/00-overview.md +23 -0
  89. data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
  90. data/TODO.suma-improvements/02-suma-e2e.md +39 -0
  91. data/TODO.suma-improvements/03-item-graph.md +22 -0
  92. data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
  93. data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
  94. data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
  95. data/TODO.suma-improvements/07-part28-xml.md +15 -0
  96. data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
  97. data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
  98. data/TODO.suma-improvements/10-expressdoc.md +8 -0
  99. data/benchmark/srl_benchmark.rb +458 -0
  100. data/benchmark/srl_native_benchmark.rb +146 -0
  101. data/benchmark/srl_ruby_benchmark.rb +132 -0
  102. data/bin/rspec +2 -1
  103. data/docs/Gemfile +12 -0
  104. data/docs/_config.yml +141 -0
  105. data/docs/_guides/changes/changes-format.adoc +778 -0
  106. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  107. data/docs/_guides/changes/index.adoc +396 -0
  108. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  109. data/docs/_guides/changes/validating-changes.adoc +681 -0
  110. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  111. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  112. data/docs/_guides/cli/format-schemas.adoc +547 -0
  113. data/docs/_guides/cli/index.adoc +8 -0
  114. data/docs/_guides/cli/managing-changes.adoc +927 -0
  115. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  116. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  117. data/docs/_guides/formatter/formatter-architecture.adoc +401 -0
  118. data/docs/_guides/index.adoc +165 -0
  119. data/docs/_guides/ler/creating-packages.adoc +664 -0
  120. data/docs/_guides/ler/index.adoc +305 -0
  121. data/docs/_guides/ler/loading-packages.adoc +707 -0
  122. data/docs/_guides/ler/package-formats.adoc +748 -0
  123. data/docs/_guides/ler/querying-packages.adoc +826 -0
  124. data/docs/_guides/ler/step-packages.adoc +385 -0
  125. data/docs/_guides/ler/validating-packages.adoc +750 -0
  126. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  127. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  128. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  129. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  130. data/docs/_guides/liquid/index.adoc +468 -0
  131. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  132. data/docs/_guides/manifests/index.adoc +307 -0
  133. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  134. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  135. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  136. data/docs/_guides/ruby-api/index.adoc +257 -0
  137. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  138. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  139. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  140. data/docs/_pages/data-model.adoc +665 -0
  141. data/docs/_pages/express-language.adoc +506 -0
  142. data/docs/_pages/getting-started.adoc +414 -0
  143. data/docs/_pages/index.adoc +116 -0
  144. data/docs/_pages/introduction.adoc +256 -0
  145. data/docs/_pages/ler-packages.adoc +837 -0
  146. data/docs/_pages/parsers.adoc +709 -0
  147. data/docs/_pages/schema-manifests.adoc +431 -0
  148. data/docs/_references/index.adoc +228 -0
  149. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  150. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  151. data/docs/_tutorials/formatting-schemas.adoc +89 -0
  152. data/docs/_tutorials/index.adoc +231 -0
  153. data/docs/_tutorials/liquid-templates.adoc +806 -0
  154. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  155. data/docs/_tutorials/querying-schemas.adoc +751 -0
  156. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  157. data/docs/index.adoc +242 -0
  158. data/docs/lychee.toml +90 -0
  159. data/examples/demo_ler_usage.sh +86 -0
  160. data/examples/ler/README.md +111 -0
  161. data/examples/ler/simple_example.ler +0 -0
  162. data/examples/ler/simple_schema.exp +33 -0
  163. data/examples/ler_build.rb +75 -0
  164. data/examples/ler_cli.rb +79 -0
  165. data/examples/ler_demo_complete.rb +276 -0
  166. data/examples/ler_query.rb +91 -0
  167. data/examples/ler_query_examples.rb +305 -0
  168. data/examples/ler_stats.rb +81 -0
  169. data/examples/phase3_demo.rb +159 -0
  170. data/examples/query_demo_simple.rb +131 -0
  171. data/exe/expressir +6 -17
  172. data/exe/expressir-format +14 -0
  173. data/exe/{format-test → expressir-format-test} +8 -7
  174. data/expressir.gemspec +50 -37
  175. data/lib/expressir/3.2/expressir_core.so +0 -0
  176. data/lib/expressir/3.3/expressir_core.so +0 -0
  177. data/lib/expressir/3.4/expressir_core.so +0 -0
  178. data/lib/expressir/4.0/expressir_core.so +0 -0
  179. data/lib/expressir/benchmark.rb +310 -0
  180. data/lib/expressir/changes/item_change.rb +20 -0
  181. data/lib/expressir/changes/mapping_change.rb +16 -0
  182. data/lib/expressir/changes/schema_change.rb +85 -0
  183. data/lib/expressir/changes/version_change.rb +26 -0
  184. data/lib/expressir/changes.rb +9 -0
  185. data/lib/expressir/cli.rb +138 -11
  186. data/lib/expressir/commands/base.rb +25 -0
  187. data/lib/expressir/commands/benchmark.rb +59 -0
  188. data/lib/expressir/commands/benchmark_cache.rb +80 -0
  189. data/lib/expressir/commands/changes.rb +34 -0
  190. data/lib/expressir/commands/changes_import_eengine.rb +146 -0
  191. data/lib/expressir/commands/changes_validate.rb +63 -0
  192. data/lib/expressir/commands/check.rb +56 -0
  193. data/lib/expressir/commands/clean.rb +20 -0
  194. data/lib/expressir/commands/coverage.rb +458 -0
  195. data/lib/expressir/commands/expand.rb +26 -0
  196. data/lib/expressir/commands/file_violations.rb +70 -0
  197. data/lib/expressir/commands/fix.rb +33 -0
  198. data/lib/expressir/commands/flatten.rb +29 -0
  199. data/lib/expressir/commands/format.rb +43 -0
  200. data/lib/expressir/commands/manifest.rb +420 -0
  201. data/lib/expressir/commands/mapping_validate.rb +68 -0
  202. data/lib/expressir/commands/non_ascii_character.rb +49 -0
  203. data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
  204. data/lib/expressir/commands/package.rb +1222 -0
  205. data/lib/expressir/commands/parity_inputs.rb +160 -0
  206. data/lib/expressir/commands/validate.rb +106 -0
  207. data/lib/expressir/commands/validate_ascii.rb +94 -0
  208. data/lib/expressir/commands/validate_load.rb +91 -0
  209. data/lib/expressir/commands/version.rb +9 -0
  210. data/lib/expressir/commands/xsd.rb +23 -0
  211. data/lib/expressir/commands.rb +30 -0
  212. data/lib/expressir/config.rb +40 -3
  213. data/lib/expressir/coverage.rb +510 -0
  214. data/lib/expressir/eengine/arm_compare_report.rb +23 -0
  215. data/lib/expressir/eengine/changes_section.rb +16 -0
  216. data/lib/expressir/eengine/compare_report.rb +69 -0
  217. data/lib/expressir/eengine/mim_compare_report.rb +23 -0
  218. data/lib/expressir/eengine/modified_object.rb +21 -0
  219. data/lib/expressir/eengine.rb +9 -0
  220. data/lib/expressir/errors.rb +113 -0
  221. data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
  222. data/lib/expressir/express/adoc_source_formatter.rb +12 -0
  223. data/lib/expressir/express/ast_key_converter.rb +114 -0
  224. data/lib/expressir/express/builder.rb +277 -0
  225. data/lib/expressir/express/builder_context.rb +22 -0
  226. data/lib/expressir/express/builder_registry.rb +397 -0
  227. data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
  228. data/lib/expressir/express/builders/built_in_builder.rb +75 -0
  229. data/lib/expressir/express/builders/constant_builder.rb +108 -0
  230. data/lib/expressir/express/builders/declaration_builder.rb +20 -0
  231. data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
  232. data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
  233. data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
  234. data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
  235. data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
  236. data/lib/expressir/express/builders/expression_builder.rb +416 -0
  237. data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
  238. data/lib/expressir/express/builders/helpers.rb +148 -0
  239. data/lib/expressir/express/builders/interface_builder.rb +151 -0
  240. data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
  241. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
  242. data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
  243. data/lib/expressir/express/builders/literal_builder.rb +93 -0
  244. data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
  245. data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
  246. data/lib/expressir/express/builders/reference_builder.rb +18 -0
  247. data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
  248. data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
  249. data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
  250. data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
  251. data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
  252. data/lib/expressir/express/builders/statement_builder.rb +243 -0
  253. data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
  254. data/lib/expressir/express/builders/syntax_builder.rb +30 -0
  255. data/lib/expressir/express/builders/type_builder.rb +238 -0
  256. data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
  257. data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
  258. data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
  259. data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
  260. data/lib/expressir/express/builders.rb +55 -0
  261. data/lib/expressir/express/cache.rb +43 -18
  262. data/lib/expressir/express/checker.rb +812 -0
  263. data/lib/expressir/express/concatenator.rb +79 -0
  264. data/lib/expressir/express/core.rb +95 -0
  265. data/lib/expressir/express/error.rb +124 -0
  266. data/lib/expressir/express/formatter.rb +89 -1548
  267. data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
  268. data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
  269. data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
  270. data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
  271. data/lib/expressir/express/formatters/references_formatter.rb +53 -0
  272. data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
  273. data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
  274. data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
  275. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
  276. data/lib/expressir/express/formatters.rb +22 -0
  277. data/lib/expressir/express/grammar/parser.rb +712 -0
  278. data/lib/expressir/express/grammar.rb +11 -0
  279. data/lib/expressir/express/hyperlink_formatter.rb +4 -5
  280. data/lib/expressir/express/interface_dot.rb +105 -0
  281. data/lib/expressir/express/lazy_repository.rb +211 -0
  282. data/lib/expressir/express/line_map.rb +48 -0
  283. data/lib/expressir/express/listing.rb +174 -0
  284. data/lib/expressir/express/model_traversal.rb +42 -0
  285. data/lib/expressir/express/model_visitor.rb +11 -10
  286. data/lib/expressir/express/node_position_index.rb +342 -0
  287. data/lib/expressir/express/parallel_files.rb +229 -0
  288. data/lib/expressir/express/parser.rb +501 -62
  289. data/lib/expressir/express/pretty_formatter.rb +586 -0
  290. data/lib/expressir/express/pretty_gate.rb +61 -0
  291. data/lib/expressir/express/refs_overlay.rb +47 -0
  292. data/lib/expressir/express/remark_attacher.rb +1098 -0
  293. data/lib/expressir/express/remark_overlay.rb +86 -0
  294. data/lib/expressir/express/remark_scanner.rb +245 -0
  295. data/lib/expressir/express/resolve_references_model_visitor.rb +7 -9
  296. data/lib/expressir/express/schema_block_scanner.rb +137 -0
  297. data/lib/expressir/express/schema_head_formatter.rb +4 -5
  298. data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
  299. data/lib/expressir/express/schema_source_formatter.rb +15 -0
  300. data/lib/expressir/express/scope_resolver.rb +223 -0
  301. data/lib/expressir/express/self_schema_reference.rb +126 -0
  302. data/lib/expressir/express/shtolo.rb +679 -0
  303. data/lib/expressir/express/smrl_xml.rb +125 -0
  304. data/lib/expressir/express/source_formatter.rb +15 -0
  305. data/lib/expressir/express/streaming_builder.rb +435 -0
  306. data/lib/expressir/express/xsd.rb +259 -0
  307. data/lib/expressir/express.rb +53 -0
  308. data/lib/expressir/liquid.rb +1 -0
  309. data/lib/expressir/manifest/resolver.rb +210 -0
  310. data/lib/expressir/manifest/validator.rb +192 -0
  311. data/lib/expressir/manifest.rb +6 -0
  312. data/lib/expressir/mapping/refpath.rb +857 -0
  313. data/lib/expressir/mapping.rb +253 -0
  314. data/lib/expressir/model/cache.rb +10 -9
  315. data/lib/expressir/model/concerns.rb +42 -0
  316. data/lib/expressir/model/data_types/aggregate.rb +8 -13
  317. data/lib/expressir/model/data_types/array.rb +15 -21
  318. data/lib/expressir/model/data_types/bag.rb +11 -15
  319. data/lib/expressir/model/data_types/binary.rb +9 -12
  320. data/lib/expressir/model/data_types/boolean.rb +7 -2
  321. data/lib/expressir/model/data_types/enumeration.rb +11 -15
  322. data/lib/expressir/model/data_types/enumeration_item.rb +5 -7
  323. data/lib/expressir/model/data_types/generic.rb +6 -8
  324. data/lib/expressir/model/data_types/generic_entity.rb +11 -13
  325. data/lib/expressir/model/data_types/integer.rb +7 -2
  326. data/lib/expressir/model/data_types/list.rb +13 -18
  327. data/lib/expressir/model/data_types/logical.rb +7 -2
  328. data/lib/expressir/model/data_types/number.rb +7 -2
  329. data/lib/expressir/model/data_types/real.rb +7 -9
  330. data/lib/expressir/model/data_types/select.rb +13 -18
  331. data/lib/expressir/model/data_types/set.rb +11 -15
  332. data/lib/expressir/model/data_types/string.rb +9 -12
  333. data/lib/expressir/model/data_types.rb +25 -0
  334. data/lib/expressir/model/declarations/attribute.rb +19 -28
  335. data/lib/expressir/model/declarations/constant.rb +10 -16
  336. data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
  337. data/lib/expressir/model/declarations/entity.rb +39 -30
  338. data/lib/expressir/model/declarations/function.rb +32 -40
  339. data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
  340. data/lib/expressir/model/declarations/interface.rb +25 -16
  341. data/lib/expressir/model/declarations/interface_item.rb +9 -11
  342. data/lib/expressir/model/declarations/interfaced_item.rb +15 -19
  343. data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
  344. data/lib/expressir/model/declarations/parameter.rb +10 -16
  345. data/lib/expressir/model/declarations/procedure.rb +30 -37
  346. data/lib/expressir/model/declarations/remark_item.rb +11 -11
  347. data/lib/expressir/model/declarations/rule.rb +38 -43
  348. data/lib/expressir/model/declarations/schema.rb +162 -64
  349. data/lib/expressir/model/declarations/schema_version.rb +8 -11
  350. data/lib/expressir/model/declarations/schema_version_item.rb +8 -11
  351. data/lib/expressir/model/declarations/subtype_constraint.rb +14 -22
  352. data/lib/expressir/model/declarations/type.rb +18 -18
  353. data/lib/expressir/model/declarations/unique_rule.rb +8 -13
  354. data/lib/expressir/model/declarations/variable.rb +10 -16
  355. data/lib/expressir/model/declarations/where_rule.rb +8 -13
  356. data/lib/expressir/model/declarations.rb +31 -0
  357. data/lib/expressir/model/dependency_resolver.rb +268 -0
  358. data/lib/expressir/model/exp_file.rb +42 -0
  359. data/lib/expressir/model/expressions/aggregate_initializer.rb +8 -9
  360. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +10 -12
  361. data/lib/expressir/model/expressions/binary_expression.rb +42 -36
  362. data/lib/expressir/model/expressions/entity_constructor.rb +10 -12
  363. data/lib/expressir/model/expressions/function_call.rb +10 -12
  364. data/lib/expressir/model/expressions/interval.rb +18 -23
  365. data/lib/expressir/model/expressions/query_expression.rb +11 -15
  366. data/lib/expressir/model/expressions/unary_expression.rb +13 -15
  367. data/lib/expressir/model/expressions.rb +18 -0
  368. data/lib/expressir/model/identifier.rb +18 -26
  369. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  370. data/lib/expressir/model/indexes/item_graph.rb +185 -0
  371. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  372. data/lib/expressir/model/indexes/type_index.rb +149 -0
  373. data/lib/expressir/model/indexes.rb +12 -0
  374. data/lib/expressir/model/interface_validator.rb +384 -0
  375. data/lib/expressir/model/literals/binary.rb +7 -9
  376. data/lib/expressir/model/literals/integer.rb +7 -9
  377. data/lib/expressir/model/literals/logical.rb +10 -12
  378. data/lib/expressir/model/literals/real.rb +7 -9
  379. data/lib/expressir/model/literals/string.rb +10 -12
  380. data/lib/expressir/model/literals.rb +13 -0
  381. data/lib/expressir/model/model_element.rb +286 -117
  382. data/lib/expressir/model/references/attribute_reference.rb +9 -12
  383. data/lib/expressir/model/references/group_reference.rb +9 -12
  384. data/lib/expressir/model/references/index_reference.rb +11 -15
  385. data/lib/expressir/model/references/simple_reference.rb +11 -14
  386. data/lib/expressir/model/references.rb +12 -0
  387. data/lib/expressir/model/remark_format.rb +17 -0
  388. data/lib/expressir/model/remark_info.rb +92 -0
  389. data/lib/expressir/model/remark_placement.rb +42 -0
  390. data/lib/expressir/model/repository.rb +472 -12
  391. data/lib/expressir/model/repository_validator.rb +293 -0
  392. data/lib/expressir/model/search_engine.rb +551 -0
  393. data/lib/expressir/model/statements/alias.rb +12 -16
  394. data/lib/expressir/model/statements/assignment.rb +12 -11
  395. data/lib/expressir/model/statements/case.rb +31 -14
  396. data/lib/expressir/model/statements/case_action.rb +9 -11
  397. data/lib/expressir/model/statements/compound.rb +10 -8
  398. data/lib/expressir/model/statements/escape.rb +10 -2
  399. data/lib/expressir/model/statements/if.rb +15 -14
  400. data/lib/expressir/model/statements/null.rb +10 -2
  401. data/lib/expressir/model/statements/procedure_call.rb +11 -11
  402. data/lib/expressir/model/statements/repeat.rb +21 -28
  403. data/lib/expressir/model/statements/return.rb +9 -8
  404. data/lib/expressir/model/statements/skip.rb +10 -2
  405. data/lib/expressir/model/statements.rb +20 -0
  406. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +13 -17
  407. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +7 -9
  408. data/lib/expressir/model/supertype_expressions.rb +12 -0
  409. data/lib/expressir/model.rb +38 -78
  410. data/lib/expressir/package/builder.rb +231 -0
  411. data/lib/expressir/package/metadata.rb +79 -0
  412. data/lib/expressir/package/reader.rb +149 -0
  413. data/lib/expressir/package.rb +8 -0
  414. data/lib/expressir/schema_manifest.rb +159 -0
  415. data/lib/expressir/schema_manifest_entry.rb +15 -0
  416. data/lib/expressir/version.rb +6 -1
  417. data/lib/expressir.rb +79 -9
  418. data/lib/tasks/verify_remarks.rake +16 -0
  419. data/rakelib/native.rake +24 -0
  420. data/rakelib/oracle.rake +52 -0
  421. data/rakelib/verify_remarks.rake +16 -0
  422. metadata +431 -129
  423. data/.cross_rubies +0 -20
  424. data/.gitmodules +0 -6
  425. data/.yardopts +0 -11
  426. data/docs/development.md +0 -90
  427. data/exe/format +0 -18
  428. data/exe/generate-parser +0 -51
  429. data/lib/expressir/cli/ui.rb +0 -36
  430. data/lib/expressir/express/2.7/express_parser.so +0 -0
  431. data/lib/expressir/express/3.0/express_parser.so +0 -0
  432. data/lib/expressir/express/3.1/express_parser.so +0 -0
  433. data/lib/expressir/express/3.2/express_parser.so +0 -0
  434. data/lib/expressir/express/visitor.rb +0 -2588
  435. data/lib/expressir/model/data_type.rb +0 -9
  436. data/lib/expressir/model/declaration.rb +0 -9
  437. data/lib/expressir/model/expression.rb +0 -9
  438. data/lib/expressir/model/literal.rb +0 -9
  439. data/lib/expressir/model/reference.rb +0 -9
  440. data/lib/expressir/model/statement.rb +0 -9
  441. data/lib/expressir/model/supertype_expression.rb +0 -9
  442. data/rakelib/antlr4-native.rake +0 -161
  443. data/rakelib/cross-ruby.rake +0 -368
  444. data/spec/acceptance/version_spec.rb +0 -27
  445. data/spec/expressir/express/cache_spec.rb +0 -89
  446. data/spec/expressir/express/formatter_spec.rb +0 -173
  447. data/spec/expressir/express/parser_spec.rb +0 -141
  448. data/spec/expressir/model/model_element_spec.rb +0 -318
  449. data/spec/spec_helper.rb +0 -24
  450. data/spec/support/console_helper.rb +0 -29
  451. data/spec/syntax/multiple.exp +0 -23
  452. data/spec/syntax/multiple.yaml +0 -198
  453. data/spec/syntax/multiple_formatted.exp +0 -71
  454. data/spec/syntax/multiple_hyperlink_formatted.exp +0 -71
  455. data/spec/syntax/multiple_schema_head_hyperlink_formatted.exp +0 -13
  456. data/spec/syntax/remark.exp +0 -193
  457. data/spec/syntax/remark.yaml +0 -471
  458. data/spec/syntax/remark_formatted.exp +0 -228
  459. data/spec/syntax/single.exp +0 -4
  460. data/spec/syntax/single.yaml +0 -18
  461. data/spec/syntax/single_formatted.exp +0 -10
  462. data/spec/syntax/single_formatted.yaml +0 -36
  463. data/spec/syntax/syntax.exp +0 -333
  464. data/spec/syntax/syntax.yaml +0 -3509
  465. data/spec/syntax/syntax_formatted.exp +0 -902
  466. data/spec/syntax/syntax_hyperlink_formatted.exp +0 -902
  467. data/spec/syntax/syntax_schema_head_formatted.exp +0 -18
@@ -0,0 +1,420 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Expressir
6
+ module Commands
7
+ # Manifest management CLI commands
8
+ # Handles schema manifest creation and validation
9
+ class Manifest < Thor
10
+ include Thor::Actions
11
+
12
+ desc "create ROOT_SCHEMA [MORE_SCHEMAS...]",
13
+ "Generate schema manifest from root schema(s)"
14
+ long_desc <<~DESC
15
+ Generate a YAML manifest of all schemas required for packaging.
16
+
17
+ The manifest uses the existing SchemaManifest format:
18
+ schemas:
19
+ schema_id:
20
+ path: /path/to/schema.exp
21
+
22
+ Workflow:
23
+ 1. Create manifest from root schema
24
+ 2. Edit manifest to add paths for schemas with null paths
25
+ 3. Validate manifest
26
+ 4. Build package using manifest
27
+
28
+ Example:
29
+ expressir manifest create schemas/activity/mim.exp \\
30
+ -o activity_manifest.yaml \\
31
+ --base-dirs /path/to/schemas
32
+
33
+ # With multiple base directories (space-separated)
34
+ expressir manifest create schemas/activity/mim.exp \\
35
+ -o activity_manifest.yaml \\
36
+ --base-dirs /path/to/resources /path/to/modules
37
+
38
+ # Or comma-separated for backward compatibility
39
+ expressir manifest create schemas/activity/mim.exp \\
40
+ -o activity_manifest.yaml \\
41
+ --base-dirs /path/to/resources,/path/to/modules
42
+ DESC
43
+ option :output, aliases: "-o", type: :string, required: true,
44
+ desc: "Output YAML file path"
45
+ option :base_dirs, type: :array,
46
+ desc: "Base directories for schema resolution (can be specified multiple times)"
47
+ option :verbose, type: :boolean, default: false,
48
+ desc: "Show detailed output"
49
+ def create(*root_schemas)
50
+ # Convert string keys to symbols for compatibility with tests
51
+ opts = options.transform_keys(&:to_sym)
52
+
53
+ if root_schemas.empty?
54
+ say "Error: At least one root schema is required", :red
55
+ say "Usage: expressir manifest create ROOT_SCHEMA [MORE_SCHEMAS...] -o OUTPUT.yaml",
56
+ :yellow
57
+ raise Thor::Error, "At least one root schema is required"
58
+ end
59
+
60
+ # Verify root schemas exist
61
+ root_schemas.each do |schema|
62
+ unless File.exist?(schema)
63
+ say "Error: Root schema not found: #{schema}", :red
64
+ raise Thor::Error, "Root schema not found: #{schema}"
65
+ end
66
+ end
67
+
68
+ say "Creating manifest from #{root_schemas.size} root schema(s)..." if opts[:verbose]
69
+
70
+ # Parse base directories - now an array directly from Thor
71
+ base_dirs = if opts[:base_dirs]
72
+ # Thor array type accepts space-separated values in a single flag
73
+ # or we can also split comma-separated values for backward compatibility
74
+ opts[:base_dirs].flat_map do |dir|
75
+ dir.split(",")
76
+ end.map(&:strip)
77
+ else
78
+ # Default to directories containing root schemas
79
+ root_schemas.map do |s|
80
+ File.dirname(File.expand_path(s))
81
+ end.uniq
82
+ end
83
+
84
+ if opts[:verbose]
85
+ say " Base directories:"
86
+ base_dirs.each_with_index do |dir, index|
87
+ say " - [source #{index + 1}]: #{dir}"
88
+ end
89
+ end
90
+
91
+ # Resolve dependencies
92
+ say "Resolving dependencies..." if opts[:verbose]
93
+ resolver = Expressir::Model::DependencyResolver.new(
94
+ base_dirs: base_dirs,
95
+ verbose: opts[:verbose],
96
+ )
97
+
98
+ resolved_paths = resolver.resolve_dependencies(root_schemas.first)
99
+
100
+ # Create manifest using existing SchemaManifest class
101
+ manifest = Expressir::SchemaManifest.new
102
+
103
+ # Add resolved schemas - use actual schema name from file, not filename
104
+ resolved_paths.each do |path|
105
+ schema_id = extract_schema_name(path)
106
+ manifest.schemas << Expressir::SchemaManifestEntry.new(
107
+ id: schema_id,
108
+ path: path,
109
+ )
110
+ end
111
+
112
+ # Add unresolved schemas with empty string paths (not nil to avoid serialization issues)
113
+ resolver.unresolved.uniq { |e| e[:schema_name] }.each do |entry|
114
+ manifest.schemas << Expressir::SchemaManifestEntry.new(
115
+ id: entry[:schema_name],
116
+ path: "",
117
+ )
118
+ end
119
+
120
+ # Save manifest
121
+ FileUtils.mkdir_p(File.dirname(opts[:output]))
122
+ File.write(opts[:output], manifest.to_yaml)
123
+
124
+ # Use validator for consistent warnings (DRY - single source of truth)
125
+ validator = Expressir::Manifest::Validator.new(manifest, opts)
126
+ path_warnings = validator.validate_path_completeness
127
+
128
+ unresolved_count = path_warnings.size
129
+ resolved_count = manifest.schemas.size - unresolved_count
130
+
131
+ say "✓ Manifest created: #{opts[:output]}", :green
132
+ say " Resolved schemas: #{resolved_count}", :green
133
+
134
+ # Warn about multiple matches
135
+ stats = resolver.statistics
136
+ if stats[:multiple_matches].any?
137
+ say ""
138
+ say "⚠ Multiple matches found (#{stats[:multiple_matches].size}):",
139
+ :yellow
140
+ stats[:multiple_matches].each do |match_info|
141
+ say " Schema '#{match_info[:schema_name]}' found in #{match_info[:matches].size} locations:",
142
+ :yellow
143
+ match_info[:matches].each_with_index do |m, idx|
144
+ relative_path = m[:path].sub("#{m[:base_dir]}/", "")
145
+ marker = idx.zero? ? "[USING]" : " "
146
+ say " #{marker} [source #{m[:index] + 1}] #{relative_path}",
147
+ :yellow
148
+ end
149
+ end
150
+ say ""
151
+ say "The first match was used for each schema.", :yellow
152
+ say "If you need a different version, manually edit #{opts[:output]}",
153
+ :yellow
154
+ end
155
+
156
+ # Warn about unresolved using validator results
157
+ if path_warnings.any?
158
+ say ""
159
+ say "⚠ Unresolved schemas (#{unresolved_count}):", :yellow
160
+ path_warnings.each { |w| say " - #{w[:schema]}", :yellow }
161
+ say ""
162
+ say "Please edit #{opts[:output]} and set 'path:' for unresolved schemas",
163
+ :yellow
164
+ say "Then validate with: expressir manifest validate #{opts[:output]}",
165
+ :yellow
166
+ else
167
+ say " All schemas resolved successfully!", :green
168
+ end
169
+ rescue StandardError => e
170
+ say "Error creating manifest: #{e.message}", :red
171
+ say e.backtrace.join("\n") if options[:verbose]
172
+ raise Thor::Error, "Failed to create manifest: #{e.message}"
173
+ end
174
+
175
+ desc "resolve MANIFEST", "Resolve schema paths in manifest"
176
+ long_desc <<~DESC
177
+ Resolve missing or incomplete schema paths in a manifest file.
178
+
179
+ This command attempts to find file paths for schemas with missing or empty paths
180
+ by searching in base directories using naming patterns:
181
+
182
+ Supported patterns:
183
+ - Resource schemas: {schema_name}.exp
184
+ - Module ARM/MIM: {module_name}/{arm|mim}.exp
185
+ Example: Activity_method_mim -> activity_method/mim.exp
186
+
187
+ The resolved manifest is written to the output file, leaving the original unchanged.
188
+
189
+ Use this command after 'expressir manifest validate --check-references' fails
190
+ to automatically resolve missing schema paths.
191
+
192
+ Examples:
193
+ # Resolve paths using manifest's existing base directories
194
+ expressir manifest resolve manifest.yaml -o resolved_manifest.yaml
195
+
196
+ # Resolve with explicit base directories (space-separated)
197
+ expressir manifest resolve manifest.yaml -o resolved.yaml \\
198
+ --base-dirs /path/to/schemas /another/path
199
+
200
+ # Or comma-separated for backward compatibility
201
+ expressir manifest resolve manifest.yaml -o resolved.yaml \\
202
+ --base-dirs /path/to/schemas,/another/path
203
+
204
+ # With verbose output
205
+ expressir manifest resolve manifest.yaml -o resolved.yaml --verbose
206
+ DESC
207
+ option :output, aliases: "-o", type: :string, required: true,
208
+ desc: "Output file path for resolved manifest"
209
+ option :base_dirs, type: :array,
210
+ desc: "Base directories for schema search (can be specified multiple times)"
211
+ option :verbose, type: :boolean, default: false,
212
+ desc: "Show detailed resolution progress"
213
+ def resolve(manifest_path)
214
+ unless File.exist?(manifest_path)
215
+ say "Error: Manifest file not found: #{manifest_path}", :red
216
+ raise Thor::Error, "Manifest file not found: #{manifest_path}"
217
+ end
218
+
219
+ say "Resolving schema paths in: #{manifest_path}..." if options[:verbose]
220
+
221
+ # Load manifest
222
+ manifest = Expressir::SchemaManifest.from_file(manifest_path)
223
+
224
+ # Parse base directories - now an array directly from Thor
225
+ resolver_options = { verbose: options[:verbose] }
226
+ if options[:base_dirs]
227
+ # Thor array type accepts space-separated values in a single flag
228
+ # or we can also split comma-separated values for backward compatibility
229
+ resolver_options[:base_dirs] = options[:base_dirs].flat_map do |dir|
230
+ dir.split(",")
231
+ end.map(&:strip)
232
+ if options[:verbose]
233
+ say " Using base directories:"
234
+ resolver_options[:base_dirs].each_with_index do |dir, index|
235
+ say " - [source #{index + 1}]: #{dir}"
236
+ end
237
+ end
238
+ end
239
+
240
+ # Create resolver and resolve paths
241
+ resolver = Expressir::Manifest::Resolver.new(manifest, resolver_options)
242
+
243
+ say "Attempting to resolve paths..." if options[:verbose]
244
+ resolved_manifest = resolver.resolve_paths
245
+
246
+ # Save resolved manifest
247
+ FileUtils.mkdir_p(File.dirname(options[:output]))
248
+ File.write(options[:output], resolved_manifest.to_yaml)
249
+
250
+ # Display statistics based on RESOLVED manifest (like manifest create)
251
+ validator = Expressir::Manifest::Validator.new(resolved_manifest,
252
+ options)
253
+ path_warnings = validator.validate_path_completeness
254
+
255
+ unresolved_count = path_warnings.size
256
+ resolved_count = resolved_manifest.schemas.size - unresolved_count
257
+
258
+ say "✓ Manifest resolved: #{options[:output]}", :green
259
+ say " Total schemas: #{resolved_manifest.schemas.size}", :green
260
+ say " Resolved schemas: #{resolved_count}", :green
261
+
262
+ # Warn about unresolved (like manifest create)
263
+ if path_warnings.any?
264
+ say ""
265
+ say "⚠ Unresolved schemas (#{unresolved_count}):", :yellow
266
+ path_warnings.each { |w| say " - #{w[:schema]}", :yellow }
267
+ say ""
268
+ say "These schemas could not be found in the search directories.",
269
+ :yellow
270
+ say "You may need to:", :yellow
271
+ say " 1. Add more base directories with --base-dirs", :yellow
272
+ say " 2. Manually edit #{options[:output]} and set their paths",
273
+ :yellow
274
+ else
275
+ say " All schema paths resolved successfully!", :green
276
+ end
277
+ rescue StandardError => e
278
+ say "Error resolving manifest: #{e.message}", :red
279
+ say e.backtrace.join("\n") if options[:verbose]
280
+ raise Thor::Error, "Failed to resolve manifest: #{e.message}"
281
+ end
282
+
283
+ desc "validate MANIFEST", "Validate a schema manifest"
284
+ long_desc <<~DESC
285
+ Validate a schema manifest file.
286
+
287
+ Validation types:
288
+ - File existence: All schema paths exist on disk
289
+ - Path completeness: All schemas have paths specified (warnings)
290
+ - Referential integrity (--check-references): All USE/REFERENCE FROM resolve
291
+
292
+ Examples:
293
+ # Basic validation (file existence and path completeness)
294
+ expressir manifest validate activity_manifest.yaml
295
+
296
+ # With referential integrity checking
297
+ expressir manifest validate activity_manifest.yaml --check-references
298
+
299
+ # With verbose output
300
+ expressir manifest validate activity_manifest.yaml --check-references --verbose
301
+ DESC
302
+ option :verbose, type: :boolean, default: false,
303
+ desc: "Show detailed validation results"
304
+ option :check_references, type: :boolean, default: false,
305
+ desc: "Validate referential integrity using dependency resolver"
306
+ def validate(manifest_path)
307
+ unless File.exist?(manifest_path)
308
+ say "Error: Manifest file not found: #{manifest_path}", :red
309
+ raise Thor::Error, "Manifest file not found: #{manifest_path}"
310
+ end
311
+
312
+ # Convert string keys to symbols for compatibility with tests
313
+ opts = options.transform_keys(&:to_sym)
314
+
315
+ say "Validating manifest: #{manifest_path}..." if opts[:verbose]
316
+
317
+ # Load manifest
318
+ manifest = Expressir::SchemaManifest.from_file(manifest_path)
319
+
320
+ # Create validator - SINGLE SOURCE OF TRUTH
321
+ validator = Expressir::Manifest::Validator.new(manifest, opts)
322
+
323
+ # Run validations using validator (NO INLINE LOGIC)
324
+ file_errors = validator.validate_file_existence
325
+ path_warnings = validator.validate_path_completeness
326
+ name_errors = validator.validate_schema_names
327
+
328
+ reference_errors = []
329
+ if opts[:check_references]
330
+ say "Checking referential integrity..." if opts[:verbose]
331
+ reference_errors = validator.validate_referential_integrity
332
+ end
333
+
334
+ # Display results
335
+ display_validation_results(manifest, file_errors, path_warnings,
336
+ name_errors, reference_errors)
337
+ rescue StandardError => e
338
+ say "Error validating manifest: #{e.message}", :red
339
+ say e.backtrace.join("\n") if options && options[:verbose]
340
+ raise Thor::Error, "Failed to validate manifest: #{e.message}"
341
+ end
342
+
343
+ private
344
+
345
+ # Extract the actual schema name from a schema file by parsing it
346
+ # @param schema_path [String] Path to the schema file
347
+ # @return [String] The schema name declared in the file
348
+ def extract_schema_name(schema_path)
349
+ repo = Expressir::Express::Parser.from_file(schema_path)
350
+ schema = repo.schemas.first
351
+ schema&.id || File.basename(schema_path, ".*")
352
+ rescue StandardError
353
+ # Fallback to filename if parsing fails
354
+ File.basename(schema_path, ".*")
355
+ end
356
+
357
+ def display_validation_results(manifest, file_errors, path_warnings,
358
+ name_errors, reference_errors)
359
+ # Convert string keys to symbols for compatibility with tests
360
+ opts = options.transform_keys(&:to_sym)
361
+
362
+ # Calculate counts
363
+ unresolved_count = manifest.schemas.count do |s|
364
+ s.path.nil? || s.path.empty?
365
+ end
366
+ resolved_count = manifest.schemas.size - unresolved_count
367
+
368
+ # Determine if validation passed
369
+ has_errors = file_errors.any? || name_errors.any? || reference_errors.any?
370
+
371
+ if has_errors
372
+ say "✗ Manifest validation failed", :red
373
+ say ""
374
+
375
+ if file_errors.any?
376
+ say "File Errors (#{file_errors.size}):", :red
377
+ file_errors.each { |e| say " - #{e[:message]}", :red }
378
+ say ""
379
+ end
380
+
381
+ if name_errors.any?
382
+ say "Schema Name Errors (#{name_errors.size}):", :red
383
+ name_errors.each { |e| say " - #{e[:message]}", :red }
384
+ say ""
385
+ end
386
+
387
+ if reference_errors.any?
388
+ say "Reference Errors (#{reference_errors.size}):", :red
389
+ reference_errors.each { |e| say " - #{e[:message]}", :red }
390
+ say ""
391
+ end
392
+
393
+ if path_warnings.any?
394
+ say "Warnings (#{path_warnings.size}):", :yellow
395
+ path_warnings.each { |w| say " - #{w[:message]}", :yellow }
396
+ end
397
+
398
+ raise Thor::Error, "Manifest validation failed"
399
+ else
400
+ say "✓ Manifest is valid", :green
401
+ if opts[:verbose]
402
+ say " Total schemas: #{manifest.schemas.size}",
403
+ :green
404
+ end
405
+ say " Resolved schemas: #{resolved_count}", :green if opts[:verbose]
406
+ if opts[:verbose] && unresolved_count.positive?
407
+ say " Unresolved schemas: #{unresolved_count}",
408
+ :green
409
+ end
410
+
411
+ if path_warnings.any?
412
+ say ""
413
+ say "Warnings (#{path_warnings.size}):", :yellow
414
+ path_warnings.each { |w| say " - #{w[:message]}", :yellow }
415
+ end
416
+ end
417
+ end
418
+ end
419
+ end
420
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Commands
5
+ # `expressir mapping validate` (#88): load a module mapping.yaml,
6
+ # resolve every <<express:...>> link and every reference path
7
+ # against the ARM/MIM interface closure. Exits 1 when unknown
8
+ # links or refpath issues remain.
9
+ class MappingValidate < Base
10
+ def run(path)
11
+ document = Expressir::Mapping.load_file(path)
12
+ repository = repository_for(path)
13
+
14
+ unknown = Expressir::Mapping.unknown_links(document, repository)
15
+ unknown.each do |link|
16
+ say "unknown: #{link.text}"
17
+ end
18
+
19
+ issues = refpath_issues(document, repository)
20
+ issues.each do |location, issue|
21
+ say "refpath #{location} [step #{issue.step}]: #{issue.message}"
22
+ end
23
+
24
+ rule_issues = Expressir::Mapping.rule_issues(document, repository)
25
+ rule_issues.each do |missing|
26
+ say "unknown rule: #{missing.text}"
27
+ end
28
+
29
+ total = unknown.size + issues.size + rule_issues.size
30
+ unless total.zero?
31
+ raise Thor::Error, "#{unknown.size} unknown link(s), " \
32
+ "#{issues.size} refpath issue(s), " \
33
+ "#{rule_issues.size} unknown rule(s)"
34
+ end
35
+
36
+ say "all links and reference paths resolve"
37
+ end
38
+
39
+ private
40
+
41
+ def refpath_issues(document, repository)
42
+ Expressir::Mapping.refpaths(document).flat_map do |location, content|
43
+ parsed = Expressir::Mapping::RefPath.parse(content)
44
+ start = Expressir::Mapping.entity_item(location)
45
+ parsed.parse_errors.map do |error|
46
+ [location, Expressir::Mapping::RefPath::Issue.new(step: nil,
47
+ message: error)]
48
+ end + Expressir::Mapping::RefPath.validate(parsed, repository,
49
+ start: start)
50
+ .map { |issue| [location, issue] }
51
+ end
52
+ end
53
+
54
+ def repository_for(path)
55
+ dir = File.dirname(File.expand_path(path))
56
+ arm = Dir[File.join(dir, "arm.exp")].first
57
+ mim = Dir[File.join(dir, "mim.exp")].first
58
+ roots = [arm, mim].compact
59
+ raise Thor::Error, "no arm.exp/mim.exp next to #{path}" if roots.empty?
60
+
61
+ files = roots.flat_map do |root|
62
+ ParityInputs.closure_paths(root)
63
+ end.uniq.select { |f| File.exist?(f) }
64
+ Expressir::Express::Parser.from_files(files)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Commands
5
+ class NonAsciiCharacter
6
+ attr_reader :char, :hex, :utf8, :is_math, :replacement,
7
+ :replacement_type, :occurrences
8
+
9
+ def initialize(char, hex, utf8, is_math, replacement, replacement_type)
10
+ @char = char
11
+ @hex = hex
12
+ @utf8 = utf8
13
+ @is_math = is_math
14
+ @replacement = replacement
15
+ @replacement_type = replacement_type
16
+ @occurrences = []
17
+ end
18
+
19
+ def add_occurrence(line_number, column, line)
20
+ @occurrences << {
21
+ line_number: line_number,
22
+ column: column,
23
+ line: line,
24
+ }
25
+ end
26
+
27
+ def replacement_text
28
+ @is_math ? "AsciiMath: #{@replacement}" : "ISO 10303-11: #{@replacement}"
29
+ end
30
+
31
+ def occurrence_count
32
+ @occurrences.size
33
+ end
34
+
35
+ def to_h
36
+ {
37
+ character: @char,
38
+ hex: @hex,
39
+ utf8: @utf8,
40
+ is_math: @is_math,
41
+ replacement_type: @replacement_type,
42
+ replacement: @replacement,
43
+ occurrence_count: occurrence_count,
44
+ occurrences: @occurrences,
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end