diff --git a/scripts/powershell/create-new-feature.ps1 b/scripts/powershell/create-new-feature.ps1 index 5826815e0..91b36bebd 100644 --- a/scripts/powershell/create-new-feature.ps1 +++ b/scripts/powershell/create-new-feature.ps1 @@ -211,6 +211,10 @@ if (-not $DryRun) { $utf8NoBom = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText($specFile, $content, $utf8NoBom) } else { + # Match the bash twin (create-new-feature.sh): warn on stderr that no + # spec template was found before creating an empty spec file, so the + # missing-template signal is not silently swallowed on Windows. + [Console]::Error.WriteLine("Warning: Spec template not found; created empty spec file") New-Item -ItemType File -Path $specFile -Force | Out-Null } } diff --git a/tests/test_timestamp_branches.py b/tests/test_timestamp_branches.py index 6fe0c14ed..2a0a2ca69 100644 --- a/tests/test_timestamp_branches.py +++ b/tests/test_timestamp_branches.py @@ -332,6 +332,27 @@ class TestSequentialBranchPowerShell: assert data["FEATURE_NUM"] == "000" assert data["BRANCH_NAME"] == "000-zero" + @pytest.mark.skipif(not _has_pwsh(), reason="pwsh not installed") + def test_missing_spec_template_warns_matching_bash(self, ps_git_repo: Path): + """When no spec template can be resolved, create-new-feature.ps1 must warn on + stderr (and still create an empty spec file), matching the bash twin's + 'Warning: Spec template not found; created empty spec file'. Before the fix + PowerShell created the empty file silently.""" + # Remove the template the fixture installs so resolution finds nothing. + (ps_git_repo / ".specify" / "templates" / "spec-template.md").unlink() + script = ps_git_repo / "scripts" / "powershell" / "create-new-feature.ps1" + result = subprocess.run( + ["pwsh", "-NoProfile", "-File", str(script), + "-Json", "-ShortName", "no-tmpl", "No template feature"], + cwd=ps_git_repo, capture_output=True, text=True, encoding="utf-8", + ) + assert result.returncode == 0, result.stderr + assert "Spec template not found" in result.stderr + # stdout stays parseable JSON and the empty spec file is still created. + data = json.loads(result.stdout) + spec_file = Path(data["SPEC_FILE"]) + assert spec_file.is_file() + # ── check_feature_branch Tests ───────────────────────────────────────────────