Guard against hardcoded ConfigEntry strings#4304
Merged
Merged
Conversation
A ConfigEntry's label/description must be authored in strings.json (resolved via config_entries.<key>) so they reach Lokalise; passing them as literals in code leaves them English-only. Adds a pre-commit/CI guard and moves the existing literal labels into strings.json. - scripts/check_config_entries.py: hook flagging literal label/description/ action_label on a ConfigEntry (skips _*/test templates; f-strings out of scope) - bbc_sounds / amplipi / squeezelite: move labels & descriptions to strings.json - scrobbler shared entries -> common strings.json (used by 3 scrobble providers) - squeezelite preset uses translation_key + translation_params (dynamic key) - regenerated en.json
Contributor
There was a problem hiding this comment.
Pull request overview
This PR prevents contributors from hardcoding user-facing ConfigEntry text (which would bypass Lokalise) by adding a pre-commit/CI guard, and migrates existing literal ConfigEntry labels/descriptions into the appropriate strings.json files (including common), with regenerated en.json.
Changes:
- Added
scripts/check_config_entries.pyand a pre-commit hook to fail on string-literalConfigEntrylabel/description/action_label. - Migrated hardcoded
ConfigEntrystrings in several providers/helpers intostrings.json(and updated code to rely on translations). - Updated squeezelite preset entries to use
translation_key+translation_params, and regeneratedmusic_assistant/translations/en.json.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/check_config_entries.py | New AST-based guard to detect hardcoded ConfigEntry user-facing strings. |
| .pre-commit-config.yaml | Registers the new check_config_entries hook for pre-commit/CI linting. |
| music_assistant/strings.json | Adds new common/shared config_entries translation source strings. |
| music_assistant/translations/en.json | Regenerated English translation bundle reflecting new/updated source strings. |
| music_assistant/helpers/scrobbler.py | Removes literal ConfigEntry text so shared scrobble entries resolve via translations. |
| music_assistant/providers/squeezelite/player.py | Switches dynamic preset label/description to translation_key + params. |
| music_assistant/providers/squeezelite/strings.json | Adds translatable template strings for presets. |
| music_assistant/providers/bbc_sounds/init.py | Removes hardcoded ConfigEntry labels to rely on translations. |
| music_assistant/providers/bbc_sounds/strings.json | Adds missing config_entries strings for the migrated BBC Sounds entries. |
| music_assistant/providers/amplipi/init.py | Removes hardcoded ConfigEntry label/description to rely on translations. |
| music_assistant/providers/amplipi/strings.json | New provider strings.json containing the migrated AmpliPi config entry strings. |
Extends the guard to f-strings and moves the dynamic labels/descriptions into
strings.json templates ({0}/{1}) + translation_params, so transient auth/status
text localizes too instead of being interpolated in code.
- check_config_entries now also flags f-string label/description/action_label
- airplay pairing flow (6), ard_audiothek sign-in label, lastfm_scrobble save
reminder + authorize action, yandex_music base_url description, and the
yandex_smarthome direct-HTTPS warning -> translation_params + strings.json
- regenerated en.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this implement/fix?
A
ConfigEntry'slabel/descriptionare localized at serialization fromstrings.json(via theconfig_entries.<key>key), so passing them as literals in code — like in #4180 — means they never reach Lokalise and stay English-only. There was nothing stopping a contributor from doing that.This adds a pre-commit/CI guard that flags hardcoded
ConfigEntrytext, and migrates every existing offender intostrings.json.scripts/check_config_entries.py: a pre-commit hook (runs in CI via the lint job) that fails when aConfigEntrypasses a hardcodedlabel/description/action_label— both plain string literals and f-strings. Skips_*/testtemplate providers.strings.json: bbc_sounds, amplipi (newstrings.json), squeezelite, and the shared scrobbler entries →common(used by 3 scrobble providers).strings.jsontemplates ({0}/{1}) +translation_params: the airplay pairing flow, ard_audiothek sign-in label, lastfm_scrobble save reminder + authorize action, yandex_music base URL description, and the yandex_smarthome direct-HTTPS warning.translation_keyso they share one template.en.json.Types of changes
bugfixnew-featureenhancementnew-providerbreaking-changerefactordocumentationmaintenancecidependenciesChecklist
pre-commit run --all-filespasses.pytestpasses, and tests have been added/updated undertests/where applicable.