Skip to content

macos-localizations: CFBundleLocalizations and lproj staging - #277

Merged
turinglambdaai merged 1 commit into
mainfrom
feat/macos-localizations
Oct 16, 2026
Merged

turinglambdaai merged 1 commit into
mainfrom
feat/macos-localizations

Conversation

@turinglambdaai

Copy link
Copy Markdown
Owner

Closes #264.

What

Apps whose in-app strings follow the user language shipped a mixed-language UI on non-English systems: the generated Info.plist declared CFBundleDevelopmentRegion=en with no localization declaration, so AppKit rendered every system-provided string (About / Hide / Quit / Close / Enter Full Screen, standard alerts, SwiftUI NavigationSplitView sidebar tooltips) in the development region's language while the in-app strings followed the user. Apps worked around it with post-packaging plutil injection plus manual re-signing (pdfgist scripts/localize-app.sh).

A (macos-localizations "zh-Hans" "en") declaration in rivet.rktd:

  • write-macos-info! emits CFBundleLocalizations when the key is present
  • packaging stages marker Contents/Resources/<lang>.lproj/InfoPlist.strings files
  • injection happens before sign-macos! — no re-sign needed
  • projects without the declaration build a byte-identical bundle to before

Language tags are validated as BCP 47 at project load (invalid tags name the expected shape); the plist writer stays permissive so validation lives at the declaration boundary where the human writes it.

Docs

docs/configuration.md gains a "macOS bundle localizations" section next to resources and i18n.

Tests

rivet/tests/resources.rkt: no key → no CFBundleLocalizations in the plist (byte-identical behavior); declared key → exact array in the plist; malformed tag fails at load-project with the BCP 47 message. macos-installer.rkt (real DMG packaging) and project.rkt suites stay green: 117 tests across the three files.

…aged apps

Apps whose in-app strings follow the user language shipped a
mixed-language UI on non-English systems: every system-provided string
(About/Hide/Quit, standard alerts, SwiftUI navigation tooltips) rendered
in the development region's language because the generated Info.plist
declared CFBundleDevelopmentRegion=en and no localizations — so
CFBundleCopyBundleLocalizations could never resolve zh-Hans or any other
language. Apps worked around it with post-packaging plutil injection
plus manual re-signing (pdfgist scripts/localize-app.sh).

A (macos-localizations "zh-Hans" "en") declaration in rivet.rktd
(BCP 47 identifiers, validated at load, deduplicated) now flows into
write-macos-info! as CFBundleLocalizations and stages marker
Contents/Resources/<lang>.lproj/InfoPlist.strings files before
sign-macos! runs — injection happens pre-signing, no re-sign needed.
Projects without the declaration build a byte-identical bundle to
before. docs/configuration.md documents the key and what it does.
@turinglambdaai
turinglambdaai merged commit 5d803e0 into main Oct 16, 2026
23 checks passed
@turinglambdaai
turinglambdaai deleted the feat/macos-localizations branch October 16, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macos: packaging support for bundle localizations (CFBundleLocalizations + lproj staging)

1 participant