expressir 2.4.29 → 2.4.31

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: b184252cfd74dc73c8b656d0845145da64c9b895d24228f5478b35dad5b0b257
4
- data.tar.gz: 100a50bd158b0ef4884171572f01e266edb334baf253e463b47ff6c8fe579321
3
+ metadata.gz: 061350f84465e77142b15dc708e0773f77626084711b2ae46e859775d0c07c5d
4
+ data.tar.gz: 41101569510c6b020847410ab0bc83cf403163d04b78743bfc8085ca863b80f3
5
5
  SHA512:
6
- metadata.gz: fb99828d597bd207b51619f71ef1085ace7da40950d43573df25b704f1afb3381d444dbbff85f516a16161eb783b769640cd5c16d273543866118e755f268325
7
- data.tar.gz: 4ae05fe7e5dec49cdb04027545f62fe3fb25f240ed430eb6eff8e18bc612d3bb76cfbbe0a044d80395089c5535ed3d323a87b2f97c94fd801830dfe3cabf13da
6
+ metadata.gz: 739f6f3d5ea7d153b0e701204d1390710e1ec99bd3602a3d934df28aa6d8f6df407f8a1d83e799f8ba5f93b65bdffa891f1b6abba1965da955ef8f782deae39e
7
+ data.tar.gz: 87c334b0480296cc1b6f8161c0b91fbb9b2d5641d537f6e4f129eb0780fab9361254ff6708e20ecc186342a1ee2c3b0877f82d2debde038740952ec8bc938603
@@ -172,19 +172,33 @@ jobs:
172
172
  release:
173
173
  name: Release gems to rubygems
174
174
  needs: [native, smoke-linux, smoke-linux-arm, smoke-macos-arm, smoke-macos-intel, smoke-windows, source]
175
- if: startsWith(github.ref, 'refs/tags/v')
175
+ # workflow_dispatch lets a fix publish the already-tagged version when
176
+ # the tag's own run failed after the builds (reruns reuse the tag's
177
+ # workflow copy, so fixes cannot reach them any other way).
178
+ if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
176
179
  runs-on: ubuntu-22.04
177
- environment: release
180
+ # No environment: the rubygems.org trusted publisher for native-gems.yml
181
+ # is registered without one; an environment claim would fail the match.
182
+ permissions:
183
+ id-token: write
178
184
  steps:
179
185
  - uses: actions/download-artifact@v4
180
186
  with:
181
187
  path: pkg/
182
188
  pattern: cross-gem-*
183
189
  merge-multiple: true
190
+ - uses: actions/download-artifact@v4
191
+ with:
192
+ path: pkg/
193
+ name: source-gem
194
+ # OIDC trusted publishing - the repo has no rubygems API-key secret;
195
+ # release.yml publishes through the same exchange.
196
+ - uses: rubygems/configure-rubygems-credentials@v2.1.0
184
197
  - name: Push to rubygems
185
- env:
186
- GEM_HOST_API_KEY: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
187
198
  run: |
188
199
  for gem in pkg/expressir-*.gem; do
189
- gem push "$gem"
200
+ # Idempotent: a gem already on rubygems (e.g. the source gem
201
+ # shipped by release.yml ahead of the platform run) is a skip,
202
+ # not a failure.
203
+ gem push "$gem" || echo "::warning::$(basename "$gem") already published or rejected; continuing"
190
204
  done
data/expressir.gemspec CHANGED
@@ -42,18 +42,18 @@ Gem::Specification.new do |spec|
42
42
  spec.extensions = ["ext/expressir_core/extconf.rb"]
43
43
  spec.add_dependency "rb_sys", "~> 0.9.130"
44
44
 
45
- spec.add_dependency "base64"
45
+ spec.add_dependency "base64", ">= 0.1.0"
46
46
  spec.add_dependency "benchmark"
47
47
  spec.add_dependency "benchmark-ips"
48
48
  spec.add_dependency "csv"
49
- spec.add_dependency "liquid"
49
+ spec.add_dependency "liquid", "~> 5"
50
50
  spec.add_dependency "lutaml-model", "~> 0.8.76"
51
51
  spec.add_dependency "moxml"
52
- spec.add_dependency "nokogiri"
52
+ spec.add_dependency "nokogiri", "~> 1.19"
53
53
  spec.add_dependency "paint"
54
- spec.add_dependency "parsanol", "~> 1.3.9", ">= 1.3.9"
54
+ spec.add_dependency "parsanol", "~> 1.3.9", ">= 1.3.89"
55
55
  spec.add_dependency "ruby-progressbar", "~> 1.11"
56
- spec.add_dependency "rubyzip"
56
+ spec.add_dependency "rubyzip", "~> 3.7"
57
57
  spec.add_dependency "table_tennis"
58
58
  spec.add_dependency "thor", "~> 1.0"
59
59
  # Native YAML/JSON engine (lutaml-model opt-in by bundle contents)
@@ -113,7 +113,12 @@ module Expressir
113
113
  # Nearest ancestor directory NAMED `schemas`, or nil.
114
114
  def ancestor_schemas_dir(root_path)
115
115
  dir = File.dirname(File.expand_path(root_path))
116
- until dir == "/"
116
+ # dirname reaches a fixed point at the filesystem root: "/" on
117
+ # POSIX, "D:/" (or a UNC root) on windows. Comparing against "/"
118
+ # alone spun forever on windows - every rake run since this
119
+ # shipped (e0f6651, 2026-09-24) burned the full 6h runner
120
+ # budget in the first expand example (#487).
121
+ until dir == "/" || dir == File.dirname(dir)
117
122
  return dir if File.basename(dir) == "schemas"
118
123
 
119
124
  dir = File.dirname(dir)
@@ -21,7 +21,7 @@ module Expressir
21
21
  autoload :Changes, "#{__dir__}/commands/changes"
22
22
  autoload :ChangesValidate, "#{__dir__}/commands/changes_validate"
23
23
  autoload :ChangesImportEengine, "#{__dir__}/commands/changes_import_eengine"
24
- autoload :Version, "#{__dir__}/commands/version"
24
+ autoload :Version, "#{__dir__}/commands/version_command"
25
25
  autoload :Package, "#{__dir__}/commands/package"
26
26
  autoload :Manifest, "#{__dir__}/commands/manifest"
27
27
  autoload :MappingValidate, "#{__dir__}/commands/mapping_validate"
@@ -7,8 +7,15 @@ module Expressir
7
7
  # Ruby bridge to the expressir-core Rust crate (parse + model
8
8
  # extraction). Available when the native extension is built;
9
9
  # callers fall back to the pure-Ruby parser otherwise.
10
+ #
11
+ # Windows is excluded along with parsanol's native engine
12
+ # (Grammar::Parser.native_available?): the core embeds the
13
+ # parsanol-rs parse stack, whose x64-mingw build deadlocks the
14
+ # same way at first parse (expressir#487) - the compiled
15
+ # extension is present, so the gate is explicit rather than a
16
+ # LoadError consequence.
10
17
  module Core
11
- NATIVE_AVAILABLE = begin
18
+ NATIVE_AVAILABLE = !Gem.win_platform? && begin
12
19
  require "expressir/expressir_core"
13
20
  true
14
21
  rescue LoadError
@@ -27,6 +27,28 @@ module Expressir
27
27
  # Files above this use parse_fresh which has no packrat cache
28
28
  LARGE_FILE_THRESHOLD = 1024 * 1024 # 1 MB
29
29
 
30
+ # Whitespace rides the engine's injected trivia (parsanol-ruby
31
+ # #180's source-preserving mode, 1.3.82+): each unit records
32
+ # verbatim under :space and attaches to the next Named capture.
33
+ # Remarks stay OUT of the skip rule — they are product data,
34
+ # captured by the tailRemark/embeddedRemark rules and attached
35
+ # by RemarkScanner; tail remarks attach backward, the engine's
36
+ # next-capture channel is the wrong direction for them.
37
+ rule(:trivia) { match[" \r\n\t\f"].repeat(1) }
38
+ # exempt (parsanol#195, shipped 1.3.89): token rules whose bodies
39
+ # manage their own internals — injection before a char-class tail
40
+ # repetition absorbs the following token across whitespace
41
+ # ("RULE r FOR" parsed as one simpleId). simpleId additionally
42
+ # matches as a single quantified Re, which needs no exemption;
43
+ # the two mechanisms agree and stay for defense in depth.
44
+ # The whitespace/remark rules manage their own trivia end to end
45
+ # (they ARE the trivia surface for remarks); injection around
46
+ # them breaks consecutive remark lines on the Ruby engine
47
+ # ("-- X\n--\nSCHEMA ..." failed - the #487 windows follow-up,
48
+ # parsanol-ruby#195 family).
49
+ skip(:trivia, whitespace: :space,
50
+ exempt: %i[simpleId digits spaces space embeddedRemark tailRemark])
51
+
30
52
  # Get cached parser instance (thread-safe)
31
53
  # Reusing the parser avoids the overhead of reinitializing all rule definitions
32
54
  def self.cached_parser
@@ -46,6 +68,15 @@ module Expressir
46
68
 
47
69
  # Check if native parsing is available
48
70
  def self.native_available?
71
+ # parsanol 1.3.54+ x64-mingw builds deadlock inside the native
72
+ # parse at runtime: the library loads (early examples run) but
73
+ # the first parse never returns (expressir#487 — every windows
74
+ # rake run since 2026-09-29 hit the 6h limit; the control at
75
+ # green-era leptris/moxml/yeptris still hangs, parsanol 1.3.53
76
+ # was green). The pure-Ruby engine is correct, so windows falls
77
+ # back to it until parsanol fixes the mingw build.
78
+ return false if Gem.win_platform?
79
+
49
80
  return @native_available unless @native_available.nil?
50
81
 
51
82
  @native_available = begin
@@ -604,7 +635,13 @@ module Expressir
604
635
  (unaryOp >> simpleFactorExpression).as(:simpleFactorUnaryExpression)
605
636
  end
606
637
  rule(:simpleId) do
607
- anyKeyword.absent? >> cts((match["a-zA-Z_"] >> match["a-zA-Z0-9_"].repeat).as(:str)).as(:simpleId)
638
+ # One quantified Re, not lead >> tail-repeat: under skip
639
+ # injection the DSL interleaves trivia before the tail
640
+ # repetition, so a two-atom ident would absorb the following
641
+ # whitespace-separated identifier ("RULE r FOR (e)" parses
642
+ # "r FOR" as one simpleId). A quantified Re consumes the
643
+ # whole identifier in a single step — parsanol GH-69.
644
+ anyKeyword.absent? >> cts(match("[a-zA-Z_][a-zA-Z0-9_]*").as(:str)).as(:simpleId)
608
645
  end
609
646
  rule(:simpleStringLiteral) do
610
647
  cts((str("'") >> (str("'").absent? >> any).repeat >> str("'")).as(:str)).as(:simpleStringLiteral)
@@ -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.29".freeze
6
+ VERSION = "2.4.31".freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.29
4
+ version: 2.4.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-03 00:00:00.000000000 Z
11
+ date: 2026-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: benchmark
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: liquid
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '5'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '5'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: lutaml-model
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -126,16 +126,16 @@ dependencies:
126
126
  name: nokogiri
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: '1.19'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: '1.19'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: paint
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -159,7 +159,7 @@ dependencies:
159
159
  version: 1.3.9
160
160
  - - ">="
161
161
  - !ruby/object:Gem::Version
162
- version: 1.3.9
162
+ version: 1.3.89
163
163
  type: :runtime
164
164
  prerelease: false
165
165
  version_requirements: !ruby/object:Gem::Requirement
@@ -169,7 +169,7 @@ dependencies:
169
169
  version: 1.3.9
170
170
  - - ">="
171
171
  - !ruby/object:Gem::Version
172
- version: 1.3.9
172
+ version: 1.3.89
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: ruby-progressbar
175
175
  requirement: !ruby/object:Gem::Requirement
@@ -188,16 +188,16 @@ dependencies:
188
188
  name: rubyzip
189
189
  requirement: !ruby/object:Gem::Requirement
190
190
  requirements:
191
- - - ">="
191
+ - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: '0'
193
+ version: '3.7'
194
194
  type: :runtime
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
- - - ">="
198
+ - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: '0'
200
+ version: '3.7'
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: table_tennis
203
203
  requirement: !ruby/object:Gem::Requirement
@@ -463,7 +463,7 @@ files:
463
463
  - lib/expressir/commands/validate.rb
464
464
  - lib/expressir/commands/validate_ascii.rb
465
465
  - lib/expressir/commands/validate_load.rb
466
- - lib/expressir/commands/version.rb
466
+ - lib/expressir/commands/version_command.rb
467
467
  - lib/expressir/commands/xsd.rb
468
468
  - lib/expressir/config.rb
469
469
  - lib/expressir/coverage.rb