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
9 changes: 9 additions & 0 deletions src/specify_cli/bundler/services/references.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,17 @@ def _resolved_locally(root: Path, component: ComponentRef) -> bool:
return True
return WorkflowRegistry(root).is_installed(component.id)
if kind == "steps":
from ...workflows import STEP_REGISTRY
from ...workflows.catalog import StepRegistry

# Step types ship with Spec Kit as built-ins (shell, gate, if, ...)
# rather than as an on-disk asset directory, so there is no
# ``_locate_bundled_step`` to mirror the three lookups above.
# ``STEP_REGISTRY`` is the bundled-with-Spec-Kit check for this kind
# -- it is what ``specify workflow step info`` reports as
# "built-in". Without it every built-in step type looked unresolved.
if component.id in STEP_REGISTRY:
return True
Comment on lines +52 to +53
return StepRegistry(root).is_installed(component.id)
except Exception: # noqa: BLE001 - resolution is best-effort
return False
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/test_bundler_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,38 @@ def test_bundled_extension_resolves(tmp_path: Path):
assert warnings == []


def test_builtin_step_type_resolves(tmp_path: Path):
"""A built-in step type must resolve, like a bundled extension.

Spec Kit ships 11 step types as built-ins registered in ``STEP_REGISTRY``
rather than as on-disk asset directories, so there is no
``_locate_bundled_step``. The ``steps`` branch of ``_resolved_locally`` only
asked ``StepRegistry(root).is_installed()``, which tracks *community* step
types installed under ``.specify/workflows/steps/`` — so every built-in step
type was reported as an unresolved reference.
"""
from specify_cli.workflows import STEP_REGISTRY

root = make_project(tmp_path)
warnings: list[str] = []
check = make_reference_checker(root, allow_network=True, warnings=warnings)

for step_id in ("shell", "gate", "command", "if"):
assert step_id in STEP_REGISTRY, step_id
assert check(_ref("steps", step_id)) is None, step_id
assert warnings == []


def test_unknown_step_type_still_errors_online(tmp_path: Path):
"""The guard must not make every step id resolve."""
root = make_project(tmp_path)
warnings: list[str] = []
check = make_reference_checker(root, allow_network=True, warnings=warnings)
problem = check(_ref("steps", "no-such-step-type"))
assert problem is not None
assert "no-such-step-type" in problem


def test_unknown_reference_errors_online(tmp_path: Path):
root = make_project(tmp_path)
warnings: list[str] = []
Expand Down