aaiss0927 opened a new pull request, #75831:
URL: https://github.com/apache/airflow/pull/75831
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
Add a **`--json`** flag to `breeze ui check-translation-completeness` that
prints the completeness report as a single machine-readable JSON document on
stdout, following the pattern `breeze ci verify --json` established in #73241.
closes: #75772
## What changed
- **`build_completeness_report()`** — the per-file aggregation
(required/translated/missing/TODO/unused counts, coverage, and the sorted
missing/unused key lists) used to live inside the rich-table rendering loop; it
is now a pure function, and the table renderer and the JSON serializer consume
the same dict, so the two outputs cannot drift apart.
- **`--json`** — boolean flag, same shape as `breeze ci verify --json`:
console narration is suppressed (sent to stderr with `--verbose`), stdout
carries nothing but the JSON document (pipe-safe for `jq`), and
`ctx.meta[SKIP_LOCAL_REPRODUCTION]` is set so CI's reproduction epilogue cannot
pollute the contract. If the computation aborts (e.g. a locale without a
`PLURAL_SUFFIXES` entry, or an unreadable locale file), the suppressed
narration is replayed to stderr so the error is not silent — whether the abort
was a `sys.exit()` or an unexpected exception.
- **`apply_translation_modifications()`** — the `--add-missing` /
`--remove-unused` block is extracted unchanged so both output modes share the
exact same modification semantics (`--json` reports the post-modification
state).
- Tests (15 new, covering the report builder, the CLI JSON mode, the
`complete`-verdict semantics, and both error-replay paths), docs
(`10_ui_tasks.rst`, i18n `README.md`, the translation agent skill's validation
step), option registration in `ui_commands_config.py`, and regenerated command
image + hash.
## Output shape
```console
$ breeze ui check-translation-completeness --language ko --json | jq
'.languages.ko.totals'
{
"required": 1296,
"required_base_en": 1296,
"required_plural": 0,
"translated": 1253,
"missing": 43,
"todos": 0,
"unused": 13,
"coverage": 96.7
}
```
Per-file entries additionally carry `missing_keys` / `unused_keys` (sorted),
and the top level carries `complete`, which mirrors the table verdict exactly
(file-set differences, missing keys, or TODOs among the reported locales;
unused keys alone do not fail it — same as today).
## Backwards compatibility
- **Default output is byte-identical.** Verified by capturing the full
output of the parent commit and this commit with `PYTHONHASHSEED=0` (the
printed key lists come from `list(set)`, so ordering is only comparable with a
fixed hash seed — a pre-existing property) and diffing: zero differences for
the all-locales run and for `--language ko`.
- **Exit-code semantics unchanged** per the original design in #55327:
missing translations never fail the command; `--json` exits 2 for an
invalid/`en` `--language` (before printing anything to stdout), exactly like
the table mode.
- `--language`, `--add-missing`, `--remove-unused` all compose with `--json`.
---
### Test
- `uv run pytest dev/breeze/tests/test_ui_commands.py` — 48 passed (33
existing + 15 new).
- Byte-identical default output proof as described above (all locales +
`--language ko`).
- Cross-checked the JSON against the rendered tables on real data: all 10
`ko` per-file rows × 8 numeric columns plus the `All files` row match, and all
20 languages' total coverage values equal the "Total Coverage per Language"
table.
- Error paths: `--json --language xx` and `--json --language en` exit 2 with
empty stdout; a locale without `PLURAL_SUFFIXES` and a malformed locale file
both keep stdout clean and replay the narration to stderr; `--json` output
re-parses with `python -m json.tool` and is byte-stable across runs (sorted key
lists).
---
##### Was generative AI tooling used to co-author this PR?
- [x] Yes (please specify the tool below)
Claude Fable 5
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
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]