Issue #3620839: Labels that only shipped configuration carries are never checked, and 24 of them are untranslated
Implements #3620839.
Reading shipped configuration
The missing direction was fed by potx and potx was never given config/install
or config/optional, so a string that only a shipped configuration entity
carries was never required to have a translation. Twenty-two of them did not
have one, from the three status labels a requester of the webform example
reads, to the flow labels of the payment example, to the name of the date
format orchestra_ui installs.
Reading them needs potx, because which of a config entity's values are
translatable is a question only the config schema answers and potx is the only
thing here that reads schemas. Two changes: the shipped config files go to it
alongside the code, and potx_finish_processing() is called so it parses them
once every schema has been seen. It also has to find the Drupal root to resolve
a dependency's schema, and it does that by splitting a path on /modules/, so
it is handed its OWN path rather than the module's — a checkout somewhere else
would otherwise leave it with nothing to read the schemas from. A run that
discovers no modules now says so and stops instead of reporting a clean tree it
never looked at.
Two kinds of string, two scopes
Getting this wrong would have been worse than not asking. localize.drupal.org offers a code string only in the catalog of the project that ships it, so those stay scoped to the project, strictly. locale keeps one string table, so a shipped config label is translated from whichever installed catalog holds the source string, and demanding a per-project copy of a word the base module already translates would manufacture duplicates — which is #3620840's whole subject. Those are scoped to the project's own catalog plus its dependencies', which is measured behaviour rather than a guess: on a French site the examples read "Start" from the base module.
What is not asked for, and why
Fifteen entries go on the allow-list rather than being translated, because they
are not this project's words: the exposed-form and pager wording views
serializes into a shipped view is core's, and core translates it. The one these
views actually chose, the exposed form's Filter, is translated. So is an
outcome machine value that ECA's own schema types as a translatable label.
Nine values are counted in the summary and not asked for at all, because no
catalog can carry them. orchestra_is_importable() mirrors
locale_string_is_safe(), tag list and token-stripping included, so what the
check accepts is what locale's importer accepts: an HTML email body is refused
there and would be refused here. A value that is a whole configuration
document, which a webform's element tree is, is not a translation unit either.
The catalog reader
The second half of the issue. The reader never looked at msgstr, so an entry
with an empty translation or a fuzzy flag counted as present while locale
ignores both at runtime. It now answers both questions the two directions ask —
whether the catalog has an ENTRY, and whether the string has a TRANSLATION —
and it scans into records before folding them, so the running state is not a
closure holding six variables by reference.
Two things found on the way
A shipped view's column read Processed in English while its French read
"Traitée le": the English had lost the "on". Fixing the English rather than the
French also stops it colliding with the webform example's Processed status,
which is exactly what #3620840 is about.
And the two per-module unit tests #3620615 added are retired, as that issue anticipated: the check now asks their question for every module rather than two. The half of the Easy Email one the check cannot ask — that nobody ships a French HTML body, since the check skips such a value rather than demanding one — stays, with the reason in its docblock.
Result
34 projects, 34 catalogs, 1634 strings extracted, 100 allowed untranslated, 9 config values no catalog can carry. Clean, against 1465 strings extracted
before. Every linter green, msgfmt --check on every touched catalog, and the
unit and affected kernel classes pass.
This merge request was prepared with the assistance of an AI agent (Claude). The analysis and the wording were reviewed by me before posting, and accountability for the content is mine.