Bind go-ruby-grape, go-ruby-rubocop, go-ruby-xslt and go-ruby-activerecord into rbgo as native modules#102
Merged
Merged
Conversation
Nokogiri::XSLT(str)/.parse -> Stylesheet#transform (Nokogiri::XML::Document) and #apply_to/#serialize (serialised String), over go-ruby-xslt's pure-Go XSLT 1.0 engine on the go-ruby-nokogiri DOM. Stylesheet params passed as a Hash. Rides the existing "nokogiri" require feature. 100% coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RuboCop::Runner.new([config])#inspect(source[, path]) -> [Cop::Offense] (cop_name/message/severity/line/column/location/correctable?) and #autocorrect -> corrected String, over go-ruby-rubocop's pure-Go core cop set on the go-ruby-parser AST. RuboCop::Config.new/.parse(yml); malformed yml raises RuboCop::Error. File-walking is the documented host seam. 100% coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Grape::Router.new #get/#post/#put/#patch/#delete/#head + #match -> Match
(#status/#ok?/#params/#route/#allowed); Grape::Validator.new { params DSL }
#validate coerces or raises Grape::Exceptions::ValidationErrors;
Grape::Formatter #format/#json/#txt/#xml + Grape.mime_for/.default_status,
over go-ruby-grape's deterministic router/coercion/formatting. Endpoint-block
exec + Rack env are documented host seams. 100% coverage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eries via go-ruby-sqlite3
require "active_record" installs ActiveRecord::Base/Model/Relation/Record/
Errors/Schema over the go-ruby-activerecord library:
- ActiveRecord::Model.new(name, table) { column …; validates_* …; belongs_to/
has_many … } builds a mapped model whose #all/#where/#select/#order/#group/
#having/#joins/#limit/#offset/#distinct/#not return chainable relations, and
#to_sql renders ActiveRecord::Relation#to_sql byte-faithfully. #build/#new
make validating Record instances; #insert_sql renders the INSERT.
- ActiveRecord::Base.establish_connection(database:/path) opens a real
go-ruby-sqlite3 database and installs it as the process adapter (the executor
seam), so a relation's #to_a/#count/#exists?/#first/#pluck and Model#create
run actual SQL against sqlite3; #connection exposes the SQLite3::Database.
- Record carries #[]/#[]=/#attributes/#valid?/#errors/#changed?; Errors is the
ActiveModel::Errors shape (#full_messages/#messages/#[]/#empty?/#count).
- ActiveRecord::Schema.add_column_sql/add_index_sql are the deterministic DDL
generators. The ActiveRecordError/StatementInvalid/RecordInvalid/
ConnectionNotEstablished error tree matches the gem.
SQL rendering + validation are deterministic Go; execution is the sqlite3
adapter. 100% coverage: Ruby-level tests for every binding line and error arm,
white-box tests for the Go-only mapper arms (arValueToRuby int/bool/fallback,
AdapterName, arInt). The bad-connection test builds its path with
filepath.ToSlash for Windows safety; no timezone-dependent assertions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tannevaled
added a commit
that referenced
this pull request
Jul 2, 2026
…require PR #102 landed the go-ruby-activerecord binding on main, so `require "active_record"` now succeeds — but the binding does not yet implement `ActiveRecord::Schema.define`, so stage 4b's route hard-failed with `NoMethodError: undefined method 'define' for Module`. Feature-detect the specific ORM capability the route uses, mirroring the skip-until-present pattern of the Sinatra stage: a Ruby probe runs the exact chain (establish_connection + Schema.define + create! + where(...).order.to_a) inside a rescue and reports "READY" only when it all runs clean, else "GAP: <ExceptionClass>: <message>". Stage 4b skips-with-gap when the ORM path is incomplete and flips to a hard assertion automatically once the binding gains the methods. Recorded gap: NoMethodError: undefined method 'define' for Module (ActiveRecord::Schema lacks .define). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tannevaled
added a commit
that referenced
this pull request
Jul 2, 2026
…#103) * test(conformance): add reference-app RUN-conformance harness for web apps Prove rbgo can *run* real Ruby web apps end-to-end (run, not just parse) by driving the Rack call(env) contract directly with a synthetic Rack env — no TCP socket, no network. scripts/conformance/webapp/ stages real .rb apps through the public ruby.Run API and asserts the deterministic response: Stage 1 Pure Rack lambda -> GREEN Stage 2 Rack + ERB view -> GREEN Stage 3 Sinatra DSL (require sinatra/base) -> GAP (no sinatra binding) Stage 4 sqlite3 + ERB/JSON data route -> GREEN Stage 4b ActiveRecord ORM data route -> GAP (go-ruby-activerecord, PR #102) A data-backed route (in-memory sqlite3 seed + query + ERB/JSON render) is servable through rbgo today via the raw sqlite3 binding (stage 4). The Sinatra and ActiveRecord stages feature-detect the require: they assert the real response when the binding is present and otherwise record the exact missing feature, so the suite stays green now and lights up automatically when the binding lands. Test-only package: no new production code, so the 100%-coverage gate (coverpkg=./internal/...) is unaffected. Apps embedded via go:embed so the suite is CWD-independent under the coverage job, on Windows, and under qemu on every 64-bit target. Deterministic and TZ-independent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(conformance): probe AR ORM capability in stage 4b, not just the require PR #102 landed the go-ruby-activerecord binding on main, so `require "active_record"` now succeeds — but the binding does not yet implement `ActiveRecord::Schema.define`, so stage 4b's route hard-failed with `NoMethodError: undefined method 'define' for Module`. Feature-detect the specific ORM capability the route uses, mirroring the skip-until-present pattern of the Sinatra stage: a Ruby probe runs the exact chain (establish_connection + Schema.define + create! + where(...).order.to_a) inside a rescue and reports "READY" only when it all runs clean, else "GAP: <ExceptionClass>: <message>". Stage 4b skips-with-gap when the ORM path is incomplete and flips to a hard assertion automatically once the binding gains the methods. Recorded gap: NoMethodError: undefined method 'define' for Module (ActiveRecord::Schema lacks .define). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: clarify stage 4b probes the AR ORM chain, not just the require Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: align stage 4b fixture header with the AR ORM capability probe Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Binds batch 7 of the go-ruby-* stdlib satellites into rbgo as native, CGO=0 modules. SQL rendering / linting / templating stay deterministic Go; the one execution seam (ActiveRecord) is wired to the already-bound go-ruby-sqlite3.
Modules
require "grape"—Grape::Router(route matching + path params),Grape::Validator(presence/type/values param validation),Grape::Formatter(json/txt), and theGrape::Exceptionstree, over go-ruby-grape. Endpoint-block execution and the Rack env are documented host seams.require "rubocop"—RuboCop::Runner#inspect/#autocorrectandRuboCop::Cop::Offense, over go-ruby-rubocop (which parses with go-ruby-parser). Reports offenses and applies autocorrections.require "nokogiri"(XSLT) —Nokogiri::XSLT(stylesheet)/Nokogiri::XSLT::Stylesheet#transform+#apply_to, over go-ruby-xslt, extending the existing Nokogiri surface.require "active_record"—ActiveRecord::Base/Model/Relation/Record/Errors/Schemaover go-ruby-activerecord:ActiveRecord::Model.new(name, table) { column …; validates_* …; belongs_to/has_many … }builds a mapped model whose#all/#where/#select/#order/#group/#having/#joins/#limit/#offset/#distinct/#notreturn chainable relations;#to_sqlrendersActiveRecord::Relation#to_sqlbyte-faithfully.ActiveRecord::Base.establish_connection(database:/path)opens a real go-ruby-sqlite3 database and installs it as the process adapter (the executor seam), so a relation's#to_a/#count/#exists?/#first/#pluckandModel#createrun actual SQL against sqlite3.#connectionexposes theSQLite3::Database.Recordcarries#[]/#[]=/#attributes/#valid?/#errors/#changed?;Errorsis the ActiveModel::Errors shape;Schema.add_column_sql/add_index_sqlare the DDL generators. TheActiveRecordError/StatementInvalid/RecordInvalid/ConnectionNotEstablishedtree matches the gem.Coverage / portability
100% coverage on all four bindings — Ruby-level tests for every binding line and error arm, white-box unit tests for the Go-only mapper arms (
arValueToRubyint/bool/fallback,AdapterName,arInt). The ActiveRecord bad-connection test builds its path withfilepath.ToSlashfor Windows safety; no timezone- or shell-dependent assertions.gofmt/go vetclean; the exact-race -coverpkggate reports total 100.0%.🤖 Generated with Claude Code