Add repo-family metadata to Fabric registry
This commit is contained in:
parent
3240b78185
commit
0ea99a73d8
15 changed files with 189 additions and 32 deletions
|
|
@ -45,6 +45,11 @@ class RegistryStore:
|
|||
remote_url text,
|
||||
default_branch text,
|
||||
state_hub_repo_id text,
|
||||
repo_family text,
|
||||
ownership_repo text,
|
||||
primary_rail text,
|
||||
supported_rails_json text not null default '[]',
|
||||
substrate_kind text,
|
||||
created_at text not null,
|
||||
updated_at text not null
|
||||
);
|
||||
|
|
@ -127,6 +132,7 @@ class RegistryStore:
|
|||
);
|
||||
"""
|
||||
)
|
||||
_ensure_repository_columns(db)
|
||||
|
||||
def upsert_repository(self, payload: dict[str, Any]) -> dict[str, Any]:
|
||||
slug = _required_text(payload, "slug")
|
||||
|
|
@ -135,22 +141,46 @@ class RegistryStore:
|
|||
remote_url = _optional_text(payload, "remote_url")
|
||||
default_branch = str(payload.get("default_branch") or "main")
|
||||
state_hub_repo_id = _optional_text(payload, "state_hub_repo_id")
|
||||
repo_family = _optional_text(payload, "repo_family")
|
||||
ownership_repo = _optional_text(payload, "ownership_repo")
|
||||
primary_rail = _optional_text(payload, "primary_rail")
|
||||
supported_rails = _optional_string_list(payload, "supported_rails")
|
||||
substrate_kind = _optional_text(payload, "substrate_kind")
|
||||
with self._connect() as db:
|
||||
db.execute(
|
||||
"""
|
||||
insert into repositories (
|
||||
slug, name, remote_url, default_branch, state_hub_repo_id,
|
||||
created_at, updated_at
|
||||
repo_family, ownership_repo, primary_rail, supported_rails_json,
|
||||
substrate_kind, created_at, updated_at
|
||||
)
|
||||
values (?, ?, ?, ?, ?, ?, ?)
|
||||
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
on conflict(slug) do update set
|
||||
name = excluded.name,
|
||||
remote_url = excluded.remote_url,
|
||||
default_branch = excluded.default_branch,
|
||||
state_hub_repo_id = excluded.state_hub_repo_id,
|
||||
repo_family = excluded.repo_family,
|
||||
ownership_repo = excluded.ownership_repo,
|
||||
primary_rail = excluded.primary_rail,
|
||||
supported_rails_json = excluded.supported_rails_json,
|
||||
substrate_kind = excluded.substrate_kind,
|
||||
updated_at = excluded.updated_at
|
||||
""",
|
||||
(slug, name, remote_url, default_branch, state_hub_repo_id, now, now),
|
||||
(
|
||||
slug,
|
||||
name,
|
||||
remote_url,
|
||||
default_branch,
|
||||
state_hub_repo_id,
|
||||
repo_family,
|
||||
ownership_repo,
|
||||
primary_rail,
|
||||
json.dumps(supported_rails, sort_keys=True),
|
||||
substrate_kind,
|
||||
now,
|
||||
now,
|
||||
),
|
||||
)
|
||||
return self.get_repository(slug)
|
||||
|
||||
|
|
@ -159,19 +189,21 @@ class RegistryStore:
|
|||
rows = db.execute(
|
||||
"""
|
||||
select slug, name, remote_url, default_branch, state_hub_repo_id,
|
||||
created_at, updated_at
|
||||
repo_family, ownership_repo, primary_rail,
|
||||
supported_rails_json, substrate_kind, created_at, updated_at
|
||||
from repositories
|
||||
order by slug
|
||||
"""
|
||||
).fetchall()
|
||||
return [_row_dict(row) for row in rows]
|
||||
return [_repository_dict(row) for row in rows]
|
||||
|
||||
def get_repository(self, slug: str) -> dict[str, Any]:
|
||||
with self._connect() as db:
|
||||
row = db.execute(
|
||||
"""
|
||||
select slug, name, remote_url, default_branch, state_hub_repo_id,
|
||||
created_at, updated_at
|
||||
repo_family, ownership_repo, primary_rail,
|
||||
supported_rails_json, substrate_kind, created_at, updated_at
|
||||
from repositories
|
||||
where slug = ?
|
||||
""",
|
||||
|
|
@ -179,7 +211,7 @@ class RegistryStore:
|
|||
).fetchone()
|
||||
if row is None:
|
||||
raise RegistryError(f"repository not found: {slug}", 404)
|
||||
return _row_dict(row)
|
||||
return _repository_dict(row)
|
||||
|
||||
def add_snapshot(self, repo_slug: str, payload: dict[str, Any]) -> dict[str, Any]:
|
||||
self.get_repository(repo_slug)
|
||||
|
|
@ -1503,6 +1535,34 @@ def _row_dict(row: sqlite3.Row) -> dict[str, Any]:
|
|||
return {key: row[key] for key in row.keys()}
|
||||
|
||||
|
||||
def _repository_dict(row: sqlite3.Row) -> dict[str, Any]:
|
||||
data = _row_dict(row)
|
||||
raw_supported_rails = data.pop("supported_rails_json", "[]")
|
||||
try:
|
||||
decoded = json.loads(raw_supported_rails or "[]")
|
||||
except json.JSONDecodeError:
|
||||
decoded = []
|
||||
data["supported_rails"] = decoded if isinstance(decoded, list) else []
|
||||
return data
|
||||
|
||||
|
||||
def _ensure_repository_columns(db: sqlite3.Connection) -> None:
|
||||
existing = {
|
||||
str(row[1])
|
||||
for row in db.execute("pragma table_info(repositories)").fetchall()
|
||||
}
|
||||
additions = {
|
||||
"repo_family": "text",
|
||||
"ownership_repo": "text",
|
||||
"primary_rail": "text",
|
||||
"supported_rails_json": "text not null default '[]'",
|
||||
"substrate_kind": "text",
|
||||
}
|
||||
for name, ddl in additions.items():
|
||||
if name not in existing:
|
||||
db.execute(f"alter table repositories add column {name} {ddl}")
|
||||
|
||||
|
||||
def _resettable_counts(db: sqlite3.Connection) -> dict[str, int]:
|
||||
return {
|
||||
"snapshots": int(db.execute("select count(*) from snapshots").fetchone()[0]),
|
||||
|
|
@ -1911,6 +1971,24 @@ def _optional_text(payload: dict[str, Any], key: str) -> str | None:
|
|||
return value
|
||||
|
||||
|
||||
def _optional_string_list(payload: dict[str, Any], key: str) -> list[str]:
|
||||
value = payload.get(key)
|
||||
if value is None:
|
||||
return []
|
||||
if not isinstance(value, list):
|
||||
raise RegistryError(f"field '{key}' must be an array of strings")
|
||||
result: list[str] = []
|
||||
seen: set[str] = set()
|
||||
for item in value:
|
||||
if not isinstance(item, str) or not item.strip():
|
||||
raise RegistryError(f"field '{key}' must be an array of non-empty strings")
|
||||
cleaned = item.strip()
|
||||
if cleaned not in seen:
|
||||
seen.add(cleaned)
|
||||
result.append(cleaned)
|
||||
return result
|
||||
|
||||
|
||||
def _utc_now() -> str:
|
||||
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue