HsuehYi opened a new issue, #75063:
URL: https://github.com/apache/airflow/issues/75063

   ### What happened and how to reproduce it?
   
   `breeze ui check-translation-completeness --add-missing` / `--remove-unused` 
rewrites each locale file with its keys sorted by `natural_sort_key()` 
(`dev/breeze/src/airflow_breeze/commands/ui_commands.py`), which compares 
case-insensitively. The repo enforces a different order for the same files: 
`jsonc/sort-keys` with `natural: true` 
(`airflow-core/src/airflow/ui/rules/jsonc.js`), applied by the 
`ts-compile-lint-ui` pre-commit hook. eslint-plugin-jsonc (3.4.2 here) 
implements that rule with `natural-compare`, which is case-sensitive — 
uppercase letters sort before lowercase ones.
   
   Both write helpers sort the whole file, not just the added/removed keys, so 
any locale file that gets rewritten (it has to have missing or unused keys to 
be touched at all) can be re-ordered as a side effect. For case-dependent keys 
the resulting order violates the repo's own ESLint rule, and the pre-commit 
hook flips those keys back — pure churn for contributors.
   
   Observed while updating the zh-TW locale (#75061): the command reordered 4 
pre-existing key pairs and the `Compile / format / lint UI` hook reverted all 
of them:
   
   | keys | order written by breeze | order required by ESLint |
   | --- | --- | --- |
   | `logLevel` / `logicalDate` | `logicalDate`, `logLevel` | `logLevel`, 
`logicalDate` |
   | `selectLanguage` / `selected` | `selected`, `selectLanguage` | 
`selectLanguage`, `selected` |
   | `sortMultiColumnHint` / `sortedAscending` | `sortedAscending`, 
`sortMultiColumnHint` | `sortMultiColumnHint`, `sortedAscending` |
   | `modeTooltip` / `modes` | `modes`, `modeTooltip` | `modeTooltip`, `modes` |
   
   Minimal check of the ESLint side (from `airflow-core/src/airflow/ui`):
   
   ```console
   $ cat public/i18n/locales/en/scratch.json   # order as written by the breeze 
command
   {
     "logicalDate": "Logical Date",
     "logLevel": "Log Level"
   }
   $ pnpm exec eslint public/i18n/locales/en/scratch.json
     2:3  error  Expected object keys to be in natural ascending order. 
'logicalDate' should be after 'logLevel'  jsonc/sort-keys
   
   ✖ 1 problem (1 error, 0 warnings)
   ```
   
   `pnpm exec eslint --fix` rewrites the file with `"logLevel"` first.
   
   Tool side, with the committed `natural_sort_key`:
   
   ```pycon
   >>> from airflow_breeze.commands.ui_commands import natural_sort_key
   >>> sorted(["logLevel", "logicalDate"], key=natural_sort_key)
   ['logicalDate', 'logLevel']
   >>> sorted(["selectLanguage", "selected"], key=natural_sort_key)
   ['selected', 'selectLanguage']
   ```
   
   ### What you think should happen instead?
   
   The command should write keys in the order the repo enforces, so that using 
it never produces an order ESLint rejects. Options:
   
   1. Align `natural_sort_key()` with the comparator the rule actually uses: 
port the character mapping of `natural-compare` (case-sensitive — digits before 
letters, `A-Z` before `a-z`, same punctuation mapping) and update 
`TestNaturalSorting.test_natural_sort_matches_eslint` accordingly. The current 
docstring says the key "mimics JavaScript's `localeCompare` with `numeric: 
true`" — eslint-plugin-jsonc does not use `localeCompare`; it depends on 
`natural-compare`.
   2. Or run the UI ESLint fix step on the rewritten files (e.g. invoke the 
existing `ts-compile-lint-ui` hook, or `pnpm eslint --fix`, from the command). 
That was the plan agreed in #58487 when it was closed ("convert 
`check_translation_completeness` into a breeze command and run prek run eslint 
as part of it") — the conversion landed (#58637), but the command writes its 
own order and never invokes ESLint.
   
   For completeness, the rule also supports `caseSensitive: false`; enabling it 
would make ESLint accept the current tool order, but every existing locale file 
would then have to be re-sorted, so aligning the command is likely the cheaper 
fix.
   
   ### Anything else?
   
   - Related history: #58487 reported this churn for the previous script and 
was closed assuming the new breeze command would run ESLint. The conversion to 
a breeze command (#58637) introduced the current comparator, but ESLint is 
still not invoked — this issue tracks what remains.
   - `TestNaturalSorting.test_natural_sort_matches_eslint` currently locks in 
the wrong expectation: it asserts `Zebra` sorts last, while `natural-compare` 
sorts `Z` (mapped to 101) before `a` (mapped to 102), i.e. `Zebra` first — 
ESLint reports "Expected object keys to be in natural ascending order. 'apple' 
should be after 'Zebra'". The test needs to be updated together with the 
comparator.
   
   ---
   Drafted-by: OpenCode; reviewed by @HsuehYi before posting
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to