"""Capability matcher helpers.""" from __future__ import annotations from fnmatch import fnmatch def _normalize_capability(capability: str) -> str: return capability.strip().lower() def capability_matches(granted: str, required: str) -> bool: granted = _normalize_capability(granted) required = _normalize_capability(required) if granted == required: return True # A granted wildcard such as "test.*" should match required "test.unit" if "*" in granted: return fnmatch(required, granted) # A required wildcard is treated as a suffix/prefix requirement for callers. if "*" in required: return fnmatch(granted, required) return False def has_capabilities(granted_caps: list[str], required_caps: list[str]) -> bool: granted = [_normalize_capability(c) for c in granted_caps] for required in required_caps: required = _normalize_capability(required) if not any(capability_matches(g, required) for g in granted): return False return True def normalize_capabilities(caps: list[str]) -> list[str]: return sorted({_normalize_capability(cap) for cap in caps})