fix(ruby): fix RuboCop Lint/Void and Naming/VariableNumber offenses in generated SDKs#14115
fix(ruby): fix RuboCop Lint/Void and Naming/VariableNumber offenses in generated SDKs#14115fern-support wants to merge 6 commits intomainfrom
Conversation
…n generated SDKs Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review.
Tip: disable this comment in your organization's Code Review settings.
🌱 Seed Test SelectorSelect languages to run seed tests for:
How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR. |
… style names Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
| function normalizeVariableNumber(name: string): string { | ||
| return name.replace(/([a-zA-Z])_(\d)/g, "$1$2"); | ||
| } |
There was a problem hiding this comment.
The normalizeVariableNumber regex only removes the underscore before the first digit in a sequence, not all underscores before digits. For example:
test_1_2_3becomestest1_2_3(only first_1normalized,_2_3remain)account_id_123_testbecomesaccount_id123_test(onlyd_1normalized)
This creates inconsistent normalization and may still trigger RuboCop violations. The regex needs to handle multiple digit groups:
return name.replace(/([a-zA-Z])_(?=\d)/g, "$1");This uses a lookahead (?=\d) instead of capturing the digit, allowing the regex engine to continue matching subsequent letter-underscore-digit patterns in the same string.
| function normalizeVariableNumber(name: string): string { | |
| return name.replace(/([a-zA-Z])_(\d)/g, "$1$2"); | |
| } | |
| function normalizeVariableNumber(name: string): string { | |
| return name.replace(/([a-zA-Z\d])_(?=\d)/g, "$1"); | |
| } | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
There was a problem hiding this comment.
Good catch! Updated the regex to ([a-zA-Z\d])_(?=\d) in all three files — this handles consecutive digit groups like test_1_2_3 → test123 correctly. Pushed in cc5483a.
…e digit groups Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
| @@ -8,7 +24,6 @@ | |||
| type: chore | |||
| createdAt: "2026-03-27" | |||
| irVersion: 61 | |||
There was a problem hiding this comment.
Version chronology is incorrect. Version 1.1.7 shows createdAt: "2026-03-26" while version 1.1.6 shows createdAt: "2026-03-27". Since 1.1.7 is a higher version number than 1.1.6, it should have been created after, not before.
This will cause issues:
- Semantic versioning violation (newer version created earlier)
- Potential confusion in release ordering and changelogs
- Breaking assumptions about version progression
Fix: Change 1.1.7's createdAt to "2026-03-27" or later, or reconsider the version numbering if 1.1.6 was meant to be the newer release.
| - version: 1.1.7 | |
| changelogEntry: | |
| - summary: | | |
| Fix RuboCop `Lint/Void` offenses in generated `boolean.rb` and `utils.rb` internal | |
| type files. Bare `value` expressions in `case/when` branches and fallthrough paths | |
| now use explicit `return value` to avoid void-context warnings. | |
| type: fix | |
| - summary: | | |
| Fix RuboCop `Naming/VariableNumber` offenses for model field names containing digits. | |
| Field names like `account_last_4` are now normalized to `account_last4` to match | |
| the `normalcase` style enforced by the generated `.rubocop.yml`. The wire value | |
| is preserved via the `api_name` parameter for correct serialization. | |
| type: fix | |
| createdAt: "2026-03-27" | |
| irVersion: 61 | |
| - version: 1.1.6 | |
| changelogEntry: | |
| - summary: | | |
| type: chore | |
| createdAt: "2026-03-27" | |
| irVersion: 61 | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
Description
Fixes RuboCop violations in generated Ruby SDKs that cause CI lint failures (e.g., fern-demo/schematic-test-ruby).
Changes Made
1. Fix
Lint/Voidoffenses in template filesboolean.Template.rb: Addedreturnbefore barevaluein thewhen TrueClass, FalseClassbranch (line 20). Other branches already used explicitreturn, making this one fall into void context.utils.Template.rb: Addedreturnbefore barevalueon theelsebranches of the pattern-matchingcase(lines 84, 87). Withoutreturn, these are dead expressions since the method continues to theraiseand finalvaluebelow.2. Fix
Naming/VariableNumberoffenses in field name generation.rubocop.ymlenforcesNaming/VariableNumber: normalcase(since v1.0.0-rc86), which disallows underscores before digits (e.g.,account_last_4should beaccount_last4).snakeCase.safeNamecan produce names likeaccount_last_4when the casing generator doesn't use smart casing, or the input triggers word-boundary splitting before digits.normalizeVariableNumber()using regex/([a-zA-Z\d])_(?=\d)/gto strip underscores before digit sequences, applied in:generateFields.ts— model field symbolsDynamicSnippetsGeneratorContext.ts— property names in generated snippetsDynamicToLiteralMapper.ts— object property names in snippet literal conversionapi_name) are unaffected, preserving correct serialization.(?=\d)to correctly handle consecutive digit groups (e.g.,test_1_2_3→test123) and preserves leading underscores and digit-preceded underscores (e.g.,_3_dstays_3_d).3. Version bump
v1.1.4entry togenerators/ruby-v2/sdk/versions.ymlwith changelog entries for both fixes.Human Review Checklist
/([a-zA-Z\d])_(?=\d)/gbreadth: This strips underscores before digits when preceded by a letter or digit. This matches RuboCop'snormalcaseexpectation, but verify edge cases (e.g.,v_2→v2,x_1_2→x12).normalizeVariableNumberis duplicated 3 times across packages. Consider whether it should be extracted into a shared utility (e.g.,@fern-api/ruby-base).getMethodNameinDynamicSnippetsGeneratorContext.tswas intentionally NOT updated — onlygetPropertyNamewas. Confirm method names don't need the same normalization.normalizeVariableNumber. Consider adding tests for edge cases (_3_d,account_last_4,test_1_2_3, names with no digits).Testing
pnpm run check(biome lint) passesreserved-keywordsfixture failure due to overly aggressive regex (fixed in subsequent commit)Link to Devin session: https://app.devin.ai/sessions/d1bd30a5218f438db2821cdb6222fcd0
Requested by: @cdonel707