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:
@@ -210,17 +210,23 @@ def step_request_diff_rich(context: Context) -> None:
|
||||
|
||||
@when("I request the diff in plain format")
|
||||
def step_request_diff_plain(context: Context) -> None:
|
||||
context.diff_output = context.apply_service.diff(context.plan_id, fmt="plain")
|
||||
context.diff_output = _capture_service_output(
|
||||
context.apply_service.diff, context.plan_id, fmt="plain"
|
||||
)
|
||||
|
||||
|
||||
@when("I request the diff in JSON format")
|
||||
def step_request_diff_json(context: Context) -> None:
|
||||
context.diff_output = context.apply_service.diff(context.plan_id, fmt="json")
|
||||
context.diff_output = _capture_service_output(
|
||||
context.apply_service.diff, context.plan_id, fmt="json"
|
||||
)
|
||||
|
||||
|
||||
@when("I request the diff in YAML format")
|
||||
def step_request_diff_yaml(context: Context) -> None:
|
||||
context.diff_output = context.apply_service.diff(context.plan_id, fmt="yaml")
|
||||
context.diff_output = _capture_service_output(
|
||||
context.apply_service.diff, context.plan_id, fmt="yaml"
|
||||
)
|
||||
|
||||
|
||||
@when("I try to get the diff")
|
||||
@@ -234,27 +240,40 @@ def step_try_get_diff(context: Context) -> None:
|
||||
|
||||
@when("I request the artifacts")
|
||||
def step_request_artifacts(context: Context) -> None:
|
||||
context.artifacts_output = context.apply_service.artifacts(context.plan_id)
|
||||
context.artifacts_output = _capture_service_output(
|
||||
context.apply_service.artifacts, context.plan_id
|
||||
)
|
||||
|
||||
|
||||
def _capture_service_output(func, *args, **kwargs):
|
||||
"""Call a service method capturing stdout (format_output writes there)."""
|
||||
from contextlib import redirect_stdout
|
||||
from io import StringIO
|
||||
|
||||
buf = StringIO()
|
||||
with redirect_stdout(buf):
|
||||
result = func(*args, **kwargs)
|
||||
return result or buf.getvalue().rstrip("\n")
|
||||
|
||||
|
||||
@when("I request the artifacts in JSON format")
|
||||
def step_request_artifacts_json(context: Context) -> None:
|
||||
context.artifacts_output = context.apply_service.artifacts(
|
||||
context.plan_id, fmt="json"
|
||||
context.artifacts_output = _capture_service_output(
|
||||
context.apply_service.artifacts, context.plan_id, fmt="json"
|
||||
)
|
||||
|
||||
|
||||
@when("I request the artifacts in plain format")
|
||||
def step_request_artifacts_plain(context: Context) -> None:
|
||||
context.artifacts_output = context.apply_service.artifacts(
|
||||
context.plan_id, fmt="plain"
|
||||
context.artifacts_output = _capture_service_output(
|
||||
context.apply_service.artifacts, context.plan_id, fmt="plain"
|
||||
)
|
||||
|
||||
|
||||
@when("I request the artifacts in YAML format")
|
||||
def step_request_artifacts_yaml(context: Context) -> None:
|
||||
context.artifacts_output = context.apply_service.artifacts(
|
||||
context.plan_id, fmt="yaml"
|
||||
context.artifacts_output = _capture_service_output(
|
||||
context.apply_service.artifacts, context.plan_id, fmt="yaml"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user