Skip to content

Commit fb14229

Browse files
BenBtgCopilot
andcommitted
chore: split out unrelated integration-upgrade fix
Move the stale_cleanup_exclusions / executable-bit upgrade fix (base.py, copilot, _migrate_commands.py, test_integration_subcommand.py) out of this PR into its own change. This PR is now scoped purely to the /speckit.converge command. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3b80e57 commit fb14229

4 files changed

Lines changed: 1 addition & 75 deletions

File tree

src/specify_cli/integrations/_migrate_commands.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,6 @@ def integration_upgrade(
461461
raise _SharedTemplateRefreshError(
462462
f"Failed to refresh shared infrastructure for '{key}': {exc}"
463463
) from exc
464-
if os.name != "nt":
465-
from .. import ensure_executable_scripts
466-
ensure_executable_scripts(project_root)
467464
new_manifest.save()
468465
_write_integration_json(project_root, installed_key, installed_keys, settings)
469466
if installed_key == key:
@@ -481,10 +478,7 @@ def integration_upgrade(
481478
# Phase 2: Remove stale files from old manifest that are not in the new one
482479
old_files = old_manifest.files
483480
new_files = new_manifest.files
484-
# Exclude integration-declared paths that use conditional manifest tracking
485-
# (e.g. merge targets like .vscode/settings.json) so they are never deleted
486-
# as "stale" while still being actively managed.
487-
stale_keys = (set(old_files) - set(new_files)) - integration.stale_cleanup_exclusions()
481+
stale_keys = set(old_files) - set(new_files)
488482
if stale_keys:
489483
stale_manifest = IntegrationManifest(key, project_root, version="stale-cleanup")
490484
stale_manifest._files = {k: old_files[k] for k in stale_keys}

src/specify_cli/integrations/base.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -393,18 +393,6 @@ def command_filename(self, template_name: str) -> str:
393393
"""
394394
return f"speckit.{template_name}.md"
395395

396-
def stale_cleanup_exclusions(self) -> set[str]:
397-
"""Return project-relative paths that upgrade must never stale-delete.
398-
399-
During ``integration upgrade``, files recorded in a previous manifest
400-
but absent from the freshly written one are treated as stale and
401-
removed. Conditionally-tracked files (e.g. a settings file that the
402-
integration merges into when it already exists, and therefore stops
403-
tracking) would otherwise be deleted even though they are still
404-
managed. Subclasses list such paths here to protect them.
405-
"""
406-
return set()
407-
408396
def commands_dest(self, project_root: Path) -> Path:
409397
"""Return the absolute path to the commands output directory.
410398

src/specify_cli/integrations/copilot/__init__.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -282,17 +282,6 @@ def command_filename(self, template_name: str) -> str:
282282
"""Copilot commands use ``.agent.md`` extension."""
283283
return f"speckit.{template_name}.agent.md"
284284

285-
def stale_cleanup_exclusions(self) -> set[str]:
286-
"""Protect ``.vscode/settings.json`` from upgrade stale-deletion.
287-
288-
``setup()`` records this file in the manifest only when it creates it;
289-
when it already exists the file is merged and intentionally left
290-
untracked. On upgrade the untracked-but-existing file would otherwise
291-
be flagged stale and deleted, destroying user settings (and the file
292-
the integration still manages).
293-
"""
294-
return {".vscode/settings.json"}
295-
296285
def post_process_skill_content(self, content: str) -> str:
297286
"""Inject shared hook guidance into Copilot skill content.
298287

tests/integrations/test_integration_subcommand.py

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,51 +2272,6 @@ def test_upgrade_migrates_opencode_legacy_dir(self, tmp_path):
22722272
f"found: {[f.name for f in core_remaining]}"
22732273
)
22742274

2275-
def test_upgrade_preserves_existing_vscode_settings(self, tmp_path):
2276-
"""Regression: copilot upgrade must not stale-delete .vscode/settings.json.
2277-
2278-
On init the file is created and recorded in the manifest. On upgrade,
2279-
setup() merges into the now-existing file and intentionally stops
2280-
tracking it, so without ``stale_cleanup_exclusions()`` the Phase 2
2281-
stale cleanup would delete it (destroying the user's settings).
2282-
"""
2283-
project = _init_project(tmp_path, "copilot")
2284-
settings = project / ".vscode" / "settings.json"
2285-
assert settings.is_file(), "init should create .vscode/settings.json"
2286-
before = json.loads(settings.read_text(encoding="utf-8"))
2287-
assert before, "settings.json should contain managed defaults"
2288-
2289-
result = _run_in_project(project, [
2290-
"integration", "upgrade", "copilot",
2291-
"--script", "sh",
2292-
])
2293-
assert result.exit_code == 0, result.output
2294-
2295-
assert settings.is_file(), ".vscode/settings.json must survive upgrade"
2296-
after = json.loads(settings.read_text(encoding="utf-8"))
2297-
assert after == before, "managed settings must be intact after upgrade"
2298-
2299-
def test_upgrade_restores_executable_bit_on_shared_scripts(self, tmp_path):
2300-
"""Regression: scripts refreshed by the managed-refresh step stay +x."""
2301-
if os.name == "nt":
2302-
pytest.skip("POSIX execute bits are not meaningful on Windows")
2303-
project = _init_project(tmp_path, "copilot")
2304-
script = project / ".specify" / "scripts" / "bash" / "check-prerequisites.sh"
2305-
assert script.is_file()
2306-
# Simulate a perms-losing install (e.g. wheel extraction dropping +x).
2307-
script.chmod(0o644)
2308-
assert not (script.stat().st_mode & 0o111)
2309-
2310-
result = _run_in_project(project, [
2311-
"integration", "upgrade", "copilot",
2312-
"--script", "sh",
2313-
])
2314-
assert result.exit_code == 0, result.output
2315-
2316-
assert script.stat().st_mode & 0o111, (
2317-
"shared .sh scripts must be executable after upgrade"
2318-
)
2319-
23202275

23212276
# ── Full lifecycle ───────────────────────────────────────────────────
23222277

0 commit comments

Comments
 (0)