fix(scripts): stop check-prerequisites text mode crashing on a legacy code page

_check_file/_check_dir hard-code U+2713/U+2717 and print() them to
sys.stdout. On Windows sys.stdout falls back to the ANSI code page whenever
stdout is not a console — which is every time an agent or a workflow step
captures the output — and U+2713 is unencodable in cp1252:

  stdout encoding: cp1252
  UnicodeEncodeError: 'charmap' codec can't encode character '✓'

So text mode aborted right after printing "AVAILABLE_DOCS:", losing every
per-document line.

Fall back to ASCII when stdout cannot encode the glyph. "[OK]"/"[FAIL]" is
the rendering these markers already have in-tree: Test-FileExists in
scripts/powershell/common.ps1 emits exactly those, and
normalize_status_text in tests/parity_helpers.py maps the glyphs onto them,
so the twins already treat the two forms as equivalent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
jawwad-ali
2026-07-31 12:52:37 +05:00
co-authored by Claude Opus 5
parent 81bf741b92
commit 275663b463
2 changed files with 60 additions and 4 deletions
+21 -4
View File
@@ -130,14 +130,31 @@ def _print_paths_only(paths: FeaturePaths, json_mode: bool) -> None:
print(f"TASKS: {paths.tasks}")
def _status_marker(ok: bool) -> str:
"""Return the status glyph, downgraded to ASCII when stdout cannot encode it.
On Windows sys.stdout falls back to the ANSI code page whenever it is not a
console - a pipe or a file redirect, which is how agents and workflow steps
invoke these scripts - and U+2713 is unencodable in cp1252, so printing it
raised UnicodeEncodeError and aborted the report right after
"AVAILABLE_DOCS:". "[OK]"/"[FAIL]" is the ASCII rendering these markers
already have in-tree: see Test-FileExists in scripts/powershell/common.ps1
and normalize_status_text in tests/parity_helpers.py.
"""
glyph = "✓" if ok else "✗"
try:
glyph.encode(getattr(sys.stdout, "encoding", None) or "utf-8")
except (LookupError, UnicodeEncodeError):
return "[OK]" if ok else "[FAIL]"
return glyph
def _check_file(path: Path, description: str) -> None:
marker = "✓" if path.is_file() else "✗"
print(f" {marker} {description}")
print(f" {_status_marker(path.is_file())} {description}")
def _check_dir(path: Path, description: str) -> None:
marker = "✓" if _dir_has_entries(path) else "✗"
print(f" {marker} {description}")
print(f" {_status_marker(_dir_has_entries(path))} {description}")
def _print_text_results(paths: FeaturePaths, include_tasks: bool) -> None: