from __future__ import annotations
from pathlib import Path
from typing import Any
from .config import Settings
class InventoryError(ValueError):
pass
class InventoryRepository:
def __init__(self, settings: Settings) -> None:
self.settings = settings
self.inventory_dir = settings.inventory_dir.resolve()
def list_types(self) -> list[str]:
return sorted(path.stem for path in self.inventory_dir.glob("*.yml"))
def read_raw(self, inventory_type: str) -> str:
path = self._path_for_type(inventory_type)
return path.read_text(encoding="utf-8")
def read_parsed(self, inventory_type: str) -> Any:
try:
import yaml
except ModuleNotFoundError as exc:
raise InventoryError("PyYAML is required for parsed inventory") from exc
raw = self.read_raw(inventory_type)
return yaml.safe_load(raw)
def read_item(self, inventory_type: str, item_id: str) -> dict[str, Any]:
data = self.read_parsed(inventory_type)
if not isinstance(data, list):
raise InventoryError("Inventory file does not contain a list")
for item in data:
if isinstance(item, dict) and item.get("id") == item_id:
return item
raise InventoryError("Inventory item not found")
def _path_for_type(self, inventory_type: str) -> Path:
if "/" in inventory_type or "\\" in inventory_type or inventory_type.startswith("."):
raise InventoryError("Invalid inventory type")
path = self.inventory_dir / f"{inventory_type}.yml"
if not path.is_file():
raise InventoryError("Inventory type not found")
return path