expressir 2.1.15 → 2.1.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebacd504321a9a5298e41193d5739458ece4cb77971721a1abab68aa2d42a28f
4
- data.tar.gz: 8e9881151845c7716af9fe10088867f1fa3fb6ca37231db4c4c20ffef74f54c7
3
+ metadata.gz: 5018391261c5ce2fbad69c753c2e1b14e11b2cf39e49b57a984ec00be70e2055
4
+ data.tar.gz: 35b88b0188c829f57ec86455bfcd8f8ee073c0df8c0fa16456990eb28af33a00
5
5
  SHA512:
6
- metadata.gz: f44c8c856af5ce6b6c2bb72fc3a600ed58b0adcfad91371944d83c070d434a9472cbd06b2596e9f7ba20ca7ca3a258f9a7410a75625536bb7c36b2a73c4f094e
7
- data.tar.gz: 93c84f64ba62d33f358e5144d508db7db349ed67097f92dc0fc8ef5ab2139118d072609fdaabf7023529429fd33fc2867528f89cf5a73bd58db1ccf10a3eb44a
6
+ metadata.gz: 6e3b27dd2b3fd8709ae737ec43cc694630e90d2f49530520a7f7d27e86cbe635cf46b143b15c6cff339fed452929422c23b70f8fe066543407aa748fe40cf224
7
+ data.tar.gz: a0f67b51074b9db60f54f500ad3b15ad4f22cd58ddd5cd895bd39a792afd4d2be0eb1d94da28766622702634b216a4ce234e9c930462a528ffe1ee644f7aee02
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-03-19 17:57:28 UTC using RuboCop version 1.74.0.
3
+ # on 2025-03-21 10:31:17 UTC using RuboCop version 1.74.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -26,7 +26,7 @@ Lint/ShadowingOuterLocalVariable:
26
26
  Exclude:
27
27
  - 'lib/expressir/express/visitor.rb'
28
28
 
29
- # Offense count: 3
29
+ # Offense count: 2
30
30
  # This cop supports safe autocorrection (--autocorrect).
31
31
  # Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
32
32
  # NotImplementedExceptions: NotImplementedError
@@ -35,43 +35,50 @@ Lint/UnusedMethodArgument:
35
35
  - 'lib/expressir/express/cache.rb'
36
36
  - 'lib/expressir/express/parser.rb'
37
37
 
38
- # Offense count: 48
38
+ # Offense count: 61
39
39
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
40
40
  Metrics/AbcSize:
41
41
  Exclude:
42
+ - 'lib/expressir/benchmark.rb'
43
+ - 'lib/expressir/cli.rb'
44
+ - 'lib/expressir/config.rb'
42
45
  - 'lib/expressir/express/formatter.rb'
43
46
  - 'lib/expressir/express/hyperlink_formatter.rb'
47
+ - 'lib/expressir/express/parser.rb'
44
48
  - 'lib/expressir/express/resolve_references_model_visitor.rb'
45
49
  - 'lib/expressir/express/visitor.rb'
46
50
  - 'lib/expressir/model/declarations/schema.rb'
47
51
  - 'lib/expressir/model/model_element.rb'
48
52
 
49
- # Offense count: 1
53
+ # Offense count: 2
50
54
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
51
55
  # AllowedMethods: refine
52
56
  Metrics/BlockLength:
53
57
  Max: 141
54
58
 
55
- # Offense count: 40
59
+ # Offense count: 45
56
60
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
57
61
  Metrics/CyclomaticComplexity:
58
62
  Exclude:
63
+ - 'lib/expressir/benchmark.rb'
59
64
  - 'lib/expressir/express/formatter.rb'
60
65
  - 'lib/expressir/express/model_visitor.rb'
66
+ - 'lib/expressir/express/parser.rb'
61
67
  - 'lib/expressir/express/visitor.rb'
62
68
  - 'lib/expressir/model/declarations/schema.rb'
63
69
  - 'lib/expressir/model/model_element.rb'
64
70
  - 'spec/support/model_element_helper.rb'
65
71
 
66
- # Offense count: 67
72
+ # Offense count: 80
67
73
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
68
74
  Metrics/MethodLength:
69
- Max: 34
75
+ Max: 44
70
76
 
71
- # Offense count: 32
77
+ # Offense count: 35
72
78
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
73
79
  Metrics/PerceivedComplexity:
74
80
  Exclude:
81
+ - 'lib/expressir/benchmark.rb'
75
82
  - 'lib/expressir/express/formatter.rb'
76
83
  - 'lib/expressir/express/visitor.rb'
77
84
  - 'lib/expressir/model/declarations/schema.rb'
data/README.adoc CHANGED
@@ -30,7 +30,41 @@ Expressir consists of 3 parts:
30
30
  // ** OMG UML 2 for Eclipse (XMI 2.1)
31
31
 
32
32
 
33
- == Usage
33
+ == Installation
34
+
35
+ Add this line to your application's `Gemfile`:
36
+
37
+ [source, sh]
38
+ ----
39
+ gem "expressir"
40
+ ----
41
+
42
+ And then execute:
43
+
44
+ [source, sh]
45
+ ----
46
+ $ bundle install
47
+ ----
48
+
49
+ Or install it yourself as:
50
+
51
+ [source, sh]
52
+ ----
53
+ $ gem install expressir
54
+ ----
55
+
56
+
57
+ == Testing
58
+
59
+ Run the test suite:
60
+
61
+ [source, sh]
62
+ ----
63
+ bundle exec rake
64
+ ----
65
+
66
+
67
+ == Usage: CLI
34
68
 
35
69
  This gem ships with a CLI tool. To check what's available you can simply run
36
70
  `expressir`, by default it will display some usage instructions.
@@ -40,9 +74,13 @@ This gem ships with a CLI tool. To check what's available you can simply run
40
74
  $ expressir
41
75
 
42
76
  Commands:
43
- expressir format PATH # pretty print EXPRESS schema located at PATH
44
- expressir help [COMMAND] # Describe available commands or one specific command
45
- expressir version # The Expressir Version
77
+ expressir benchmark FILE_OR_YAML # Benchmark schema loading performance for a file or list of files from YAML
78
+ expressir benchmark-cache FILE_OR_YAML # Benchmark schema loading with caching
79
+ expressir clean PATH # Strip remarks and prettify EXPRESS schema at PATH
80
+ expressir format PATH # pretty print EXPRESS schema located at PATH
81
+ expressir help [COMMAND] # Describe available commands or one specific command
82
+ expressir validate *PATH # validate EXPRESS schema located at PATH
83
+ expressir version # Expressir Version
46
84
  ----
47
85
 
48
86
  === Pretty print
@@ -52,97 +90,189 @@ Commands:
52
90
  expressir format schemas/resources/action_schema/action_schema.exp
53
91
  ----
54
92
 
93
+ === Clean schema
94
+
95
+ The `clean` command strips remarks and prettifies EXPRESS schemas. You can
96
+ optionally save the result to a file.
97
+
98
+ [source, sh]
99
+ ----
100
+ # Output to stdout
101
+ expressir clean schemas/resources/action_schema/action_schema.exp
55
102
 
56
- == Development
103
+ # Save to file
104
+ expressir clean schemas/resources/action_schema/action_schema.exp --output clean_schema.exp
105
+ ----
57
106
 
58
- We are following Sandi Metz's Rules for this gem, you can read
59
- the http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers[description of the rules here] All new code should follow these rules.
60
- If you make changes in a pre-existing file that violates these rules you should
61
- fix the violations as part of your contribution.
107
+ === Benchmarking
62
108
 
63
- === Setup
109
+ Expressir includes powerful benchmarking capabilities for measuring schema
110
+ loading performance. You can benchmark individual files or multiple files listed
111
+ in a YAML configuration.
64
112
 
65
- Clone the repository.
113
+ ==== Benchmark a single file
66
114
 
67
115
  [source, sh]
68
116
  ----
69
- git clone https://github.com/metanorma/expressir
117
+ # Basic benchmarking
118
+ expressir benchmark schemas/resources/action_schema/action_schema.exp
119
+
120
+ # With detailed output
121
+ expressir benchmark schemas/resources/action_schema/action_schema.exp --verbose
122
+
123
+ # Using benchmark-ips for more detailed statistics
124
+ expressir benchmark schemas/resources/action_schema/action_schema.exp --ips
125
+
126
+ # With specific output format
127
+ expressir benchmark schemas/resources/action_schema/action_schema.exp --format json
128
+ ----
129
+
130
+ ==== Benchmark multiple files from YAML
131
+
132
+ Create a YAML file with a list of schema paths:
133
+
134
+ .schemas.yml
135
+ [source, yaml]
136
+ ----
137
+ schemas:
138
+ - schemas/resources/action_schema/action_schema.exp
139
+ - schemas/resources/approval_schema/approval_schema.exp
140
+ - schemas/resources/date_time_schema/date_time_schema.exp
70
141
  ----
71
142
 
72
- Setup your environment.
143
+ Then benchmark all schemas at once:
73
144
 
74
145
  [source, sh]
75
146
  ----
76
- bin/setup
77
- git submodule update --init
78
- bundle exec rake generate
79
- bundle exec rake compile
147
+ expressir benchmark schemas.yml --verbose
80
148
  ----
81
149
 
82
- Run the test suite
150
+ ==== Benchmark with caching
151
+
152
+ You can also benchmark schema loading with caching to measure parsing time,
153
+ cache writing time, and cache reading time:
83
154
 
84
155
  [source, sh]
85
156
  ----
86
- bundle exec rake
157
+ # Benchmark a single file with caching
158
+ expressir benchmark-cache schemas/resources/action_schema/action_schema.exp
159
+
160
+ # With custom cache location
161
+ expressir benchmark-cache schemas/resources/action_schema/action_schema.exp --cache_path /tmp/schema_cache.bin
162
+
163
+ # Benchmark multiple files from YAML with caching
164
+ expressir benchmark-cache schemas.yml --verbose
87
165
  ----
88
166
 
167
+ ==== Benchmark options
89
168
 
169
+ The benchmark commands support several options:
90
170
 
91
- == Installation
171
+ [options="header"]
172
+ |===
173
+ | Option | Description
174
+ | `--ips` | Use benchmark-ips for detailed statistics
175
+ | `--verbose` | Show detailed output
176
+ | `--save` | Save benchmark results to file
177
+ | `--format FORMAT` | Output format: json, csv, or default
178
+ | `--cache_path PATH` | (benchmark-cache only) Path to store the cache file
179
+ |===
92
180
 
93
- Add this line to your application's `Gemfile`:
181
+ When using the `--format json` option, results will be output in JSON format,
182
+ making it easy to parse for further analysis or visualization.
94
183
 
95
- [source, sh]
184
+
185
+
186
+ == Usage: Ruby
187
+
188
+ === Parsing EXPRESS schema files
189
+
190
+ ==== General
191
+
192
+ The library provides two main methods for parsing EXPRESS files.
193
+
194
+ ==== Parsing a single file
195
+
196
+ Use the `from_file` method to parse a single EXPRESS schema file:
197
+
198
+ [source,ruby]
96
199
  ----
97
- gem "expressir"
200
+ # Parse a single file
201
+ repository = Expressir::Express::Parser.from_file("path/to/schema.exp")
202
+
203
+ # With options
204
+ repository = Expressir::Express::Parser.from_file(
205
+ "path/to/schema.exp",
206
+ skip_references: false, # Set to true to skip resolving references
207
+ include_source: true, # Set to true to include original source in the model
208
+ root_path: "/base/path" # Optional base path for relative paths
209
+ )
98
210
  ----
99
211
 
100
- And then execute:
212
+ The `from_file` method will raise a `SchemaParseFailure` exception if the schema
213
+ fails to parse, providing information about the specific file and the parsing
214
+ error:
101
215
 
102
- [source, sh]
216
+ [source,ruby]
103
217
  ----
104
- $ bundle install
218
+ begin
219
+ repository = Expressir::Express::Parser.from_file("path/to/schema.exp")
220
+ rescue Expressir::Express::Error::SchemaParseFailure => e
221
+ puts "Failed to parse schema: #{e.message}"
222
+ puts "Filename: #{e.filename}"
223
+ puts "Error details: #{e.parse_failure_cause.ascii_tree}"
224
+ end
105
225
  ----
106
226
 
107
- Or install it yourself as:
227
+ ==== Parsing multiple files
108
228
 
109
- [source, sh]
229
+ Use the `from_files` method to parse multiple EXPRESS schema files:
230
+
231
+ [source,ruby]
110
232
  ----
111
- $ gem install expressir
233
+ # Parse multiple files
234
+ files = ["schema1.exp", "schema2.exp", "schema3.exp"]
235
+ repository = Expressir::Express::Parser.from_files(files)
112
236
  ----
113
237
 
238
+ You can provide a block to track loading progress and handle errors:
114
239
 
115
- == Usage
240
+ [source,ruby]
241
+ ----
242
+ files = ["schema1.exp", "schema2.exp", "schema3.exp"]
243
+ repository = Expressir::Express::Parser.from_files(files) do |filename, schemas, error|
244
+ if error
245
+ puts "Error loading #{filename}: #{error.message}"
246
+ # Skip the file with an error or take other action
247
+ else
248
+ puts "Successfully loaded #{schemas.length} schemas from #{filename}"
249
+ end
250
+ end
251
+ ----
116
252
 
117
253
  === Filtering out schemas
118
254
 
119
- Use the `select_proc` argument of `to_hash`.
120
-
121
- Example:
255
+ You can filter out specific schemas from the repository easily since
256
+ `Expressir::Model::Repository` implements `Enumerable`.
122
257
 
123
258
  [source,ruby]
124
259
  ----
125
-
126
260
  schema_yaml = YAML.load_file('documents/iso-10303-41/schemas.yaml')
127
261
  schema_paths = schema_yaml['schemas'].map {|x,y| y['path'].gsub("../../", "")}
128
262
 
129
263
  repo = Expressir::Express::Parser.from_files(schema_paths)
130
264
 
131
265
  filtered_schemas = ["action_schema", "date_time_schema"]
132
- select_proc = Proc.new do |value|
133
- if value.is_a?(Expressir::Model::Declarations::Schema)
134
- filtered_schemas.include?(value.id)
135
- else
136
- true
137
- end
266
+ repo.select do |schema|
267
+ filtered_schemas.include?(schema.name)
268
+ end.each do |schema|
269
+ puts "Schema name: #{schema.name}"
270
+ puts "Schema file: #{schema.file}"
271
+ puts "Schema version: #{schema.version}"
138
272
  end
139
-
140
- repo_hash = repo.to_hash(select_proc: select_proc)
141
- schemas = repo_hash['schemas']
142
- schemas.map {|s| s["id"] }
143
273
  ----
144
274
 
145
- === Convert models to liquid
275
+ === Convert models to Liquid
146
276
 
147
277
  Use `to_liquid` method to convert the models of `Expressir::Model::*` to liquid
148
278
  drop models (`Expressir::Liquid::*`).
@@ -158,24 +288,24 @@ repo_drop = repo.to_liquid
158
288
  where `repo` is an instance of `Expressir::Model::Repository` and
159
289
  `repo_drop` is an instance of `Expressir::Liquid::RepositoryDrop`.
160
290
 
161
- The liquid drop models of `Expressir::Liquid::*` have the same attributes
291
+ The Liquid drop models of `Expressir::Liquid::*` have the same attributes
162
292
  (`model_attr`) as the models of `Expressir::Model::*`.
163
293
 
164
294
  For example, `Expressir::Model::Repository` has the following attributes:
165
295
 
166
- - schemas
296
+ * `schemas`
167
297
 
168
298
  and each `Expressir::Model::Declarations::Schema` has the following attributes:
169
299
 
170
- - file
171
- - version
172
- - interfaces
173
- - constants
174
- - entities
175
- - subtype_constraints
176
- - functions
177
- - rules
178
- - procedures
300
+ * `file`
301
+ * `version`
302
+ * `interfaces`
303
+ * `constants`
304
+ * `entities`
305
+ * `subtype_constraints`
306
+ * `functions`
307
+ * `rules`
308
+ * `procedures`
179
309
 
180
310
  Thus, `Expressir::Liquid::Repository` has the same attribute `schemas`
181
311
  and `Expressir::Liquid::Declarations::SchemaDrop` has same attribute `file`.
@@ -188,6 +318,7 @@ schema = repo_drop.schemas.first
188
318
  schema.file = "path/to/file.exp"
189
319
  ----
190
320
 
321
+
191
322
  == Contributing
192
323
 
193
324
  First, thank you for contributing! We love pull requests from everyone. By
@@ -207,12 +338,23 @@ Here are a few technical guidelines to follow:
207
338
  * Party!
208
339
 
209
340
 
341
+ == Documentation
342
+
343
+ Expressir provides detailed documentation on various aspects of its functionality:
344
+
345
+ * link:docs/benchmarking.adoc[Benchmarking]: Learn about Expressir's built-in
346
+ capabilities for measuring schema loading performance, particularly useful for
347
+ large schemas or when optimizing performance.
348
+
349
+ * link:docs/liquid_drops.adoc[Liquid Integration]: Documentation on how to use
350
+ Expressir models with Liquid templates for flexible document generation.
351
+
210
352
  == License
211
353
 
212
354
  Expressir is distributed under the BSD 2-clause license.
213
355
 
214
- Expressir originally contained some code from the NIST Reeper project but
215
- has been completely rewritten.
356
+ NOTE: Expressir originally contained some code from the NIST Reeper project but no
357
+ longer contains them.
216
358
 
217
359
  The https://www.nist.gov/services-resources/software/reeper[NIST Reeper license]
218
360
  is reproduced below:
@@ -0,0 +1,107 @@
1
+ = Benchmarking schema loading in Expressir
2
+
3
+ Expressir provides built-in benchmarking capabilities for measuring schema
4
+ loading performance. This is particularly useful for large schemas or when
5
+ optimizing performance.
6
+
7
+ == Activating benchmark mode
8
+
9
+ Benchmark mode can be activated using environment variables:
10
+
11
+ [source,bash]
12
+ ----
13
+ # Basic benchmarking
14
+ EXPRESSIR_BENCHMARK=true ruby your_script.rb
15
+
16
+ # Verbose output with timing for each file
17
+ EXPRESSIR_BENCHMARK=true EXPRESSIR_BENCHMARK_VERBOSE=true ruby your_script.rb
18
+
19
+ # Use benchmark-ips for more detailed statistics
20
+ EXPRESSIR_BENCHMARK=true EXPRESSIR_BENCHMARK_IPS=true ruby your_script.rb
21
+
22
+ # Save benchmark results to file
23
+ EXPRESSIR_BENCHMARK=true EXPRESSIR_BENCHMARK_SAVE=true ruby your_script.rb
24
+ ----
25
+
26
+ == Environment variables
27
+
28
+ The following environment variables control benchmarking:
29
+
30
+ |===
31
+ | Variable | Description | Default
32
+
33
+ | `EXPRESSIR_BENCHMARK`
34
+ | Enable benchmarking mode
35
+ | `false`
36
+
37
+ | `EXPRESSIR_BENCHMARK_IPS`
38
+ | Use benchmark-ips for detailed statistics
39
+ | `false`
40
+
41
+ | `EXPRESSIR_BENCHMARK_VERBOSE`
42
+ | Show verbose output for benchmarking
43
+ | `false`
44
+
45
+ | `EXPRESSIR_BENCHMARK_SAVE`
46
+ | Save benchmark results to file
47
+ | `false`
48
+
49
+ | `EXPRESSIR_BENCHMARK_ITERATIONS`
50
+ | Number of iterations for benchmark-ips
51
+ | `3`
52
+
53
+ | `EXPRESSIR_BENCHMARK_WARMUP`
54
+ | Warmup time for benchmark-ips in seconds
55
+ | `1`
56
+
57
+ | `EXPRESSIR_BENCHMARK_PARALLEL`
58
+ | Enable parallel processing (future feature)
59
+ | `false`
60
+ |===
61
+
62
+ == Sample usage
63
+
64
+ A sample benchmark script is provided at
65
+ `spec/benchmarks/schema_loading_benchmark.rb`. You can run it with various
66
+ configurations to see the benchmarking in action:
67
+
68
+ [source,bash]
69
+ ----
70
+ # Basic benchmarking
71
+ EXPRESSIR_BENCHMARK=true ruby spec/benchmarks/schema_loading_benchmark.rb
72
+
73
+ # Detailed IPS benchmarking
74
+ EXPRESSIR_BENCHMARK=true EXPRESSIR_BENCHMARK_IPS=true ruby spec/benchmarks/schema_loading_benchmark.rb
75
+ ----
76
+
77
+ == Programmatic access
78
+
79
+ You can also access benchmarking functionality programmatically:
80
+
81
+ [source,ruby]
82
+ ----
83
+ require 'expressir'
84
+
85
+ # Check if benchmarking is enabled
86
+ if Expressir.configuration.benchmark_enabled?
87
+ puts "Benchmarking is active"
88
+ end
89
+
90
+ # Measure a specific operation
91
+ result = Expressir::Benchmark.measure_file("path/to/file.exp") do
92
+ # Code to benchmark
93
+ do_something()
94
+ end
95
+
96
+ # Measure a collection of files
97
+ results = Expressir::Benchmark.measure_collection(files) do |file|
98
+ # Process each file
99
+ process_file(file)
100
+ end
101
+ ----
102
+
103
+ == Future features
104
+
105
+ Future versions of Expressir will include parallel schema loading capabilities
106
+ that can be benchmarked using the `EXPRESSIR_BENCHMARK_PARALLEL=true`
107
+ environment variable.
data/expressir.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["open.source@ribose.com"]
10
10
 
11
11
  spec.summary = "EXPRESS parser and toolkit for Ruby"
12
- spec.description = "Expressir (EXPRESS in Ruby) is a Ruby parser for EXPRESS and a set of tools for accessing EXPRESS data models."
12
+ spec.description = 'Expressir ("EXPRESS in Ruby") is a Ruby parser for EXPRESS and a set of tools for accessing EXPRESS data models.'
13
13
 
14
14
  spec.homepage = "https://github.com/lutaml/expressir"
15
15
  spec.license = "BSD-2-Clause"
@@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
33
33
 
34
34
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
35
35
 
36
+ spec.add_dependency "benchmark-ips"
37
+ spec.add_dependency "csv"
36
38
  spec.add_dependency "liquid"
37
39
  spec.add_dependency "lutaml-model", "~>0.7"
38
40
  spec.add_dependency "parslet", "~> 2.0"