intermittent commit

This commit is contained in:
2026-07-14 13:22:11 +02:00
parent ec748e3fcf
commit f2ade1d624
4 changed files with 217 additions and 25 deletions

View File

@@ -356,42 +356,117 @@ def _condition_visibility(
registry: PlatformRegistry,
principal: ApiPrincipal,
) -> tuple[bool, str, dict[str, list[str]]]:
blockers = {"modules": [], "capabilities": [], "scopes": []}
missing_required_modules = [module_id for module_id in condition.required_modules if module_id not in installed]
if missing_required_modules:
blockers["modules"].extend(missing_required_modules)
if condition.any_modules and not any(module_id in installed for module_id in condition.any_modules):
blockers["modules"].extend(module_id for module_id in condition.any_modules if module_id not in blockers["modules"])
conflicting_modules = [module_id for module_id in condition.missing_modules if module_id in installed]
if conflicting_modules:
blockers["modules"].extend(conflicting_modules)
missing_capabilities = [name for name in condition.required_capabilities if not registry.has_capability(name)]
if missing_capabilities:
blockers["capabilities"].extend(missing_capabilities)
missing_scopes = [scope for scope in condition.required_scopes if not has_scope(principal, scope)]
missing_any_scopes = list(condition.any_scopes) if condition.any_scopes and not any(has_scope(principal, scope) for scope in condition.any_scopes) else []
if missing_scopes:
blockers["scopes"].extend(missing_scopes)
if missing_any_scopes:
blockers["scopes"].extend(scope for scope in missing_any_scopes if scope not in blockers["scopes"])
missing_required_modules = _missing_required_modules(condition, installed)
unsatisfied_any_modules = _unsatisfied_any_modules(condition, installed)
conflicting_modules = _conflicting_modules(condition, installed)
missing_capabilities = _missing_required_capabilities(condition, registry)
missing_scopes = _missing_required_scopes(condition, principal)
unsatisfied_any_scopes = _unsatisfied_any_scopes(condition, principal)
blockers = _condition_blockers(
missing_required_modules=missing_required_modules,
unsatisfied_any_modules=unsatisfied_any_modules,
conflicting_modules=conflicting_modules,
missing_capabilities=missing_capabilities,
missing_scopes=missing_scopes,
unsatisfied_any_scopes=unsatisfied_any_scopes,
)
if not blockers["modules"] and not blockers["capabilities"] and not blockers["scopes"]:
if _condition_has_no_blockers(blockers):
return True, "conditions satisfied", blockers
reason = _condition_blocker_reason(
missing_required_modules=missing_required_modules,
unsatisfied_any_modules=unsatisfied_any_modules,
conflicting_modules=conflicting_modules,
missing_capabilities=missing_capabilities,
missing_scopes=missing_scopes,
unsatisfied_any_scopes=unsatisfied_any_scopes,
)
return False, reason, blockers
def _missing_required_modules(condition: DocumentationCondition, installed: set[str]) -> list[str]:
return [module_id for module_id in condition.required_modules if module_id not in installed]
def _unsatisfied_any_modules(condition: DocumentationCondition, installed: set[str]) -> list[str]:
if not condition.any_modules:
return []
if any(module_id in installed for module_id in condition.any_modules):
return []
return list(condition.any_modules)
def _conflicting_modules(condition: DocumentationCondition, installed: set[str]) -> list[str]:
return [module_id for module_id in condition.missing_modules if module_id in installed]
def _missing_required_capabilities(condition: DocumentationCondition, registry: PlatformRegistry) -> list[str]:
return [name for name in condition.required_capabilities if not registry.has_capability(name)]
def _missing_required_scopes(condition: DocumentationCondition, principal: ApiPrincipal) -> list[str]:
return [scope for scope in condition.required_scopes if not has_scope(principal, scope)]
def _unsatisfied_any_scopes(condition: DocumentationCondition, principal: ApiPrincipal) -> list[str]:
if not condition.any_scopes:
return []
if any(has_scope(principal, scope) for scope in condition.any_scopes):
return []
return list(condition.any_scopes)
def _condition_blockers(
*,
missing_required_modules: list[str],
unsatisfied_any_modules: list[str],
conflicting_modules: list[str],
missing_capabilities: list[str],
missing_scopes: list[str],
unsatisfied_any_scopes: list[str],
) -> dict[str, list[str]]:
blockers = {"modules": [], "capabilities": [], "scopes": []}
_extend_unique(blockers["modules"], missing_required_modules)
_extend_unique(blockers["modules"], unsatisfied_any_modules)
_extend_unique(blockers["modules"], conflicting_modules)
_extend_unique(blockers["capabilities"], missing_capabilities)
_extend_unique(blockers["scopes"], missing_scopes)
_extend_unique(blockers["scopes"], unsatisfied_any_scopes)
return blockers
def _extend_unique(target: list[str], values: list[str]) -> None:
target.extend(value for value in values if value not in target)
def _condition_has_no_blockers(blockers: dict[str, list[str]]) -> bool:
return not blockers["modules"] and not blockers["capabilities"] and not blockers["scopes"]
def _condition_blocker_reason(
*,
missing_required_modules: list[str],
unsatisfied_any_modules: list[str],
conflicting_modules: list[str],
missing_capabilities: list[str],
missing_scopes: list[str],
unsatisfied_any_scopes: list[str],
) -> str:
parts: list[str] = []
if missing_required_modules:
parts.append("missing modules: " + ", ".join(missing_required_modules))
if condition.any_modules and not any(module_id in installed for module_id in condition.any_modules):
parts.append("requires one installed module from: " + ", ".join(condition.any_modules))
if unsatisfied_any_modules:
parts.append("requires one installed module from: " + ", ".join(unsatisfied_any_modules))
if conflicting_modules:
parts.append("not active when installed: " + ", ".join(conflicting_modules))
if missing_capabilities:
parts.append("missing capabilities: " + ", ".join(missing_capabilities))
if missing_scopes:
parts.append("missing scopes: " + ", ".join(missing_scopes))
if missing_any_scopes:
parts.append("requires one scope from: " + ", ".join(missing_any_scopes))
return False, "; ".join(parts), blockers
if unsatisfied_any_scopes:
parts.append("requires one scope from: " + ", ".join(unsatisfied_any_scopes))
return "; ".join(parts)
def _documentation_target_layer(topic: DocumentationTopic, active: bool, blockers: dict[str, list[str]]) -> str: