diff --git a/.github/workflows/rake.yml b/.github/workflows/rake.yml index 8b9e1329..8f6096de 100644 --- a/.github/workflows/rake.yml +++ b/.github/workflows/rake.yml @@ -18,12 +18,15 @@ jobs: env: BUNDLE_WITHOUT: "secryst" SKIP_JS: "1" - # The ISC corpus sweep (ISC_SWEEP=1) stays opt-in until the - # conformance gap it measures is closed: it currently exposes real - # per-map mismatches across the corpus. Run it locally with - # ISC_SWEEP=1 INTERSCRIPT_MAPS_PATH=../maps/maps \ - # rspec spec/interscript_spec.rb - # to track that gap; flip it on here once it goes green. + SKIP_PYTHON: "1" + ISC_SWEEP: "1" + # The ISC corpus sweep: every map's own tests through every + # supported compiler (Interpreter, Compiler::Ruby), against the + # ../maps sibling from the monorepo checkout. The conformance gap + # it measured is closed (16,482 examples, 0 failures — + # interscript-ruby#779..#786); this is now the CI conformance + # gate for the corpus. The experimental Python bridge is excluded + # (SKIP_PYTHON) until its own corpus conformance work lands. steps: - name: Checkout monorepo @@ -43,14 +46,26 @@ jobs: - name: Install Python helper and gems working-directory: ruby + # bash everywhere: the PYBIN substitution is POSIX shell, which + # PowerShell (the windows default) cannot parse. --break-system- + # packages rides out PEP 668 on Homebrew-managed macos Pythons. + shell: bash run: | bundle config set --local with jsexec bundle install - # PyCall binds whichever libpython it was built against, which - # is not necessarily the python that bare `pip` targets — - # install the regex helper into that interpreter. - PYBIN=$(bundle exec ruby -e 'require "pycall"; v = PyCall.sys.version[/\d+\.\d+/]; puts "python#{v}"') - "$PYBIN" -m pip install regex + if bundle exec ruby -e 'require "pycall"' >/dev/null 2>&1; then + # PyCall binds whichever libpython it was built against, which + # is not necessarily the python that bare `pip` targets — + # install the regex helper into that interpreter. + PYBIN=$(bundle exec ruby -e 'require "pycall"; v = PyCall.sys.version[/\d+\.\d+/]; puts "python#{v}"') + if command -v "$PYBIN" >/dev/null 2>&1; then + "$PYBIN" -m pip install --break-system-packages regex || "$PYBIN" -m pip install regex + else + echo "$PYBIN not on PATH — python helper not installed" + fi + else + echo "pycall not bundled (SKIP_PYTHON) — python helper not installed" + fi - name: RSpec working-directory: ruby diff --git a/lib/interscript/stdlib/functions/rababa_adapter.rb b/lib/interscript/stdlib/functions/rababa_adapter.rb index 1cf79d77..d700572d 100644 --- a/lib/interscript/stdlib/functions/rababa_adapter.rb +++ b/lib/interscript/stdlib/functions/rababa_adapter.rb @@ -1,7 +1,7 @@ class Interscript::Stdlib module Functions class RababaAdapter - @rababa_diacritizer = nil + @rababa_diacritizers = {} @mutex = Mutex.new class << self @@ -18,7 +18,7 @@ def reverse(output, config: nil) end def reset_cache - @mutex.synchronize { @rababa_diacritizer = nil } + @mutex.synchronize { @rababa_diacritizers.clear } end private @@ -26,7 +26,7 @@ def reset_cache def diacritizer_for(config_key) require_rababa! @mutex.synchronize do - @rababa_diacritizer ||= build_diacritizer(config_key) + @rababa_diacritizers[config_key] ||= build_diacritizer(config_key) end end diff --git a/spec/stdlib_functions_spec.rb b/spec/stdlib_functions_spec.rb index 17b1e716..db184cdf 100644 --- a/spec/stdlib_functions_spec.rb +++ b/spec/stdlib_functions_spec.rb @@ -56,9 +56,11 @@ describe ".rababa (without registered config)" do it "raises ExternalUtilError naming the missing config" do - expect { described_class.rababa("كتب", config: "default") }.to raise_error( + # A name that cannot be registered: the sweep's load path puts the + # monorepo's rababa-configs in scope, where "default" exists. + expect { described_class.rababa("كتب", config: "no-such-config") }.to raise_error( Interscript::ExternalUtilError, - /No rababa config registered under 'default'/ + /No rababa config registered under 'no-such-config'/ ) end end