From e1ffe96656d6485217ee337133891c0e733f755d Mon Sep 17 00:00:00 2001 From: Y-C Date: Thu, 10 Sep 2026 02:10:44 +0800 Subject: [PATCH] [v3-3-test] Fix airflow info --file-io uploading an empty report (#72707) * Fix airflow info --file-io uploading an empty report The report was read back from rich's recording buffer, but the render ran inside a capture, and rich skips the record buffer while a capture is active. The command therefore uploaded a zero-byte file and reported success, for a command whose only purpose is producing that report. The console is built without a color system because the result is written to a file, where escape codes would be noise rather than formatting. * Update airflow-core/tests/unit/cli/commands/test_info_command.py Co-authored-by: rjgoyln <151457491+rjgoyln@users.noreply.github.com> * Pin the uploaded report width so it does not depend on the terminal The console only falls back to a fixed width when stdout is not a tty, so a report generated from a real terminal was laid out at that terminal's width and long path values were cut off in the uploaded file. --------- (cherry picked from commit 90787d5a2da4f2efa52c9274d4fff06e2087be1f) Co-authored-by: Y-C Co-authored-by: Eason09053360 <185830721+Eason09053360@users.noreply.github.com> Co-authored-by: Henry Chen Co-authored-by: rjgoyln <151457491+rjgoyln@users.noreply.github.com> --- airflow-core/src/airflow/cli/commands/info_command.py | 7 ++++--- .../tests/unit/cli/commands/test_info_command.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/airflow-core/src/airflow/cli/commands/info_command.py b/airflow-core/src/airflow/cli/commands/info_command.py index 06c32e5c0af73..79c4ae8b7f3a9 100644 --- a/airflow-core/src/airflow/cli/commands/info_command.py +++ b/airflow-core/src/airflow/cli/commands/info_command.py @@ -335,10 +335,11 @@ def show(self, output: str, console: AirflowConsole | None = None) -> None: def render_text(self, output: str) -> str: """Export the info to string.""" - console = AirflowConsole(record=True) - with console.capture(): + # The text is uploaded as a file: no escape codes, fixed width regardless of the terminal. + console = AirflowConsole(color_system=None, width=200) + with console.capture() as capture: self.show(output=output, console=console) - return console.export_text() + return capture.get() class FileIoException(Exception): diff --git a/airflow-core/tests/unit/cli/commands/test_info_command.py b/airflow-core/tests/unit/cli/commands/test_info_command.py index 20a05dc328f4e..2dc3d60e4e67e 100644 --- a/airflow-core/tests/unit/cli/commands/test_info_command.py +++ b/airflow-core/tests/unit/cli/commands/test_info_command.py @@ -162,6 +162,15 @@ def test_show_info_anonymize(self, stdout_capture): assert airflow_version in output assert "postgresql+psycopg2://p...s:PASSWORD@postgres/airflow" in output + @mock.patch.dict(os.environ, {"FORCE_COLOR": "1", "TERM": "xterm-256color"}) + def test_render_text_stays_plain_on_a_color_terminal(self): + instance = info_command.AirflowInfo(info_command.NullAnonymizer()) + + rendered = instance.render_text("table") + + assert airflow_version in rendered + assert "\x1b[" not in rendered + @pytest.fixture def setup_parser(): @@ -188,3 +197,4 @@ def test_show_info_anonymize_fileio(self, setup_parser, cleanup_providers_manage with stdout_capture as stdout: info_command.show_info(setup_parser.parse_args(["info", "--file-io", "--anonymize"])) assert "https://file.io/TEST" in stdout.getvalue() + assert airflow_version in post.call_args.kwargs["content"]