Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/specify_cli/presets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,7 @@ def record_written(written: Dict[str, List[str]]) -> None:
ext_manifest_path = ext_dir / "extension.yml"
if ext_manifest_path.exists():
try:
from ..extensions import ExtensionManifest
from ..extensions import ExtensionManifest, ValidationError
ext_manifest = ExtensionManifest(ext_manifest_path)
# Filter to only the command being reconciled
matching_cmds = [
Expand All @@ -1727,7 +1727,7 @@ def record_written(written: Dict[str, List[str]]) -> None:
)
record_written(written)
registered = True
except Exception:
except (TypeError, ValueError, KeyError, ValidationError):
# Extension registration failed; fall back to
# generic path-based registration below.
pass
Expand Down
19 changes: 19 additions & 0 deletions tests/test_presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,25 @@ def test_resolve_extension_command_via_manifest_skips_oserror_manifests(self, pr

assert result is None, "OSError during manifest load must be silently skipped"

def test_resolve_extension_command_via_manifest_skips_validation_error(self, project_dir):
"""resolve_extension_command_via_manifest skips extensions whose manifest raises ValidationError."""
import unittest.mock as mock

ext_dir = project_dir / ".specify" / "extensions" / "bad-ext"
cmd_dir = ext_dir / "commands"
cmd_dir.mkdir(parents=True)
(cmd_dir / "mycmd.md").write_text("---\ndescription: d\n---\n\nbody\n")
# Write a manifest with missing required fields to trigger ValidationError
(ext_dir / "extension.yml").write_text(
"schema_version: '1.0'\n"
"extension:\n id: bad-ext\n"
)

resolver = PresetResolver(project_dir)
result = resolver.resolve_extension_command_via_manifest("speckit.bad-ext.mycmd")

assert result is None, "ValidationError during manifest load must be silently skipped"


class TestExtensionPriorityResolution:
"""Test extension priority resolution with registered and unregistered extensions."""
Expand Down