fix(cli): write machine-readable formats directly to stdout bypassing Rich line-wrapping

The format_output() function returned a string that callers passed to
Rich console.print(), which wraps long lines at terminal width.  This
injected literal newline characters into JSON string values (e.g. in
definition_of_done fields), producing invalid JSON that downstream
parsers could not decode (JSONDecodeError: Invalid control character).

For machine-readable formats (json, yaml, plain), format_output() now
writes the rendered output directly to sys.stdout and returns an empty
string.  This preserves the exact serialization from json.dumps/
yaml.dump without Rich text processing artifacts.

Refs: #746
This commit is contained in:
Luis Mendes
2026-03-13 23:03:43 +00:00
parent 2acb957d83
commit ab911dbdc4
22 changed files with 298 additions and 52 deletions
+29
View File
@@ -87,6 +87,31 @@ def _make_mock_container(
return mock_container
def _capturing_format_output(data: Any, format_type: str) -> str:
"""Wrapper around ``format_output`` that captures stdout writes.
``format_output`` for machine-readable formats (json, yaml, plain)
writes directly to ``sys.stdout`` and returns ``""``. This wrapper
redirects ``sys.stdout`` only during the ``format_output`` call so
that the rendered content is returned as a string, allowing the
caller's ``console.print(result)`` to write it to the test's Rich
console buffer. Structlog noise that would otherwise pollute the
captured stdout is excluded because the redirect is scoped tightly.
"""
import sys as _sys
from cleveragents.cli.formatting import format_output as _real_format_output
buf = StringIO()
old = _sys.stdout
_sys.stdout = buf
try:
ret = _real_format_output(data, format_type)
finally:
_sys.stdout = old
return ret or buf.getvalue().rstrip("\n")
def _run_cli_func(
func: Any,
repo: NamespacedProjectRepository,
@@ -123,6 +148,10 @@ def _run_cli_func(
"cleveragents.cli.commands.project_context.err_console",
test_console,
),
patch(
"cleveragents.cli.commands.project_context.format_output",
_capturing_format_output,
),
):
try:
func(**kwargs)