diff --git a/homeassistant/components/fyta/quality_scale.yaml b/homeassistant/components/fyta/quality_scale.yaml index 97f62f884e7..0fbacd0e12e 100644 --- a/homeassistant/components/fyta/quality_scale.yaml +++ b/homeassistant/components/fyta/quality_scale.yaml @@ -53,8 +53,8 @@ rules: status: exempt comment: No noisy entities. discovery: - status: exempt - comment: bug in hassfest + status: done + comment: DHCP stale-devices: done diagnostics: done exception-translations: done diff --git a/homeassistant/components/powerfox/quality_scale.yaml b/homeassistant/components/powerfox/quality_scale.yaml index 5a14264940f..7e104b894ca 100644 --- a/homeassistant/components/powerfox/quality_scale.yaml +++ b/homeassistant/components/powerfox/quality_scale.yaml @@ -57,9 +57,9 @@ rules: comment: | This integration is connecting to a cloud service. discovery: - status: exempt + status: done comment: | - It can find poweropti devices via zeroconf, but will start a normal user flow. + It can find poweropti devices via zeroconf, and will start a normal user flow. docs-data-update: done docs-examples: todo docs-known-limitations: done diff --git a/script/hassfest/quality_scale_validation/discovery.py b/script/hassfest/quality_scale_validation/discovery.py index a4f01ce0269..d24005b6373 100644 --- a/script/hassfest/quality_scale_validation/discovery.py +++ b/script/hassfest/quality_scale_validation/discovery.py @@ -7,23 +7,32 @@ import ast from script.hassfest.model import Integration -DISCOVERY_FUNCTIONS = [ - "async_step_discovery", +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_zeroconf", - "async_step_dhcp", "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 DISCOVERY_FUNCTIONS + type(item) is ast.AsyncFunctionDef and item.name in CONFIG_FLOW_STEPS for item in ast.walk(module) ) @@ -35,11 +44,15 @@ def validate(integration: Integration) -> list[str] | None: if not config_flow_file.exists(): return ["Integration is missing config_flow.py"] - config_flow = ast.parse(config_flow_file.read_text()) + # Check manifest + if any(key in integration.manifest for key in MANIFEST_KEYS): + return None - if not _has_discovery_function(config_flow): + # Fallback => check config_flow step + config_flow = ast.parse(config_flow_file.read_text()) + if not (_has_discovery_function(config_flow)): return [ - f"Integration is missing one of {DISCOVERY_FUNCTIONS} " + f"Integration is missing one of {CONFIG_FLOW_STEPS} " f"in {config_flow_file}" ]