62 lines
1.6 KiB
Python
62 lines
1.6 KiB
Python
"""Enforce that the integration supports discovery.
|
|
|
|
https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/discovery/
|
|
"""
|
|
|
|
import ast
|
|
|
|
from script.hassfest import ast_parse_module
|
|
from script.hassfest.model import Config, Integration
|
|
|
|
MANIFEST_KEYS = [
|
|
"bluetooth",
|
|
"dhcp",
|
|
"homekit",
|
|
"mqtt",
|
|
"ssdp",
|
|
"usb",
|
|
"zeroconf",
|
|
]
|
|
CONFIG_FLOW_STEPS = {
|
|
"async_step_bluetooth",
|
|
"async_step_discovery",
|
|
"async_step_dhcp",
|
|
"async_step_hassio",
|
|
"async_step_homekit",
|
|
"async_step_mqtt",
|
|
"async_step_ssdp",
|
|
"async_step_usb",
|
|
"async_step_zeroconf",
|
|
}
|
|
|
|
|
|
def _has_discovery_function(module: ast.Module) -> bool:
|
|
"""Test if the module defines at least one of the discovery functions."""
|
|
return any(
|
|
type(item) is ast.AsyncFunctionDef and item.name in CONFIG_FLOW_STEPS
|
|
for item in ast.walk(module)
|
|
)
|
|
|
|
|
|
def validate(
|
|
config: Config, integration: Integration, *, rules_done: set[str]
|
|
) -> list[str] | None:
|
|
"""Validate that the integration implements diagnostics."""
|
|
|
|
config_flow_file = integration.path / "config_flow.py"
|
|
if not config_flow_file.exists():
|
|
return ["Integration is missing config_flow.py"]
|
|
|
|
# Check manifest
|
|
if any(key in integration.manifest for key in MANIFEST_KEYS):
|
|
return None
|
|
|
|
# Fallback => check config_flow step
|
|
config_flow = ast_parse_module(config_flow_file)
|
|
if not (_has_discovery_function(config_flow)):
|
|
return [
|
|
f"Integration is missing one of {CONFIG_FLOW_STEPS} in {config_flow_file}"
|
|
]
|
|
|
|
return None
|