From 6e52eb55c9a711ea189627661962bc1f271f9879 Mon Sep 17 00:00:00 2001 From: jawwad-ali Date: Fri, 31 Jul 2026 12:57:51 +0500 Subject: [PATCH] fix(powershell): stop Out-Null swallowing the AVAILABLE_DOCS status lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test-FileExists / Test-DirHasFiles report their line with Write-Output and ALSO return $true/$false — both on the Success stream. The callers piped the whole call to `| Out-Null` to discard the boolean, which discarded the report line with it, so text mode printed the header and nothing under it: BEFORE (measured, powershell.exe -NoProfile -File ... -IncludeTasks): FEATURE_DIR:...\specs\001-f AVAILABLE_DOCS: (2 lines) AFTER: FEATURE_DIR:...\specs\001-f AVAILABLE_DOCS: [OK] research.md [FAIL] data-model.md [FAIL] contracts/ [FAIL] quickstart.md [FAIL] tasks.md (7 lines) The bash and Python twins both list every document under that header, so the PowerShell variant silently returned less information for the same inputs. Filter out only the boolean, keeping the report lines. Adds the first PowerShell text-mode test in this file (every existing PS test is -Json). File stays ASCII-only (verified 0 non-ASCII bytes). Co-Authored-By: Claude Opus 5 (1M context) --- scripts/powershell/check-prerequisites.ps1 | 17 +++++---- .../test_check_prerequisites_python_parity.py | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/scripts/powershell/check-prerequisites.ps1 b/scripts/powershell/check-prerequisites.ps1 index 07ece76e21..43107f20f3 100644 --- a/scripts/powershell/check-prerequisites.ps1 +++ b/scripts/powershell/check-prerequisites.ps1 @@ -141,13 +141,18 @@ if ($Json) { Write-Output "FEATURE_DIR:$($paths.FEATURE_DIR)" Write-Output "AVAILABLE_DOCS:" - # Show status of each potential document - Test-FileExists -Path $paths.RESEARCH -Description 'research.md' | Out-Null - Test-FileExists -Path $paths.DATA_MODEL -Description 'data-model.md' | Out-Null - Test-DirHasFiles -Path $paths.CONTRACTS_DIR -Description 'contracts/' | Out-Null - Test-FileExists -Path $paths.QUICKSTART -Description 'quickstart.md' | Out-Null + # Show status of each potential document. + # These helpers report their line with Write-Output and ALSO return a + # bool, both on the Success stream, so 'Out-Null' discarded the report + # line along with the return value and left AVAILABLE_DOCS empty. Drop + # only the boolean so the per-document lines reach stdout like the + # bash and Python twins. + Test-FileExists -Path $paths.RESEARCH -Description 'research.md' | Where-Object { $_ -isnot [bool] } + Test-FileExists -Path $paths.DATA_MODEL -Description 'data-model.md' | Where-Object { $_ -isnot [bool] } + Test-DirHasFiles -Path $paths.CONTRACTS_DIR -Description 'contracts/' | Where-Object { $_ -isnot [bool] } + Test-FileExists -Path $paths.QUICKSTART -Description 'quickstart.md' | Where-Object { $_ -isnot [bool] } if ($IncludeTasks) { - Test-FileExists -Path $paths.TASKS -Description 'tasks.md' | Out-Null + Test-FileExists -Path $paths.TASKS -Description 'tasks.md' | Where-Object { $_ -isnot [bool] } } } diff --git a/tests/test_check_prerequisites_python_parity.py b/tests/test_check_prerequisites_python_parity.py index cdc02b915d..baf788de8c 100644 --- a/tests/test_check_prerequisites_python_parity.py +++ b/tests/test_check_prerequisites_python_parity.py @@ -436,3 +436,38 @@ def test_hyphen_separator_is_still_honoured(self, tmp_path: Path): "integration_settings": {"droid": {"invoke_separator": "-"}}, }) assert common.get_invoke_separator(self._repo(tmp_path, body)) == "-" + + +@pytest.mark.skipif( + not (HAS_PWSH or _WINDOWS_POWERSHELL), reason="no PowerShell available" +) +def test_powershell_text_output_lists_available_docs(prereq_repo: Path) -> None: + """Text mode must print a status line per document, like the twins. + + `Test-FileExists` / `Test-DirHasFiles` report their line with `Write-Output` + and ALSO `return $true/$false`, both on the Success stream. The callers piped + the whole call to `| Out-Null` to discard the boolean, which discarded the + report line too — so `AVAILABLE_DOCS:` was emitted with nothing under it + while the bash and Python twins list every document. + """ + feat = prereq_repo / "specs" / "001-my-feature" + feat.mkdir(parents=True) + (feat / "plan.md").write_text("# plan\n", encoding="utf-8") + (feat / "research.md").write_text("# research\n", encoding="utf-8") + _write_feature_json(prereq_repo) + + ps = _run(_ps_cmd(prereq_repo, "-IncludeTasks"), prereq_repo) + + assert ps.returncode == 0, ps.stderr + assert "AVAILABLE_DOCS:" in ps.stdout + for doc in ( + "research.md", + "data-model.md", + "contracts/", + "quickstart.md", + "tasks.md", + ): + assert doc in ps.stdout, (doc, ps.stdout) + # The existing file reports [OK], the missing ones [FAIL]. + assert "[OK] research.md" in _normalize_status_text(ps.stdout), ps.stdout + assert "[FAIL] quickstart.md" in _normalize_status_text(ps.stdout), ps.stdout