Skip to content

refactor(strcase,BREAKING!): adopt STYLE2024 case conversion rules#405

Open
Kybxd wants to merge 2 commits into
masterfrom
strcase-style2024
Open

refactor(strcase,BREAKING!): adopt STYLE2024 case conversion rules#405
Kybxd wants to merge 2 commits into
masterfrom
strcase-style2024

Conversation

@Kybxd
Copy link
Copy Markdown
Collaborator

@Kybxd Kybxd commented May 14, 2026

Motivation

The internal/strcase package was forked long ago from iancoleman/strcase and produced names that diverge from the Protobuf STYLE2024 and Edition 2024: features.enforce_naming_style guide:

  • It inserted underscores at letter↔digit boundaries (Tier1tier_1), which STYLE2024 explicitly forbids.
  • It treated all-caps acronyms as a single token (JSONData → various forms depending on the acronym table) instead of as ordinary words.
  • It carried a long tail of unused helpers (ToLowerCamel, ToKebab, ToDelimited, …) inherited from upstream.

Meanwhile downstream code (protogen, confgen) kept patching around these rough edges with ad-hoc prefix logic and ToCamel/ToPascal swaps. This MR reworks the package to STYLE2024 in one place, removes the workarounds at call sites, and regenerates the affected test fixtures.

What changes

internal/strcase — core rewrite

  • New chunk-based PascalCase / snake_case algorithm in camel.go / snake.go. STYLE2024 invariants:

    • Underscores only appear before a letter (Tier1tier1, never tier_1).
    • Acronyms are ordinary words (GetDnsRequest / dns_request, userIDuser_id).
  • Public API trimmed to the four conversions actually needed:

    Function Result
    ToPascal(s) AnyKindOfString
    ToCamel(s) anyKindOfString
    ToSnake(s) any_kind_of_string
    ToScreamingSnake(s) ANY_KIND_OF_STRING

    ToCamel now produces anyKindOfString (i.e. previous ToLowerCamel semantics). ToLowerCamel, ToKebab, ToScreamingKebab, ToDelimited, ToScreamingDelimited, ToSnakeWithIgnore are removed.

  • New helper EnumValue(enumName, value) (enum_value.go) producing STYLE2024-compliant enum value names: prefixes with UPPER_SNAKE_CASE(enumName), normalizes the value, and inserts a leading V when the value would otherwise start with a digit. Examples:

    EnumValue("DeviceTier", "Tier1")           -> "DEVICE_TIER_TIER1"
    EnumValue("DeviceTier", "1")               -> "DEVICE_TIER_V1"
    EnumValue("ItemType",   "EQUIP")           -> "ITEM_TYPE_EQUIP"
    EnumValue("ItemType",   "ITEM_TYPE_EQUIP") -> "ITEM_TYPE_EQUIP"
    
  • doc.go / README.md rewritten to describe the STYLE2024 contract and the (now smaller) public surface.

  • Tests rewritten against the new rules; new enum_value_test.go covers EnumValue plus an acronym-context regression case.

Call sites updated to use the new API

  • internal/confgen (util.go, table_parser.go, document_parser.go): default field/column/node name derivation switches from ToCamel to ToPascal so the proto field hero_id continues to map to the sheet/document name HeroId under the new rules.
  • internal/protogen/exporter.go: union enum value names go through EnumValue("Type", field.Name); when an explicit message type is not provided, the type name is derived via ToPascal(field.Name).
  • internal/protogen/sheet_mode.go: enum value naming for sheet-mode enums goes through EnumValue(ws.Name, value.Name); the ad-hoc prefix-prepend logic is removed.
  • internal/tools/cmd/ecode/main.go: directly uses ToCamel for the Go field name (replaces the previous PascalCase + manual lower-first hack).

Options — deprecation

options.ProtoOutputOption.EnumValueWithPrefix is deprecated and now a no-op. STYLE2024 mandates the enum-name prefix unconditionally, so the option no longer makes sense. The field is kept for config-schema backward compatibility; updated godoc reflects this. The functional test setup (test/functest/util.go) drops its usage.

Breaking changes

This MR will change generated .proto content for any sheet whose names contain digit-letter junctions, all-caps acronyms, or rely on the ad-hoc enum prefix toggle. Concretely:

  • Sheet/file names with digit junctions normalize differently:
    • csv__bom__utf_8_bom.protocsv__bom__utf8_bom.proto
    • excel__metasheet__merger_1.protoexcel__metasheet__merger1.proto
    • excel__metasheet__scatter_1.protoexcel__metasheet__scatter1.proto
  • Field / enum value spellings inside generated protos shift to the STYLE2024 form (see updated golden files under test/functest/proto/default/*).
  • EnumValueWithPrefix = false no longer suppresses the prefix; downstream users relying on the unprefixed form must regenerate.
  • Removed strcase symbols (ToLowerCamel, ToKebab, ToDelimited, …): no internal user remains, but external embedders of internal/strcase (if any) need to migrate to the four supported conversions.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 93.45794% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.09%. Comparing base (ffb15fb) to head (1307232).

Files with missing lines Patch % Lines
internal/strcase/camel.go 88.46% 5 Missing and 4 partials ⚠️
internal/protogen/sheet_mode.go 50.00% 3 Missing and 1 partial ⚠️
internal/protogen/exporter.go 76.92% 1 Missing and 2 partials ⚠️
internal/protogen/protogen.go 50.00% 1 Missing and 2 partials ⚠️
internal/strcase/enum_value.go 90.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #405      +/-   ##
==========================================
+ Coverage   74.83%   75.09%   +0.25%     
==========================================
  Files          88       90       +2     
  Lines        9372     9536     +164     
==========================================
+ Hits         7014     7161     +147     
- Misses       1785     1795      +10     
- Partials      573      580       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wenchy
Copy link
Copy Markdown
Member

wenchy commented May 27, 2026

Due to Edition 2024: features.enforce_naming_style

Values available:

STYLE2024: Enforces strict adherence to the style guide for naming.
STYLE_LEGACY: Applies the pre-Edition 2024 level of style guide enforcement.

So if tableau support the new naming style, it shoud be enabled by config options.

@Kybxd Kybxd force-pushed the strcase-style2024 branch from 8e578f1 to 53cbd55 Compare May 27, 2026 06:44
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

The latest Buf updates on your PR. Results from workflow Buf CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMay 27, 2026, 8:46 AM

@Kybxd Kybxd force-pushed the strcase-style2024 branch from 53cbd55 to 1512f30 Compare May 27, 2026 06:48
Rewrite the strcase package so that all case conversions follow the
Protobuf STYLE2024 guide (https://protobuf.dev/programming-guides/style/):

- Underscores are only allowed in front of a letter, so digit boundaries
  no longer get an underscore (e.g. "Tier1" -> "tier1", not "tier_1").
- Acronyms are treated as ordinary words
  (e.g. "JSONData" -> "json_data", "userID" -> "user_id").

Public API changes:
- ToPascal / ToCamel / ToSnake / ToScreamingSnake are reimplemented on
  a new chunk-based algorithm in camel.go / snake.go. ToCamel now
  produces "anyKindOfString" (was the previous ToLowerCamel semantics);
  the unused ToLowerCamel / ToKebab / ToDelimited variants are dropped.
- Add EnumValue(enumName, value) helper (internal/strcase/enum_value.go)
  that builds STYLE2024-compliant enum value names: prefixes the value
  with UPPER_SNAKE_CASE(enumName) and inserts a leading "V" when the
  value would otherwise start with a digit
  (e.g. EnumValue("DeviceTier", "1") -> "DEVICE_TIER_V1").
- Update doc.go / README.md and rewrite snake/camel tests against the
  new rules; add enum_value_test.go.

Call sites:
- internal/confgen: switch ToCamel -> ToPascal for default field name
  and union type-column / type-node lookup.
- internal/protogen/exporter: build union enum value names via
  EnumValue("Type", field.Name); use ToPascal to derive the union
  message type when no explicit type is given.
- internal/protogen/sheet_mode: enum value naming goes through
  EnumValue(ws.Name, value.Name); the ad-hoc prefix logic is removed.
- internal/tools/cmd/ecode: use ToCamel directly for goName.

Options:
- Deprecate ProtoOutputOption.EnumValueWithPrefix. STYLE2024 mandates
  the prefix unconditionally, so the option is now a no-op and only
  kept for config-schema backward compatibility. Remove its usage from
  the functional test setup.

Test fixtures regenerated to reflect the new naming:
- Rename csv__bom__utf_8_bom.proto -> csv__bom__utf8_bom.proto and
  excel__metasheet__merger_1/scatter_1.proto -> *_merger1/scatter1.proto
  (digits no longer separated by underscore).
- Update generated .proto files under test/functest/proto/default/* for
  fields/enum values whose case form changed under STYLE2024.
@Kybxd Kybxd force-pushed the strcase-style2024 branch from 1512f30 to 9e21b81 Compare May 27, 2026 07:46
Introduce a legacy mode in the strcase package to allow existing projects
to opt back into the pre-STYLE2024 naming algorithm. This mode is gated
by the `useLegacyNamingStyle` option and is force-disabled when the
requested proto edition is >= 2024.

Key changes:
- Change proto edition type from string to int for proper numeric
  comparison against the STYLE2024 edition threshold.
- Add legacy implementations for camel, snake, and enum value
  conversions, porting the old byte-walking algorithms.
- Make `EnumValueWithPrefix` conditional under legacy mode, matching
  the historical behavior where prefixing was opt-in.
- Update all strcase tests to run cases against both STYLE2024 and
  legacy engines side-by-side.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants