fix(scripts): honor explicit -Number 0 in PowerShell create-new-feature (parity with bash) (#3196)

Get-BranchName used `[long]$Number = 0` as both the default and the 'auto-detect' sentinel (`if ($Number -eq 0)`), so an explicitly-passed `-Number 0` was indistinguishable from 'not supplied' and silently auto-incremented. The bash twin keys off whether the value is non-empty (`[ -z "$BRANCH_NUMBER" ]`), so `--number 0` is honored and yields FEATURE_NUM 000 -- a cross-platform divergence for identical input.

Use $PSBoundParameters.ContainsKey('Number') instead, so an explicit value (including 0) is honored and only a missing -Number auto-detects -- mirroring bash. This also aligns the -Timestamp+-Number warning, which bash emits for `--number 0 --timestamp` (non-empty check) but PowerShell previously skipped.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ali jawwad
2026-06-29 19:52:22 +05:00
committed by GitHub
parent b7e67f55bf
commit fd185c1fd8
2 changed files with 38 additions and 4 deletions

View File

@@ -142,8 +142,10 @@ if ($ShortName) {
$branchSuffix = Get-BranchName -Description $featureDesc
}
# Warn if -Number and -Timestamp are both specified
if ($Timestamp -and $Number -ne 0) {
# Warn if -Number and -Timestamp are both specified. Use ContainsKey (not
# `-ne 0`) so an explicit `-Number 0` is also detected, matching the bash twin's
# `[ -n "$BRANCH_NUMBER" ]` check.
if ($Timestamp -and $PSBoundParameters.ContainsKey('Number')) {
Write-Warning "[specify] Warning: -Number is ignored when -Timestamp is used"
$Number = 0
}
@@ -153,8 +155,10 @@ if ($Timestamp) {
$featureNum = Get-Date -Format 'yyyyMMdd-HHmmss'
$branchName = "$featureNum-$branchSuffix"
} else {
# Determine branch number from existing feature directories
if ($Number -eq 0) {
# Determine branch number from existing feature directories. Auto-detect only
# when -Number was not supplied; an explicit value (including 0) is honored,
# matching the bash twin's `[ -z "$BRANCH_NUMBER" ]` check.
if (-not $PSBoundParameters.ContainsKey('Number')) {
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
}

View File

@@ -275,6 +275,19 @@ class TestSequentialBranch:
branch = line.split(":", 1)[1].strip()
assert branch == "1001-next-feat", f"expected 1001-next-feat, got: {branch}"
def test_explicit_number_zero_is_honored(self, git_repo: Path):
"""An explicit --number 0 is honored literally (FEATURE_NUM 000), not treated
as auto-detect, even when higher-numbered specs already exist. This pins the
canonical bash behavior the PowerShell twin must mirror."""
(git_repo / "specs" / "003-existing").mkdir(parents=True)
r = run_script(
git_repo, "--json", "--dry-run", "--number", "0", "--short-name", "zero", "Zero feature",
)
assert r.returncode == 0, r.stderr
data = json.loads(r.stdout)
assert data["FEATURE_NUM"] == "000"
assert data["BRANCH_NAME"] == "000-zero"
class TestSequentialBranchPowerShell:
def test_powershell_scanner_uses_long_tryparse_for_large_prefixes(self):
@@ -302,6 +315,23 @@ class TestSequentialBranchPowerShell:
assert r2.returncode == 0, r2.stderr
assert json.loads(r2.stdout)["BRANCH_NAME"] == "001-use-go-now"
@pytest.mark.skipif(not _has_pwsh(), reason="pwsh not installed")
def test_explicit_number_zero_is_honored_matching_bash(self, ps_git_repo: Path):
"""An explicit -Number 0 must be honored (FEATURE_NUM 000) like the bash twin,
even when higher-numbered specs exist. Before the fix, PowerShell could not
distinguish -Number 0 from the default and silently auto-detected (e.g. 004)."""
script = ps_git_repo / "scripts" / "powershell" / "create-new-feature.ps1"
(ps_git_repo / "specs" / "003-existing").mkdir(parents=True)
result = subprocess.run(
["pwsh", "-NoProfile", "-File", str(script),
"-Json", "-DryRun", "-Number", "0", "-ShortName", "zero", "Zero feature"],
cwd=ps_git_repo, capture_output=True, text=True,
)
assert result.returncode == 0, result.stderr
data = json.loads(result.stdout)
assert data["FEATURE_NUM"] == "000"
assert data["BRANCH_NAME"] == "000-zero"
# ── check_feature_branch Tests ───────────────────────────────────────────────