Skip to content

Commit bc3341a

Browse files
committed
fix(scripts): honor SPECIFY_NO_PERSIST in create-new-feature's direct feature.json write
The three create-new-feature variants write .specify/feature.json directly rather than through get_feature_paths(), so they ignored SPECIFY_NO_PERSIST entirely, leaving the "stops every core script from writing feature.json" guarantee in docs/reference/core.md broader than the implementation.
1 parent d17ba34 commit bc3341a

4 files changed

Lines changed: 60 additions & 6 deletions

File tree

‎scripts/bash/create-new-feature.sh‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,11 @@ if [ "$DRY_RUN" != true ]; then
366366
fi
367367
fi
368368

369-
# Persist to .specify/feature.json so downstream commands can find the feature
370-
_persist_feature_json "$REPO_ROOT" "$FEATURE_DIR"
369+
# Persist to .specify/feature.json so downstream commands can find the
370+
# feature, unless the orchestrator opted out via SPECIFY_NO_PERSIST (#4129).
371+
if [[ "${SPECIFY_NO_PERSIST:-}" != "1" && "${SPECIFY_NO_PERSIST:-}" != "true" ]]; then
372+
_persist_feature_json "$REPO_ROOT" "$FEATURE_DIR"
373+
fi
371374

372375
# Inform the user how to set feature state in their own shell
373376
printf '# To persist: export SPECIFY_FEATURE=%s\n' "$(shell_quote "$BRANCH_NAME")" >&2

‎scripts/powershell/create-new-feature.ps1‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,11 @@ if (-not $DryRun) {
283283
}
284284
}
285285

286-
# Persist to .specify/feature.json so downstream commands can find the feature
287-
Save-FeatureJson -RepoRoot $repoRoot -FeatureDirectory $featureDir
286+
# Persist to .specify/feature.json so downstream commands can find the
287+
# feature, unless the orchestrator opted out via SPECIFY_NO_PERSIST (#4129).
288+
if ($env:SPECIFY_NO_PERSIST -ne '1' -and $env:SPECIFY_NO_PERSIST -ne 'true') {
289+
Save-FeatureJson -RepoRoot $repoRoot -FeatureDirectory $featureDir
290+
}
288291

289292
# Set environment variables for the current session
290293
$env:SPECIFY_FEATURE = $branchName

‎scripts/python/create_new_feature.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import datetime
77
import json
8+
import os
89
import re
910
import shlex
1011
import sys
@@ -406,8 +407,10 @@ def main(argv: list[str] | None = None) -> int:
406407
)
407408
spec_file.touch()
408409

409-
# Persist to .specify/feature.json so downstream commands can find the feature.
410-
persist_feature_json(repo_root, f"specs/{branch_name}")
410+
# Persist to .specify/feature.json so downstream commands can find the
411+
# feature, unless the orchestrator opted out via SPECIFY_NO_PERSIST (#4129).
412+
if os.environ.get("SPECIFY_NO_PERSIST", "") not in ("1", "true"):
413+
persist_feature_json(repo_root, f"specs/{branch_name}")
411414

412415
# Inform the user how to set feature state in their own shell.
413416
feature_assignment, directory_assignment = _persistence_assignments(

‎tests/test_specify_no_persist.py‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,48 @@ def test_py_specify_no_persist_suppresses_write(repo: Path) -> None:
112112
result = run(py_cmd(repo, SCRIPT, "--json"), repo, env)
113113
assert result.returncode == 0, result.stderr
114114
assert _feature_json(repo) is None
115+
116+
117+
# create-new-feature writes .specify/feature.json directly (not via
118+
# get_feature_paths()), so it must honor SPECIFY_NO_PERSIST separately.
119+
120+
CREATE_SCRIPT = "create-new-feature"
121+
SPEC_TEMPLATE_BODY = "# Spec Template\n\nBody.\n"
122+
123+
124+
def _create_feature_repo(tmp_path: Path, name: str = "proj") -> Path:
125+
repo = make_repo(tmp_path, name)
126+
install_scripts(repo, CREATE_SCRIPT)
127+
templates = repo / ".specify" / "templates"
128+
templates.mkdir(parents=True, exist_ok=True)
129+
(templates / "spec-template.md").write_text(SPEC_TEMPLATE_BODY, encoding="utf-8")
130+
return repo
131+
132+
133+
@requires_bash
134+
def test_bash_create_new_feature_no_persist_suppresses_write(tmp_path: Path) -> None:
135+
repo = _create_feature_repo(tmp_path)
136+
env = clean_env()
137+
env["SPECIFY_NO_PERSIST"] = "1"
138+
result = run(bash_cmd(repo, CREATE_SCRIPT, "--json", "x"), repo, env)
139+
assert result.returncode == 0, result.stderr
140+
assert _feature_json(repo) is None
141+
142+
143+
@pytest.mark.skipif(not HAS_POWERSHELL, reason="no PowerShell available")
144+
def test_ps_create_new_feature_no_persist_suppresses_write(tmp_path: Path) -> None:
145+
repo = _create_feature_repo(tmp_path)
146+
env = clean_env()
147+
env["SPECIFY_NO_PERSIST"] = "true"
148+
result = run(ps_cmd(repo, CREATE_SCRIPT, "-Json", "x"), repo, env)
149+
assert result.returncode == 0, result.stderr
150+
assert _feature_json(repo) is None
151+
152+
153+
def test_py_create_new_feature_no_persist_suppresses_write(tmp_path: Path) -> None:
154+
repo = _create_feature_repo(tmp_path)
155+
env = clean_env()
156+
env["SPECIFY_NO_PERSIST"] = "1"
157+
result = run(py_cmd(repo, CREATE_SCRIPT, "--json", "x"), repo, env)
158+
assert result.returncode == 0, result.stderr
159+
assert _feature_json(repo) is None

0 commit comments

Comments
 (0)