From 2b36f0ce94cc2a86f0aec921c57412d6bc255414 Mon Sep 17 00:00:00 2001 From: Ali jawwad <33836051+jawwad-ali@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:58:46 +0500 Subject: [PATCH] fix(powershell): stop Out-Null swallowing the AVAILABLE_DOCS status lines (#3891) 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 c547d5f8c..27c87d6c6 100644 --- a/scripts/powershell/check-prerequisites.ps1 +++ b/scripts/powershell/check-prerequisites.ps1 @@ -157,13 +157,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 6dbd4c62e..b0e74217c 100644 --- a/tests/test_check_prerequisites_python_parity.py +++ b/tests/test_check_prerequisites_python_parity.py @@ -564,3 +564,38 @@ class TestGetInvokeSeparatorTolerance: "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