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
11 changes: 11 additions & 0 deletions src/specify_cli/bundler/models/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# reject an unsupported major version so a file written by a newer/incompatible
# Spec Kit fails fast instead of being parsed under the wrong assumptions.
CONFIG_SCHEMA_VERSION = "1.0"
CATALOG_SCHEMA_VERSION = "1.0"


class InstallPolicy(str, Enum):
Expand Down Expand Up @@ -215,6 +216,16 @@ def load_catalog_payload(data: Any) -> dict[str, CatalogEntry]:
"""Parse a catalog JSON payload into ``{bundle_id: CatalogEntry}``."""
if not isinstance(data, dict):
raise BundlerError("Catalog payload must be a JSON object.")
schema_version = data.get("schema_version")
if schema_version is not None and (
str(schema_version).strip().split(".")[0]
!= CATALOG_SCHEMA_VERSION.split(".")[0]
):
raise BundlerError(
f"Unsupported catalog schema version "
f"'{str(schema_version).strip()}'; this Spec Kit understands "
f"version {CATALOG_SCHEMA_VERSION}."
)
bundles_raw = data.get("bundles")
if not isinstance(bundles_raw, dict):
raise BundlerError("Catalog payload is missing a 'bundles' object.")
Expand Down
8 changes: 8 additions & 0 deletions tests/contract/test_catalog_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ def test_catalog_entry_rejects_non_mapping_provides():
CatalogEntry.from_dict(data)


def test_load_payload_rejects_unsupported_schema_version():
payload = catalog_payload({"demo": catalog_entry_dict("demo")})
payload["schema_version"] = "2.0"

with pytest.raises(BundlerError, match="Unsupported catalog schema version"):
load_catalog_payload(payload)


@pytest.mark.parametrize("field", ["requires", "provides"])
@pytest.mark.parametrize("bad", [[], "", 0, False])
def test_catalog_entry_rejects_falsy_non_mapping(field, bad):
Expand Down