Skip to content

fix(ruby): stop sub-SDKs named after Ruby or SDK constants from shadowing them - #206

Merged
2ynn merged 1 commit into
mainfrom
fix/ruby/qualify-core-constants
Nov 10, 2026
Merged

2ynn merged 1 commit into
mainfrom
fix/ruby/qualify-core-constants

Conversation

@2ynn

@2ynn 2ynn commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Why

Generated Ruby code lives inside the SDK module, and every tag becomes a sub-SDK class directly under it. Unqualified constant references in the templates therefore resolved to a same-named sub-SDK instead of the intended constant:

  • File.extname, Time.now, Date.iso8601, is_a? Hash and similar failed srb tc when a spec had a File, Time, Date or Hash tag.
  • include Kernel made the gem fail to load when a spec had a Kernel tag.
  • A Utils or SDKHooks tag replaced the SDK's own module (Utils is not a class). An SDKConfiguration tag overwrote sdkconfiguration.rb and the @sdk_configuration instance variable.

What changed

  • Ruby core and stdlib constants (::String, ::JSON, ::File, ::StandardError, ...) are prefixed with :: in the SDK templates and in the TypeScript helpers that emit Ruby code.
  • Usage snippets are top-level Ruby, so their date, date-time, file and environment variable example values stay unqualified (rubyConstantRef). Model defaults and generated tests keep the prefix.
  • Sub-SDKs whose class or file name matches an SDK internal (Utils, SDKHooks, SDKConfiguration, sdkconfiguration.rb) get an SDK suffix, repeated until the name is free of every other sub-SDK and the main SDK file (subSDKTypeName). A sub-SDK accessor named sdk_configuration becomes sdk_configuration_ (sanitizeSubSDKFieldName).
  • Schemas keep their names: models live under Models:: and do not shadow these constants.
  • New snapshot tests, each compiled with srb tc and rubocop:
    • TestSnapRubySubSDKCoreConstantCollision: tags File, Time, Hash, Class, Kernel, Utils, Date, String, Array, SDKConfiguration, SDKHooks, UtilsSDK.
    • TestSnapRubySubSDKReservedNameNesting: sdkClassName: UtilsSDK with a Utils tag (sub-SDK becomes UtilsSDKSDK), plus nested groups admin.SDKConfiguration and admin.SDKHooks.
    • TestSnapRubyCoreConstantExampleValues: date, date-time and file example values stay unqualified in USAGE.md and use :: in generated tests.
  • Existing Ruby namespace snapshots are updated for the :: prefixes.
  • Ruby review SDK regenerated. The diff contains only :: qualification, formatter re-wrapping and the matching gen.lock checksums.

Drive-by: date and date-time doc links

Unrelated to the shadowing fix. Ruby docs linked date fields to DateTime and date-time fields to Date. templates/templates/ruby/includes/documentation.ts now swaps them back, with its own changeset (docs, patch). In the review SDK this only changes four docs pages and their gen.lock checksums.

Testing

  • go test ./pkg/generate/snapshots/namespaces/ -run Ruby -count=1 with Ruby 3.2.11 and Go 1.26.10: all 6 Ruby snapshot tests generate, compile (srb tc, rubocop) and match.
  • make lint steps: prettier, go mod tidy -diff, tsgo for the Ruby templates and golangci-lint all pass.
  • Each reserved tag (Utils, SDKHooks, SDKConfiguration, sdk_configuration) was generated with main and with this branch, then loaded with SDK.new. On main, all four fail to load (Utils is not a class, SDKHooks is not a module, wrong number of arguments (given 1, expected 6)). On this branch they load and the accessors return the renamed sub-SDKs. The renames therefore only affect SDKs that could not be used before.
  • TARGET=review make build-ruby passes (srb tc, rubocop, mock-server build and staticcheck).
  • A large production-scale spec with many tags regenerates and passes srb tc and rubocop (5039 files, no offenses).

Known and out of scope: the tag pair SDKConfiguration + sdkconfiguration (already renamed upstream to SDKConfiguration1 / Sdkconfiguration2) still fails at runtime because attr_accessor is derived from Type.Name while the instance variable is derived from FieldName. This mismatch predates this change.

Public-safety check

  • This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
  • Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (.claude/skills/public-repo-communication/SKILL.md).
  • Generated fixtures and review SDK changes are public-safe.
  • I reviewed git diff --check.

@github-actions github-actions Bot added the ruby Trigger (19) snapshot tests for ruby label Nov 9, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 93 files

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Get a Slack DM when cubic finishes reviewing your PRs. Connect Slack

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread .changesets/1794269653-401e804c.yaml Resolved
@2ynn
2ynn force-pushed the fix/ruby/qualify-core-constants branch from 23a4842 to bc7275a Compare November 9, 2026 23:52

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 3 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Fixes Ruby generator collisions by qualifying core constants with :: and suffix-renaming sub-SDKs that shadow SDK internals, with snapshot tests pinning the corrected output; the renames only affect specs that previously failed to load.

View guided diff | Turn on auto-fix | Re-trigger cubic

@speakeasy-generator-bot

speakeasy-generator-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Generator Snapshot Testing

Selector(s) Result Summary
snapshot-ruby ✅ Snapshot run completed

Snapshot results: https://github.com/speakeasy-api/openapi-generation-snapshots/issues/162#issuecomment-6755288845

Snapshot results are summarized above. Additional run context is linked for maintainers with access.

@2ynn
2ynn force-pushed the fix/ruby/qualify-core-constants branch 2 times, most recently from 5dd5d29 to 18babcb Compare November 10, 2026 00:00
Comment on lines +152 to +155
return `[DateTime](https://ruby-doc.org/stdlib-2.6.1/libdoc/date/rdoc/DateTime.html)`;
}
case "date": {
return `[DateTime](https://ruby-doc.org/stdlib-2.6.1/libdoc/date/rdoc/DateTime.html)`;
return `[Date](https://ruby-doc.org/stdlib-2.6.1/libdoc/date/rdoc/Date.html)`;

@2ynn 2ynn Nov 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔊 Drive-by fix, unrelated to the constant shadowing: date fields linked to DateTime and date-time fields to Date. Swapped here; covered by its own docs changeset, and the review SDK diff for it is limited to four docs pages.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 6 reviewed files. 1 file intentionally excluded from review.

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Fixes Ruby generator shadowing by qualifying core constants with :: and renaming colliding sub-SDKs; snapshot tests pin output and renames only affect specs that previously failed to load, so no supported callers break.

View guided diff | Turn on auto-fix | Re-trigger cubic

@2ynn
2ynn marked this pull request as ready for review November 10, 2026 00:10
@2ynn
2ynn requested a review from a team as a code owner November 10, 2026 00:10
…wing them

Generated Ruby code lives inside the SDK module, and every tag becomes a
sub-SDK class directly under it. Unqualified references in the templates
therefore resolved to a same-named sub-SDK instead of the intended
constant:

- `File.extname`, `Time.now`, `Date.iso8601`, `is_a? Hash` and similar
  failed `srb tc` when a spec had a `File`, `Time`, `Date` or `Hash` tag;
- `include Kernel` made the gem fail to load with a `Kernel` tag;
- a `Utils` or `SDKHooks` tag replaced the SDK's own module
  (`Utils is not a class`), and an `SDKConfiguration` tag overwrote
  `sdkconfiguration.rb` and the `@sdk_configuration` instance variable.

Prefix Ruby core and stdlib constants with `::` in the SDK templates and
in the TypeScript helpers that emit Ruby code. Usage snippets are
top-level Ruby, so their date, date-time, file and environment variable
example values stay unqualified; model defaults and generated tests keep
the prefix.

Sub-SDKs whose class or file name matches an SDK internal (`Utils`,
`SDKHooks`, `SDKConfiguration`) get an `SDK` suffix, repeated until the
name is free, and a sub-SDK accessor named `sdk_configuration` becomes
`sdk_configuration_`. Schemas keep their names: models live under
`Models::` and do not shadow these constants.

Add snapshot tests for tags that collide with these constants, for
reserved names in nested groups and next to a main SDK class that takes
the first suffix, and for example values in usage snippets versus
generated tests. Compiling them runs `srb tc` on the generated SDKs.

Drive-by: Ruby docs linked `date` fields to `DateTime` and `date-time`
fields to `Date`; swap the links.

Regenerate the Ruby review SDK.
@2ynn
2ynn force-pushed the fix/ruby/qualify-core-constants branch from 18babcb to 7ac2c05 Compare November 10, 2026 00:14
@2ynn 2ynn added the review:bypass Merge without human review approval. Required status checks still apply. label Nov 10, 2026

@speakeasybot speakeasybot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: review:bypass label applied by @2ynn. Required status checks still gate this merge.

@2ynn
2ynn added this pull request to the merge queue Nov 10, 2026
Merged via the queue into main with commit 04d09be Nov 10, 2026
249 checks passed
@2ynn
2ynn deleted the fix/ruby/qualify-core-constants branch November 10, 2026 13:21
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

review:bypass Merge without human review approval. Required status checks still apply. ruby Trigger (19) snapshot tests for ruby

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants