expressir 2.2.0 → 2.3.0

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 (192) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.rubocop_todo.yml +254 -77
  4. data/Gemfile +4 -1
  5. data/README.adoc +63 -26
  6. data/benchmark/srl_benchmark.rb +386 -0
  7. data/benchmark/srl_native_benchmark.rb +142 -0
  8. data/benchmark/srl_ruby_benchmark.rb +130 -0
  9. data/expressir.gemspec +4 -2
  10. data/lib/expressir/benchmark.rb +1 -1
  11. data/lib/expressir/changes/item_change.rb +0 -1
  12. data/lib/expressir/changes/mapping_change.rb +0 -1
  13. data/lib/expressir/changes/schema_change.rb +0 -2
  14. data/lib/expressir/changes/version_change.rb +0 -3
  15. data/lib/expressir/changes.rb +5 -6
  16. data/lib/expressir/cli.rb +10 -24
  17. data/lib/expressir/commands/base.rb +2 -9
  18. data/lib/expressir/commands/changes.rb +0 -2
  19. data/lib/expressir/commands/changes_import_eengine.rb +0 -3
  20. data/lib/expressir/commands/changes_validate.rb +0 -2
  21. data/lib/expressir/commands/format.rb +5 -3
  22. data/lib/expressir/commands/manifest.rb +0 -7
  23. data/lib/expressir/commands/package.rb +93 -101
  24. data/lib/expressir/commands/validate.rb +0 -2
  25. data/lib/expressir/commands/validate_ascii.rb +2 -4
  26. data/lib/expressir/commands/validate_load.rb +8 -5
  27. data/lib/expressir/commands.rb +20 -0
  28. data/lib/expressir/config.rb +0 -2
  29. data/lib/expressir/coverage.rb +11 -4
  30. data/lib/expressir/eengine/arm_compare_report.rb +1 -4
  31. data/lib/expressir/eengine/changes_section.rb +1 -3
  32. data/lib/expressir/eengine/compare_report.rb +1 -13
  33. data/lib/expressir/eengine/mim_compare_report.rb +1 -4
  34. data/lib/expressir/eengine/modified_object.rb +1 -2
  35. data/lib/expressir/eengine.rb +9 -0
  36. data/lib/expressir/errors.rb +113 -0
  37. data/lib/expressir/express/builder.rb +22 -7
  38. data/lib/expressir/express/builder_registry.rb +411 -0
  39. data/lib/expressir/express/builders/attribute_decl_builder.rb +0 -6
  40. data/lib/expressir/express/builders/built_in_builder.rb +1 -16
  41. data/lib/expressir/express/builders/constant_builder.rb +4 -19
  42. data/lib/expressir/express/builders/declaration_builder.rb +0 -4
  43. data/lib/expressir/express/builders/derive_clause_builder.rb +0 -2
  44. data/lib/expressir/express/builders/derived_attr_builder.rb +0 -2
  45. data/lib/expressir/express/builders/domain_rule_builder.rb +0 -2
  46. data/lib/expressir/express/builders/entity_decl_builder.rb +7 -13
  47. data/lib/expressir/express/builders/explicit_attr_builder.rb +5 -8
  48. data/lib/expressir/express/builders/expression_builder.rb +31 -67
  49. data/lib/expressir/express/builders/function_decl_builder.rb +20 -18
  50. data/lib/expressir/express/builders/interface_builder.rb +0 -20
  51. data/lib/expressir/express/builders/inverse_attr_builder.rb +0 -2
  52. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +0 -6
  53. data/lib/expressir/express/builders/inverse_clause_builder.rb +0 -2
  54. data/lib/expressir/express/builders/literal_builder.rb +1 -15
  55. data/lib/expressir/express/builders/procedure_decl_builder.rb +20 -19
  56. data/lib/expressir/express/builders/qualifier_builder.rb +0 -27
  57. data/lib/expressir/express/builders/reference_builder.rb +1 -10
  58. data/lib/expressir/express/builders/rule_decl_builder.rb +21 -19
  59. data/lib/expressir/express/builders/schema_body_decl_builder.rb +0 -4
  60. data/lib/expressir/express/builders/schema_decl_builder.rb +7 -13
  61. data/lib/expressir/express/builders/schema_version_builder.rb +0 -6
  62. data/lib/expressir/express/builders/simple_id_builder.rb +1 -10
  63. data/lib/expressir/express/builders/statement_builder.rb +4 -32
  64. data/lib/expressir/express/builders/subtype_constraint_builder.rb +6 -30
  65. data/lib/expressir/express/builders/syntax_builder.rb +60 -7
  66. data/lib/expressir/express/builders/type_builder.rb +3 -45
  67. data/lib/expressir/express/builders/type_decl_builder.rb +1 -7
  68. data/lib/expressir/express/builders/unique_clause_builder.rb +1 -3
  69. data/lib/expressir/express/builders/unique_rule_builder.rb +0 -2
  70. data/lib/expressir/express/builders/where_clause_builder.rb +1 -3
  71. data/lib/expressir/express/builders.rb +47 -35
  72. data/lib/expressir/express/error.rb +0 -3
  73. data/lib/expressir/express/formatter.rb +17 -19
  74. data/lib/expressir/express/formatters/data_types_formatter.rb +295 -293
  75. data/lib/expressir/express/formatters/declarations_formatter.rb +617 -615
  76. data/lib/expressir/express/formatters/expressions_formatter.rb +146 -144
  77. data/lib/expressir/express/formatters/literals_formatter.rb +35 -33
  78. data/lib/expressir/express/formatters/references_formatter.rb +34 -32
  79. data/lib/expressir/express/formatters/remark_formatter.rb +176 -209
  80. data/lib/expressir/express/formatters/remark_item_formatter.rb +18 -16
  81. data/lib/expressir/express/formatters/statements_formatter.rb +190 -188
  82. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +41 -39
  83. data/lib/expressir/express/formatters.rb +22 -0
  84. data/lib/expressir/express/parser.rb +40 -41
  85. data/lib/expressir/express/pretty_formatter.rb +68 -47
  86. data/lib/expressir/express/remark_attacher.rb +210 -147
  87. data/lib/expressir/express/streaming_builder.rb +0 -3
  88. data/lib/expressir/express/transformer/remark_handling.rb +1 -2
  89. data/lib/expressir/express.rb +29 -0
  90. data/lib/expressir/manifest/resolver.rb +0 -3
  91. data/lib/expressir/manifest/validator.rb +0 -3
  92. data/lib/expressir/manifest.rb +6 -0
  93. data/lib/expressir/model/cache.rb +1 -1
  94. data/lib/expressir/model/concerns.rb +19 -0
  95. data/lib/expressir/model/data_types/aggregate.rb +1 -1
  96. data/lib/expressir/model/data_types/array.rb +1 -1
  97. data/lib/expressir/model/data_types/bag.rb +1 -1
  98. data/lib/expressir/model/data_types/binary.rb +1 -1
  99. data/lib/expressir/model/data_types/boolean.rb +1 -1
  100. data/lib/expressir/model/data_types/enumeration.rb +1 -1
  101. data/lib/expressir/model/data_types/enumeration_item.rb +1 -1
  102. data/lib/expressir/model/data_types/generic.rb +1 -1
  103. data/lib/expressir/model/data_types/generic_entity.rb +1 -1
  104. data/lib/expressir/model/data_types/integer.rb +1 -1
  105. data/lib/expressir/model/data_types/list.rb +1 -1
  106. data/lib/expressir/model/data_types/logical.rb +1 -1
  107. data/lib/expressir/model/data_types/number.rb +1 -1
  108. data/lib/expressir/model/data_types/real.rb +1 -1
  109. data/lib/expressir/model/data_types/select.rb +1 -1
  110. data/lib/expressir/model/data_types/set.rb +1 -1
  111. data/lib/expressir/model/data_types/string.rb +1 -1
  112. data/lib/expressir/model/data_types.rb +25 -0
  113. data/lib/expressir/model/declarations/attribute.rb +1 -1
  114. data/lib/expressir/model/declarations/constant.rb +1 -1
  115. data/lib/expressir/model/declarations/derived_attribute.rb +1 -1
  116. data/lib/expressir/model/declarations/entity.rb +4 -1
  117. data/lib/expressir/model/declarations/function.rb +3 -1
  118. data/lib/expressir/model/declarations/informal_proposition_rule.rb +2 -1
  119. data/lib/expressir/model/declarations/interface.rb +1 -1
  120. data/lib/expressir/model/declarations/interface_item.rb +1 -1
  121. data/lib/expressir/model/declarations/interfaced_item.rb +1 -1
  122. data/lib/expressir/model/declarations/inverse_attribute.rb +1 -1
  123. data/lib/expressir/model/declarations/parameter.rb +1 -1
  124. data/lib/expressir/model/declarations/procedure.rb +3 -1
  125. data/lib/expressir/model/declarations/remark_item.rb +1 -1
  126. data/lib/expressir/model/declarations/rule.rb +4 -1
  127. data/lib/expressir/model/declarations/schema.rb +2 -1
  128. data/lib/expressir/model/declarations/schema_version.rb +1 -1
  129. data/lib/expressir/model/declarations/schema_version_item.rb +1 -1
  130. data/lib/expressir/model/declarations/subtype_constraint.rb +1 -1
  131. data/lib/expressir/model/declarations/type.rb +4 -1
  132. data/lib/expressir/model/declarations/unique_rule.rb +1 -1
  133. data/lib/expressir/model/declarations/variable.rb +1 -1
  134. data/lib/expressir/model/declarations/where_rule.rb +1 -1
  135. data/lib/expressir/model/declarations.rb +31 -0
  136. data/lib/expressir/model/dependency_resolver.rb +0 -2
  137. data/lib/expressir/model/exp_file.rb +38 -0
  138. data/lib/expressir/model/expressions/aggregate_initializer.rb +1 -1
  139. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +1 -1
  140. data/lib/expressir/model/expressions/binary_expression.rb +1 -1
  141. data/lib/expressir/model/expressions/entity_constructor.rb +1 -1
  142. data/lib/expressir/model/expressions/function_call.rb +1 -1
  143. data/lib/expressir/model/expressions/interval.rb +1 -1
  144. data/lib/expressir/model/expressions/query_expression.rb +1 -1
  145. data/lib/expressir/model/expressions/unary_expression.rb +1 -1
  146. data/lib/expressir/model/expressions.rb +18 -0
  147. data/lib/expressir/model/identifier.rb +5 -1
  148. data/lib/expressir/model/indexes.rb +11 -0
  149. data/lib/expressir/model/literals/binary.rb +1 -1
  150. data/lib/expressir/model/literals/integer.rb +1 -1
  151. data/lib/expressir/model/literals/logical.rb +1 -1
  152. data/lib/expressir/model/literals/real.rb +1 -1
  153. data/lib/expressir/model/literals/string.rb +1 -1
  154. data/lib/expressir/model/literals.rb +13 -0
  155. data/lib/expressir/model/model_element.rb +7 -15
  156. data/lib/expressir/model/references/attribute_reference.rb +1 -1
  157. data/lib/expressir/model/references/group_reference.rb +1 -1
  158. data/lib/expressir/model/references/index_reference.rb +1 -1
  159. data/lib/expressir/model/references/simple_reference.rb +1 -1
  160. data/lib/expressir/model/references.rb +12 -0
  161. data/lib/expressir/model/remark_info.rb +1 -7
  162. data/lib/expressir/model/repository.rb +72 -36
  163. data/lib/expressir/model/repository_validator.rb +0 -2
  164. data/lib/expressir/model/search_engine.rb +6 -30
  165. data/lib/expressir/model/statements/alias.rb +1 -1
  166. data/lib/expressir/model/statements/assignment.rb +1 -1
  167. data/lib/expressir/model/statements/case.rb +1 -1
  168. data/lib/expressir/model/statements/case_action.rb +1 -1
  169. data/lib/expressir/model/statements/compound.rb +1 -1
  170. data/lib/expressir/model/statements/escape.rb +1 -1
  171. data/lib/expressir/model/statements/if.rb +1 -1
  172. data/lib/expressir/model/statements/null.rb +1 -1
  173. data/lib/expressir/model/statements/procedure_call.rb +1 -1
  174. data/lib/expressir/model/statements/repeat.rb +1 -1
  175. data/lib/expressir/model/statements/return.rb +1 -1
  176. data/lib/expressir/model/statements/skip.rb +1 -1
  177. data/lib/expressir/model/statements.rb +20 -0
  178. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +1 -1
  179. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +1 -1
  180. data/lib/expressir/model/supertype_expressions.rb +12 -0
  181. data/lib/expressir/model.rb +28 -4
  182. data/lib/expressir/package/builder.rb +33 -4
  183. data/lib/expressir/package/metadata.rb +0 -1
  184. data/lib/expressir/package/reader.rb +0 -1
  185. data/lib/expressir/package.rb +8 -0
  186. data/lib/expressir/schema_manifest.rb +5 -6
  187. data/lib/expressir/schema_manifest_entry.rb +3 -4
  188. data/lib/expressir/transformer.rb +7 -0
  189. data/lib/expressir/version.rb +1 -1
  190. data/lib/expressir.rb +23 -173
  191. metadata +64 -9
  192. data/lib/expressir/express/builders/token_builder.rb +0 -15
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # SRL Benchmark Script for Expressir - Native Parser Only
5
+ # Tests Rust native parser performance on full STEPmod Resource Library
6
+
7
+ require 'bundler/setup'
8
+ require 'benchmark'
9
+ require 'fileutils'
10
+
11
+ # Force loading of native extension first
12
+ require 'parsanol'
13
+ require 'parsanol/native'
14
+
15
+ # Now require expressir
16
+ require 'expressir'
17
+
18
+ # Configuration
19
+ SRL_PATH = '/Users/mulgogi/src/mn/iso-10303/schemas/resources'
20
+
21
+ def find_exp_files
22
+ Dir.glob("#{SRL_PATH}/*/*.exp").sort
23
+ end
24
+
25
+ def count_lines(files)
26
+ files.sum { |f| File.read(f).lines.count }
27
+ end
28
+
29
+ puts "=" * 70
30
+ puts "EXPRESSIR SRL BENCHMARK: Native Parser (Rust)"
31
+ puts "=" * 70
32
+ puts
33
+
34
+ # Check native availability
35
+ native_available = Parsanol::Native.available?
36
+ puts "Native parser available: #{native_available ? 'YES' : 'NO'}"
37
+ puts
38
+
39
+ if !native_available
40
+ puts "Native parser not available. Run `rake compile` in parsanol-ruby."
41
+ exit 1
42
+ end
43
+
44
+ # Find all EXPRESS files
45
+ files = find_exp_files
46
+ total_lines = count_lines(files)
47
+
48
+ puts "Files to parse: #{files.size}"
49
+ puts "Total lines of code: #{total_lines}"
50
+ puts
51
+
52
+ if files.empty?
53
+ puts "ERROR: No EXPRESS files found at #{SRL_PATH}"
54
+ exit 1
55
+ end
56
+
57
+ # Warmup - parse first file to ensure everything is loaded
58
+ puts "Warming up..."
59
+ warmup_file = files.first
60
+ begin
61
+ content = File.read(warmup_file)
62
+ Expressir::Express::Parser.from_exp(content, skip_references: true, use_native: true)
63
+ puts "Warmup complete."
64
+ rescue => e
65
+ puts "Warning: Warmup failed: #{e.message}"
66
+ puts e.backtrace.first(5)
67
+ end
68
+ puts
69
+
70
+ # Run Native benchmark
71
+ puts "-" * 70
72
+ puts "NATIVE PARSER BENCHMARK"
73
+ puts "-" * 70
74
+
75
+ results = { success: 0, failed: 0, errors: [], total_time: 0 }
76
+ file_times = []
77
+
78
+ time = Benchmark.realtime do
79
+ files.each_with_index do |file, idx|
80
+ file_start = Time.now
81
+ begin
82
+ content = File.read(file)
83
+ Expressir::Express::Parser.from_exp(content, skip_references: true, use_native: true)
84
+ results[:success] += 1
85
+ file_time = Time.now - file_start
86
+ file_times << { file: File.basename(file), time: file_time, lines: content.lines.count }
87
+
88
+ # Progress every 10 files
89
+ if (idx + 1) % 10 == 0
90
+ print "."
91
+ $stdout.flush
92
+ end
93
+ rescue => e
94
+ results[:failed] += 1
95
+ results[:errors] << { file: File.basename(file), error: e.message[0..100] }
96
+ end
97
+ end
98
+ end
99
+ puts
100
+
101
+ results[:total_time] = time
102
+
103
+ # Calculate stats
104
+ lines_per_sec = (total_lines / results[:total_time]).round(1)
105
+ files_per_sec = (files.size / results[:total_time]).round(2)
106
+
107
+ puts
108
+ puts "Native Parser Results:"
109
+ puts " Success: #{results[:success]}/#{files.size} files"
110
+ puts " Failed: #{results[:failed]} files"
111
+ puts " Time: #{results[:total_time].round(2)}s"
112
+ puts " Speed: #{lines_per_sec} lines/sec"
113
+ puts " Speed: #{files_per_sec} files/sec"
114
+
115
+ if results[:failed] > 0
116
+ puts
117
+ puts "Errors (first 10):"
118
+ results[:errors].first(10).each do |err|
119
+ puts " - #{err[:file]}: #{err[:error]}"
120
+ end
121
+ end
122
+
123
+ # Show top 5 slowest files
124
+ puts
125
+ puts "Top 5 slowest files:"
126
+ sorted = file_times.sort_by { |f| -f[:time] }.first(5)
127
+ sorted.each do |f|
128
+ puts " #{f[:file]}: #{f[:time].round(2)}s (#{f[:lines]} lines)"
129
+ end
130
+
131
+ # Show top 5 fastest files
132
+ puts
133
+ puts "Top 5 fastest files:"
134
+ sorted = file_times.sort_by { |f| f[:time] }.first(5)
135
+ sorted.each do |f|
136
+ puts " #{f[:file]}: #{f[:time].round(3)}s (#{f[:lines]} lines)"
137
+ end
138
+
139
+ puts
140
+ puts "=" * 70
141
+ puts "BENCHMARK COMPLETE"
142
+ puts "=" * 70
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # SRL Benchmark Script for Expressir - Ruby Parser Only
5
+ # Tests pure Ruby parser performance on full STEPmod Resource Library
6
+
7
+ require 'bundler/setup'
8
+ require 'benchmark'
9
+ require 'fileutils'
10
+
11
+ # Load expressir WITHOUT native extension
12
+ require 'expressir'
13
+
14
+ # Configuration
15
+ SRL_PATH = '/Users/mulgogi/src/mn/iso-10303/schemas/resources'
16
+
17
+ def find_exp_files
18
+ Dir.glob("#{SRL_PATH}/*/*.exp").sort
19
+ end
20
+
21
+ def count_lines(files)
22
+ files.sum { |f| File.read(f).lines.count }
23
+ end
24
+
25
+ puts "=" * 70
26
+ puts "EXPRESSIR SRL BENCHMARK: Pure Ruby Parser"
27
+ puts "=" * 70
28
+ puts
29
+
30
+ # Find all EXPRESS files
31
+ files = find_exp_files
32
+ total_lines = count_lines(files)
33
+
34
+ puts "Files to parse: #{files.size}"
35
+ puts "Total lines of code: #{total_lines}"
36
+ puts
37
+
38
+ if files.empty?
39
+ puts "ERROR: No EXPRESS files found at #{SRL_PATH}"
40
+ exit 1
41
+ end
42
+
43
+ # Warmup - parse first file to ensure everything is loaded
44
+ puts "Warming up..."
45
+ warmup_file = files.first
46
+ begin
47
+ Expressir::Express::Parser.from_file(warmup_file, skip_references: true)
48
+ puts "Warmup complete."
49
+ rescue => e
50
+ puts "Warning: Warmup failed: #{e.message}"
51
+ end
52
+ puts
53
+
54
+ # Run Ruby benchmark
55
+ puts "-" * 70
56
+ puts "RUBY PARSER BENCHMARK"
57
+ puts "-" * 70
58
+
59
+ results = { success: 0, failed: 0, errors: [], total_time: 0 }
60
+ file_times = []
61
+
62
+ time = Benchmark.realtime do
63
+ files.each_with_index do |file, idx|
64
+ file_start = Time.now
65
+ begin
66
+ Expressir::Express::Parser.from_file(file, skip_references: true)
67
+ results[:success] += 1
68
+ file_time = Time.now - file_start
69
+ content = File.read(file)
70
+ file_times << { file: File.basename(file), time: file_time, lines: content.lines.count }
71
+
72
+ # Progress every 10 files
73
+ if (idx + 1) % 10 == 0
74
+ print "."
75
+ $stdout.flush
76
+ end
77
+ rescue => e
78
+ results[:failed] += 1
79
+ results[:errors] << { file: File.basename(file), error: e.message[0..100] }
80
+ end
81
+ end
82
+ end
83
+ puts
84
+
85
+ results[:total_time] = time
86
+
87
+ # Calculate stats
88
+ lines_per_sec = (total_lines / results[:total_time]).round(1)
89
+ files_per_sec = (files.size / results[:total_time]).round(2)
90
+
91
+ puts
92
+ puts "Ruby Parser Results:"
93
+ puts " Success: #{results[:success]}/#{files.size} files"
94
+ puts " Failed: #{results[:failed]} files"
95
+ puts " Time: #{results[:total_time].round(2)}s"
96
+ puts " Speed: #{lines_per_sec} lines/sec"
97
+ puts " Speed: #{files_per_sec} files/sec"
98
+
99
+ if results[:failed] > 0
100
+ puts
101
+ puts "Errors (first 10):"
102
+ results[:errors].first(10).each do |err|
103
+ puts " - #{err[:file]}: #{err[:error]}"
104
+ end
105
+ end
106
+
107
+ # Show top 5 slowest files
108
+ puts
109
+ puts "Top 5 slowest files:"
110
+ sorted = file_times.sort_by { |f| -f[:time] }.first(5)
111
+ sorted.each do |f|
112
+ puts " #{f[:file]}: #{f[:time].round(2)}s (#{f[:lines]} lines)"
113
+ end
114
+
115
+ # Show top 5 fastest files
116
+ puts
117
+ puts "Top 5 fastest files:"
118
+ sorted = file_times.sort_by { |f| f[:time] }.first(5)
119
+ sorted.each do |f|
120
+ puts " #{f[:file]}: #{f[:time].round(3)}s (#{f[:lines]} lines)"
121
+ end
122
+
123
+ puts
124
+ puts "=" * 70
125
+ puts "BENCHMARK COMPLETE"
126
+ puts "=" * 70
127
+ puts
128
+ puts "NOTE: Native parser benchmark skipped due to AST format incompatibility."
129
+ puts "The native parser returns a different AST format than Expressir expects."
130
+ puts "This requires further work to implement sequence merging in Rust."
data/expressir.gemspec CHANGED
@@ -32,13 +32,15 @@ Gem::Specification.new do |spec|
32
32
  end
33
33
 
34
34
  spec.add_dependency "base64"
35
+ spec.add_dependency "benchmark"
35
36
  spec.add_dependency "benchmark-ips"
36
37
  spec.add_dependency "csv"
37
38
  spec.add_dependency "liquid"
38
- spec.add_dependency "lutaml-model"
39
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
39
40
  spec.add_dependency "moxml"
40
41
  spec.add_dependency "paint"
41
- spec.add_dependency "parsanol", "~> 1.1"
42
+ spec.add_dependency "parsanol", "~> 1.3.7", ">= 1.3.7"
43
+ spec.add_dependency "nokogiri"
42
44
  spec.add_dependency "ruby-progressbar", "~> 1.11"
43
45
  spec.add_dependency "rubyzip", "~> 2.3"
44
46
  spec.add_dependency "table_tennis"
@@ -268,7 +268,7 @@ module Expressir
268
268
  result.each do |r|
269
269
  if r.is_a?(Model::Declarations::Schema)
270
270
  schema_count += 1
271
- total_objects += 1 # Count the schema itself
271
+ total_objects += 1 # Count the schema itself
272
272
  end
273
273
  end
274
274
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
3
 
5
4
  module Expressir
6
5
  module Changes
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
3
 
5
4
  module Expressir
6
5
  module Changes
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
- require_relative "version_change"
5
3
 
6
4
  module Expressir
7
5
  module Changes
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
- require_relative "item_change"
5
- require_relative "mapping_change"
6
3
 
7
4
  module Expressir
8
5
  module Changes
@@ -1,10 +1,9 @@
1
- # frozen_string_literal: true
2
-
1
+ # lib/expressir/changes.rb
3
2
  module Expressir
4
- # Module for EXPRESS schema change tracking and management
5
3
  module Changes
4
+ autoload :SchemaChange, "#{__dir__}/changes/schema_change"
5
+ autoload :VersionChange, "#{__dir__}/changes/version_change"
6
+ autoload :ItemChange, "#{__dir__}/changes/item_change"
7
+ autoload :MappingChange, "#{__dir__}/changes/mapping_change"
6
8
  end
7
9
  end
8
-
9
- require_relative "changes/schema_change"
10
- require_relative "changes/mapping_change"
data/lib/expressir/cli.rb CHANGED
@@ -1,20 +1,6 @@
1
1
  require "thor"
2
2
  require "yaml"
3
3
 
4
- require_relative "commands/base"
5
- require_relative "commands/format"
6
- require_relative "commands/clean"
7
- require_relative "commands/benchmark"
8
- require_relative "commands/benchmark_cache"
9
- require_relative "commands/validate"
10
- require_relative "commands/validate_load"
11
- require_relative "commands/validate_ascii"
12
- require_relative "commands/coverage"
13
- require_relative "commands/changes"
14
- require_relative "commands/version"
15
- require_relative "commands/package"
16
- require_relative "commands/manifest"
17
-
18
4
  module Expressir
19
5
  class Cli < Thor
20
6
  # Exit with error code on command failures
@@ -33,14 +19,14 @@ module Expressir
33
19
  desc: "Include provenance information (ELF profile only)",
34
20
  default: true
35
21
  def format(path)
36
- Commands::Format.new(options).run(path)
22
+ Expressir::Commands::Format.new(options).run(path)
37
23
  end
38
24
 
39
25
  desc "clean PATH", "Strip remarks and prettify EXPRESS schema at PATH"
40
26
  method_option :output, type: :string,
41
27
  desc: "Output file path (defaults to stdout)"
42
28
  def clean(path)
43
- Commands::Clean.new(options).run(path)
29
+ Expressir::Commands::Clean.new(options).run(path)
44
30
  end
45
31
 
46
32
  desc "benchmark FILE_OR_YAML",
@@ -52,7 +38,7 @@ module Expressir
52
38
  method_option :format, type: :string,
53
39
  desc: "Output format (json, csv, default)"
54
40
  def benchmark(path)
55
- Commands::Benchmark.new(options).run(path)
41
+ Expressir::Commands::Benchmark.new(options).run(path)
56
42
  end
57
43
 
58
44
  desc "benchmark-cache FILE_OR_YAML", "Benchmark schema loading with caching"
@@ -65,11 +51,11 @@ module Expressir
65
51
  method_option :cache_path, type: :string,
66
52
  desc: "Path to store the cache file"
67
53
  def benchmark_cache(path)
68
- Commands::BenchmarkCache.new(options).run(path)
54
+ Expressir::Commands::BenchmarkCache.new(options).run(path)
69
55
  end
70
56
 
71
57
  desc "validate SUBCOMMAND", "EXPRESS schema validation commands"
72
- subcommand "validate", Commands::Validate
58
+ subcommand "validate", Expressir::Commands::Validate
73
59
 
74
60
  desc "coverage *PATH",
75
61
  "List EXPRESS entities and check documentation coverage"
@@ -82,21 +68,21 @@ module Expressir
82
68
  method_option :ignore_files, type: :string,
83
69
  desc: "Path to YAML file containing array of files to ignore from overall coverage calculation"
84
70
  def coverage(*paths)
85
- Commands::Coverage.new(options).run(paths)
71
+ Expressir::Commands::Coverage.new(options).run(paths)
86
72
  end
87
73
 
88
74
  desc "changes SUBCOMMAND", "Commands for EXPRESS Changes files"
89
- subcommand "changes", Commands::Changes
75
+ subcommand "changes", Expressir::Commands::Changes
90
76
 
91
77
  desc "manifest SUBCOMMAND", "Schema manifest management commands"
92
- subcommand "manifest", Commands::Manifest
78
+ subcommand "manifest", Expressir::Commands::Manifest
93
79
 
94
80
  desc "package SUBCOMMAND", "LER package management commands"
95
- subcommand "package", Commands::Package
81
+ subcommand "package", Expressir::Commands::Package
96
82
 
97
83
  desc "version", "Expressir Version"
98
84
  def version
99
- Commands::Version.new(options).run
85
+ Expressir::Commands::Version.new(options).run
100
86
  end
101
87
  end
102
88
  end
@@ -17,15 +17,8 @@ module Expressir
17
17
  end
18
18
  end
19
19
 
20
- def exit_with_error(message, exit_code = 1)
21
- say message
22
- # In test mode, raise an exception instead of exiting
23
- # This makes it easier to test error cases
24
- if defined?(@test_mode) && @test_mode
25
- raise message # Just raise the message as an exception
26
- else
27
- exit exit_code
28
- end
20
+ def exit_with_error(message, _exit_code = 1)
21
+ raise Expressir::CommandError.new(message)
29
22
  end
30
23
  end
31
24
  end
@@ -16,7 +16,6 @@ module Expressir
16
16
  method_option :verbose, type: :boolean,
17
17
  desc: "Show verbose output"
18
18
  def validate(path)
19
- require_relative "changes_validate"
20
19
  ChangesValidate.new(options).run(path)
21
20
  end
22
21
 
@@ -27,7 +26,6 @@ module Expressir
27
26
  method_option :verbose, type: :boolean,
28
27
  desc: "Show verbose output"
29
28
  def import_eengine(input_xml, schema_name, version)
30
- require_relative "changes_import_eengine"
31
29
  ChangesImportEengine.call(input_xml, options[:output], schema_name,
32
30
  version, **options)
33
31
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
- require_relative "../eengine/compare_report"
5
-
6
3
  module Expressir
7
4
  module Commands
8
5
  # Command to import eengine comparison XML to EXPRESS Changes YAML
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base"
4
-
5
3
  module Expressir
6
4
  module Commands
7
5
  # Command to validate and normalize EXPRESS Changes YAML files
@@ -12,9 +12,11 @@ module Expressir
12
12
  when "iso"
13
13
  format_with_iso_profile(repository)
14
14
  else
15
- say "Error: Unknown profile '#{profile}'. Valid profiles are: 'iso', 'elf'",
16
- :red
17
- exit 1
15
+ raise Expressir::InvalidOptionError.new(
16
+ "profile",
17
+ profile,
18
+ valid_options: ["iso", "elf"],
19
+ )
18
20
  end
19
21
  end
20
22
 
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "thor"
4
- require_relative "../schema_manifest"
5
- require_relative "../model/dependency_resolver"
6
4
 
7
5
  module Expressir
8
6
  module Commands
@@ -124,7 +122,6 @@ module Expressir
124
122
  File.write(opts[:output], manifest.to_yaml)
125
123
 
126
124
  # Use validator for consistent warnings (DRY - single source of truth)
127
- require_relative "../manifest/validator"
128
125
  validator = Expressir::Manifest::Validator.new(manifest, opts)
129
126
  path_warnings = validator.validate_path_completeness
130
127
 
@@ -241,7 +238,6 @@ module Expressir
241
238
  end
242
239
 
243
240
  # Create resolver and resolve paths
244
- require_relative "../manifest/resolver"
245
241
  resolver = Expressir::Manifest::Resolver.new(manifest, resolver_options)
246
242
 
247
243
  say "Attempting to resolve paths..." if options[:verbose]
@@ -252,7 +248,6 @@ module Expressir
252
248
  File.write(options[:output], resolved_manifest.to_yaml)
253
249
 
254
250
  # Display statistics based on RESOLVED manifest (like manifest create)
255
- require_relative "../manifest/validator"
256
251
  validator = Expressir::Manifest::Validator.new(resolved_manifest,
257
252
  options)
258
253
  path_warnings = validator.validate_path_completeness
@@ -323,7 +318,6 @@ module Expressir
323
318
  manifest = Expressir::SchemaManifest.from_file(manifest_path)
324
319
 
325
320
  # Create validator - SINGLE SOURCE OF TRUTH
326
- require_relative "../manifest/validator"
327
321
  validator = Expressir::Manifest::Validator.new(manifest, opts)
328
322
 
329
323
  # Run validations using validator (NO INLINE LOGIC)
@@ -352,7 +346,6 @@ module Expressir
352
346
  # @param schema_path [String] Path to the schema file
353
347
  # @return [String] The schema name declared in the file
354
348
  def extract_schema_name(schema_path)
355
- require_relative "../express/parser"
356
349
  repo = Expressir::Express::Parser.from_file(schema_path)
357
350
  schema = repo.schemas.first
358
351
  schema&.id || File.basename(schema_path, ".*")