fix: keep zero plural form in Apple XLIFF export#3789
Conversation
Apple XLIFF export dropped any plural form that CLDR doesn't define for the target locale, so an authored zero case (e.g. English zero/one/other) never made it into the exported stringsdict/xcstrings. AppleXliffExporter now keeps every form the user actually wrote in addition to the locale's CLDR forms, matching what the xcstrings exporter already does. Fixes tolgee#3074
📝 WalkthroughWalkthroughModifies AppleXliffExporter's plural-form generation logic to include all authored plural forms (e.g., "zero") in addition to CLDR-required forms for the target locale, replacing prior delegation to a shared populateForms function. Adds a unit test verifying zero-form retention in exported XLIFF output. ChangesApple XLIFF plural export fix
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
backend/data/src/main/kotlin/io/tolgee/formats/apple/out/AppleXliffExporter.kt (1)
231-242: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared plural-form helper here
AppleXliffExporter.kt:231-242— this duplicates the existingpopulateFormslogic inpluralFormsUtil.kt; call the helper instead of inlining the union/fallback code so Apple plural handling stays in one place.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/data/src/main/kotlin/io/tolgee/formats/apple/out/AppleXliffExporter.kt` around lines 231 - 242, The plural-form handling in AppleXliffExporter.populateForms is duplicating the shared logic from pluralFormsUtil.kt. Update populateForms to delegate to the existing helper instead of inlining the union of getPluralFormsForLocale(languageTag) with forms.keys and the "other" fallback, so Apple plural behavior stays centralized and easier to maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@backend/data/src/main/kotlin/io/tolgee/formats/apple/out/AppleXliffExporter.kt`:
- Around line 231-242: The plural-form handling in
AppleXliffExporter.populateForms is duplicating the shared logic from
pluralFormsUtil.kt. Update populateForms to delegate to the existing helper
instead of inlining the union of getPluralFormsForLocale(languageTag) with
forms.keys and the "other" fallback, so Apple plural behavior stays centralized
and easier to maintain.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 200c9117-a38a-4c96-91a1-09abd7e39465
📒 Files selected for processing (2)
backend/data/src/main/kotlin/io/tolgee/formats/apple/out/AppleXliffExporter.ktbackend/data/src/test/kotlin/io/tolgee/unit/formats/apple/out/AppleXliffFileExporterTest.kt
|
Deliberately not delegating to The shared helper stays correct as-is for the Android XML resources exporter, since Android plural resources really are constrained to CLDR quantities (noted in the PR description). Keeping this one local avoids changing behavior for that other caller. Happy to rename it to something more specific like |
|
Checked the shared helper before switching to it: |
Problem
Apple XLIFF export drops any plural form that CLDR doesn't define for the target locale. English only has
oneandotherin CLDR, so a key with azeroform (e.g. "No participants" / "1 Participant" / "%d Participants") gets exported withoutplural.zeroat all. The string is just gone from the file.AppleXliffExporter.handlePluralruns the converted forms throughpopulateForms, which builds its output set fromgetPluralFormsForLocale(languageTag)only. Any form outside that set gets dropped instead of exported. This is locale-specific behavior, not something Apple's formats actually require:AppleXcstringsExporter(the.xcstringsexporter) skips this filtering entirely and just writes out whatever formsformsResultcontains. That's why the reporter's.xcstringsworkaround kept the zero case while XLIFF/stringsdict export lost it.Change
AppleXliffExporter'spopulateFormsnow keeps every form that's actually present in the message, on top of the locale's CLDR forms (somanyfor Czech still gets filled in fromotherwhen the message doesn't specify it, same as before). This lines XLIFF export up with what the xcstrings exporter already does, so azeroform the user wrote makes it into the export regardless of whether the target locale's CLDR data includes it.I left
io.tolgee.formats.populateForms(used by the Android XML resources exporter) alone. Android's plural resources really are constrained to CLDR quantities, so filtering there is correct.Tests
Added a test to
AppleXliffFileExporterTestwith an English key carryingzero/one/otherforms and checked all three trans-units, includingplural.zero, show up in the exported XLIFF.No JDK on this machine, so I couldn't run
./gradlew :data:testlocally. I traced the fix by hand againstPluralsFormUtilTest(which already assertsgetPluralFormsForLocale("en")returns onlyone, other) and against howAppleXcstringsExporterbuilds its output. Would appreciate CI confirming the new test passes.Fixes #3074
Summary by CodeRabbit
Bug Fixes
Tests