import logging from clan_lib.api import API from clan_lib.errors import ClanError from clan_lib.flake import Flake from clan_lib.machines.actions import FieldSchema from clan_lib.nix_models.clan import InventoryMeta from clan_lib.persist.introspection import retrieve_typed_field_names from clan_lib.persist.inventory_store import InventoryStore from clan_lib.persist.write_rules import is_readonly_key log = logging.getLogger(__name__) @API.register def get_clan_details(flake: Flake) -> InventoryMeta: """Retrieve the clan details from the inventory of a given flake. Args: flake: The Flake instance representing the clan. Returns: InventoryMeta: The meta information from the clan's inventory. Raises: ClanError: If the flake does not exist, or if the inventory is invalid (missing the meta attribute). """ inventory_store = InventoryStore(flake) inventory = inventory_store.read() meta = inventory.get("meta") if not meta: msg = f"Inventory of flake '{flake}' does not have a meta attribute" raise ClanError(msg) return meta @API.register def get_clan_details_schema(flake: Flake) -> dict[str, FieldSchema]: """Get attributes for each field of the clan. This function checks which fields of the 'clan' resource are readonly and provides a reason if so. Args: flake (Flake): The Flake object for which to retrieve fields. Returns: dict[str, FieldSchema]: A map from field-names to { 'readonly' (bool) and 'reason' (str or None ) } """ inventory_store = InventoryStore(flake) attribute_props = inventory_store.get_attribute_props() field_names = retrieve_typed_field_names(InventoryMeta) return { field: { "readonly": is_readonly_key(f"meta.{field}", attribute_props), # TODO: Provide a meaningful reason "reason": None, "readonly_members": [], } for field in field_names }