expressir 2.4.11 → 2.4.12

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: 29d1099f121d8528e495476328a9388278187589c0358db455d57e231055a6dc
4
- data.tar.gz: 6cadd85e6d2b1184ff1cc53883857698f5c3b0d8985ac2f6f962986ceeb84326
3
+ metadata.gz: 76901fb66e21e9752a5ba64f7b80c23e92a7fa54fac6df80ba221d46bee358e3
4
+ data.tar.gz: d02e64ac60b0b670f31f665e3834553e29dfd8abc9f7ff51c22bc33dbafcbe11
5
5
  SHA512:
6
- metadata.gz: 82bd2f4cd92180180f6c9b831dd0964950cc8be5a71e51bd5e737a6538289dad0a7e7b0e91902e6462f7df5aa6878fa0b6ec58c99b019a88e8e8145322eec935
7
- data.tar.gz: 6c60ea124de34b72f42107538fce8d527488361957eeec4b42e0b7a1b769ac2e4254e17f292fd1be151902ee8a0dab2328d583c71e9290582019f28fc92987ac
6
+ metadata.gz: c6c20c797b67efe96bf149207c2283b6e8ba3054e17feda55630fbccf92d337bdfc3322c0a77408262bf1066a60a30b2f137c5f2d4f5a62f78bcea69f818e567
7
+ data.tar.gz: 39f8f5f287a3d01df2f84cc3667afc00632de391415f9b6aad21538623f167330de9ea3b8857ebe25490d946113d7a85637b5884625ec445b52d3d4a2663b214
data/README.adoc CHANGED
@@ -215,6 +215,8 @@ Commands:
215
215
  expressir flatten PATH # Flatten the interface closure into an ISO 10303-11:1994 longform schema
216
216
  expressir fix PATH # Rewrite self-schema-qualified references (#125)
217
217
  expressir format PATH # pretty print EXPRESS schema located at PATH
218
+ expressir mapping_validate PATH # Validate <<express:...>> links in a module mapping.yaml against its ARM/MIM closure
219
+ expressir xsd PATH -o OUT.xsd # Write an XML Schema rendering of the EXPRESS schema at PATH
218
220
  expressir help [COMMAND] # Describe available commands or one specific command
219
221
  expressir validate load *PATH # validate EXPRESS schema located at PATH
220
222
  expressir validate ascii PATH # Validate EXPRESS files for ASCII-only content (excluding remarks)
@@ -1266,7 +1268,38 @@ The default text output displays:
1266
1268
  This helps identify areas of your EXPRESS schemas that need documentation
1267
1269
  improvement.
1268
1270
 
1269
- === EXPRESS Changes files
1271
+ === Schema hyperlinked source faces
1272
+
1273
+ `Schema#source`, `Schema#source_hyperlinked`, and
1274
+ `Schema#formatted_hyperlinked(_adoc)` render a schema head or the full
1275
+ schema with cross-references either verbatim or as links (the adoc
1276
+ variant emits `<<schema.item,item>>` xref macros — render inside a
1277
+ `[source,subs="+macros"]` block for live links; see the
1278
+ `Expressir::Express::SmrlXml` and `Expressir::Express::Xsd` writers
1279
+ for the XML faces).
1280
+
1281
+ == MIM mapping validation (mapping.yaml)
1282
+
1283
+ `expressir mapping_validate PATH` loads a module `mapping.yaml`
1284
+ (lutaml-model typed: `Expressir::Mapping::Document`) and resolves every
1285
+ `<<express:SCHEMA.ITEM,ITEM>>` link against the ARM/MIM interface
1286
+ closure, reporting links whose schema or item is unknown.
1287
+
1288
+ == XML faces
1289
+
1290
+ - `Expressir::Express::SmrlXml.format(repository)` — the SMRL index
1291
+ block per schema (eeng wo-smrl-xml shape).
1292
+ - `Expressir::Express::Xsd.format(schema)` — an XML Schema rendering
1293
+ (entities as element/complexType, substitutionGroup for subtypes,
1294
+ enumeration facets).
1295
+
1296
+ == Lazy compiled-set access
1297
+
1298
+ `Expressir::Express::Core.lazy_set(artifact)` lists a compiled set's
1299
+ wire paths without hydrating and hydrates individual files on demand —
1300
+ renderers that touch one schema per page hydrate one schema per page.
1301
+
1302
+ == EXPRESS Changes files
1270
1303
 
1271
1304
  Expressir provides commands for working with EXPRESS Changes files that track
1272
1305
  schema modifications across versions.
@@ -304,6 +304,45 @@ fn set_count(_ruby: &Ruby, reader: &SetReader) -> usize {
304
304
  reader.set.files.len()
305
305
  }
306
306
 
307
+ /// Every wire path in the artifact, in artifact order — no hydration.
308
+ fn set_wire_paths(_ruby: &Ruby, reader: &SetReader) -> Result<magnus::Value, Error> {
309
+ let paths = RArray::with_capacity(reader.set.files.len());
310
+ for file in &reader.set.files {
311
+ paths.push(ruby_str(_ruby, &file.wire_path))?;
312
+ }
313
+ Ok(paths.as_value())
314
+ }
315
+
316
+ fn ruby_str(ruby: &Ruby, s: &str) -> magnus::Value {
317
+ ruby.str_new(s).as_value()
318
+ }
319
+
320
+ /// `[wire_path, model]` for ONE file, addressed by wire path — the
321
+ /// lazy-access path (M2): callers hydrate only the schemas a render
322
+ /// touches instead of the whole set.
323
+ fn set_hydrate_one(ruby: &Ruby, reader: &SetReader, wire_path: String) -> Result<magnus::Value, Error> {
324
+ let file = reader
325
+ .set
326
+ .files
327
+ .iter()
328
+ .find(|f| f.wire_path == wire_path)
329
+ .ok_or_else(|| {
330
+ Error::new(
331
+ ruby.exception_runtime_error(),
332
+ format!("wire path {wire_path} not in compiled set"),
333
+ )
334
+ })?;
335
+ let wire = file.wire().map_err(|e| {
336
+ Error::new(ruby.exception_runtime_error(), format!("{}: {e}", file.wire_path))
337
+ })?;
338
+ let mut cache = reader.cache.lock().expect("class cache");
339
+ let model = value_to_ruby(ruby, &mut cache, &wire)?;
340
+ let pair = RArray::with_capacity(2);
341
+ pair.push(ruby.str_new(&file.wire_path))?;
342
+ pair.push(model)?;
343
+ Ok(pair.as_value())
344
+ }
345
+
307
346
  /// `[wire_path, model]` for the next file in artifact order, nil at
308
347
  /// the end.
309
348
  fn set_next(ruby: &Ruby, reader: &SetReader) -> Result<magnus::Value, Error> {
@@ -441,6 +480,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
441
480
  set_class.define_method("digest", method!(set_digest, 0))?;
442
481
  set_class.define_method("count", method!(set_count, 0))?;
443
482
  set_class.define_method("next", method!(set_next, 0))?;
483
+ set_class.define_method("wire_paths", method!(set_wire_paths, 0))?;
484
+ set_class.define_method("hydrate_one", method!(set_hydrate_one, 1))?;
444
485
  set_class.define_method("matches_sources", method!(set_matches_sources, 1))?;
445
486
  Ok(())
446
487
  }
data/lib/expressir/cli.rb CHANGED
@@ -99,6 +99,18 @@ module Expressir
99
99
  Expressir::Commands::BenchmarkCache.new(options).run(path)
100
100
  end
101
101
 
102
+ desc "mapping_validate PATH", "Validate <<express:...>> links in a module mapping.yaml against its ARM/MIM closure"
103
+ def mapping_validate(path)
104
+ Expressir::Commands::MappingValidate.new(options).run(path)
105
+ end
106
+
107
+ desc "xsd PATH", "Write an XML Schema rendering of the EXPRESS schema at PATH"
108
+ method_option :output, type: :string, aliases: "-o",
109
+ desc: "Output file path (defaults to stdout)"
110
+ def xsd(path)
111
+ Expressir::Commands::Xsd.new(options).run(path)
112
+ end
113
+
102
114
  desc "validate SUBCOMMAND", "EXPRESS schema validation commands"
103
115
  subcommand "validate", Expressir::Commands::Validate
104
116
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Commands
5
+ # `expressir mapping validate` (#88): load a module mapping.yaml
6
+ # and resolve every <<express:...>> link against the ARM/MIM
7
+ # interface closure. Exits 1 when unknown links remain.
8
+ class MappingValidate < Base
9
+ def run(path)
10
+ document = Expressir::Mapping.load_file(path)
11
+ unknown = Expressir::Mapping.unknown_links(document, repository_for(path))
12
+
13
+ if unknown.empty?
14
+ say "all links resolve"
15
+ return
16
+ end
17
+
18
+ unknown.each do |link|
19
+ say "unknown: #{link.text}"
20
+ end
21
+ raise Thor::Error, "#{unknown.size} unknown link(s)"
22
+ end
23
+
24
+ private
25
+
26
+ def repository_for(path)
27
+ dir = File.dirname(File.expand_path(path))
28
+ arm = Dir[File.join(dir, "arm.exp")].first
29
+ mim = Dir[File.join(dir, "mim.exp")].first
30
+ roots = [arm, mim].compact
31
+ raise Thor::Error, "no arm.exp/mim.exp next to #{path}" if roots.empty?
32
+
33
+ files = roots.flat_map do |root|
34
+ ParityInputs.closure_paths(root)
35
+ end.uniq.select { |f| File.exist?(f) }
36
+ Expressir::Express::Parser.from_files(files)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Commands
5
+ # `expressir xsd` (#276): write the XML Schema rendering of the
6
+ # schema at PATH.
7
+ class Xsd < Base
8
+ def run(path)
9
+ repo = Expressir::Express::Parser.from_file(path)
10
+ schema = repo.schemas.first
11
+ raise Thor::Error, "no schema in #{path}" unless schema
12
+
13
+ xml = Expressir::Express::Xsd.format(schema)
14
+ if options[:output]
15
+ File.write(options[:output], xml)
16
+ say "written to #{options[:output]}"
17
+ else
18
+ $stdout.write(xml)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -24,5 +24,7 @@ module Expressir
24
24
  autoload :Version, "#{__dir__}/commands/version"
25
25
  autoload :Package, "#{__dir__}/commands/package"
26
26
  autoload :Manifest, "#{__dir__}/commands/manifest"
27
+ autoload :MappingValidate, "#{__dir__}/commands/mapping_validate"
28
+ autoload :Xsd, "#{__dir__}/commands/xsd"
27
29
  end
28
30
  end
@@ -43,6 +43,24 @@ module Expressir
43
43
  ::Expressir::Core.parse_to_model(source, path)
44
44
  end
45
45
 
46
+ # Lazy handle over a compiled-set artifact (M2): `wire_paths`
47
+ # lists the set's files without hydrating anything; `hydrate_one`
48
+ # builds a single file's model on demand. Renderers that touch
49
+ # one schema per page hydrate one schema per page instead of the
50
+ # whole repository.
51
+ def self.lazy_set(path)
52
+ unless NATIVE_AVAILABLE
53
+ raise NotImplementedError,
54
+ "lazy set unavailable without the native extension"
55
+ end
56
+ unless ::Expressir::Core.const_defined?(:Set) &&
57
+ ::Expressir::Core::Set.method_defined?(:hydrate_one)
58
+ raise NotImplementedError, "lazy set unavailable; ext too old"
59
+ end
60
+
61
+ ::Expressir::Core::Set.open(path)
62
+ end
63
+
46
64
  # Compile many files concurrently: jobs are [read_path,
47
65
  # wire_path] pairs; the block receives (wire_path, model, error)
48
66
  # per job in completion order. Workers run on native threads, so
@@ -3,6 +3,6 @@ module Expressir
3
3
  # autoload it (Ruby autoload only works for module/class constants, not
4
4
  # for string constants like `Expressir::VERSION`).
5
5
  module Version
6
- VERSION = "2.4.11".freeze
6
+ VERSION = "2.4.12".freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.11
4
+ version: 2.4.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -425,6 +425,7 @@ files:
425
425
  - lib/expressir/commands/flatten.rb
426
426
  - lib/expressir/commands/format.rb
427
427
  - lib/expressir/commands/manifest.rb
428
+ - lib/expressir/commands/mapping_validate.rb
428
429
  - lib/expressir/commands/non_ascii_character.rb
429
430
  - lib/expressir/commands/non_ascii_violation_collection.rb
430
431
  - lib/expressir/commands/package.rb
@@ -433,6 +434,7 @@ files:
433
434
  - lib/expressir/commands/validate_ascii.rb
434
435
  - lib/expressir/commands/validate_load.rb
435
436
  - lib/expressir/commands/version.rb
437
+ - lib/expressir/commands/xsd.rb
436
438
  - lib/expressir/config.rb
437
439
  - lib/expressir/coverage.rb
438
440
  - lib/expressir/eengine.rb