mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 08:17:08 +00:00
Add config flow rules to quality_scale hassfest validation (#131791)
* Add config flow rules to quality_scale hassfest validation * Use integration.config_flow property
This commit is contained in:
parent
bbce183faf
commit
62e788c7da
@ -86,7 +86,10 @@ rules:
|
|||||||
comment: >
|
comment: >
|
||||||
This is not possible because the integrations generates entities
|
This is not possible because the integrations generates entities
|
||||||
based on a user supplied config or discovery.
|
based on a user supplied config or discovery.
|
||||||
reconfiguration-flow: done
|
reconfiguration-flow:
|
||||||
|
status: exempt
|
||||||
|
comment: >
|
||||||
|
This integration is reconfigured via options flow.
|
||||||
dynamic-devices:
|
dynamic-devices:
|
||||||
status: done
|
status: done
|
||||||
comment: |
|
comment: |
|
||||||
|
@ -12,7 +12,13 @@ from homeassistant.exceptions import HomeAssistantError
|
|||||||
from homeassistant.util.yaml import load_yaml_dict
|
from homeassistant.util.yaml import load_yaml_dict
|
||||||
|
|
||||||
from .model import Config, Integration, ScaledQualityScaleTiers
|
from .model import Config, Integration, ScaledQualityScaleTiers
|
||||||
from .quality_scale_validation import RuleValidationProtocol, config_entry_unloading
|
from .quality_scale_validation import (
|
||||||
|
RuleValidationProtocol,
|
||||||
|
config_entry_unloading,
|
||||||
|
config_flow,
|
||||||
|
reauthentication_flow,
|
||||||
|
reconfiguration_flow,
|
||||||
|
)
|
||||||
|
|
||||||
QUALITY_SCALE_TIERS = {value.name.lower(): value for value in ScaledQualityScaleTiers}
|
QUALITY_SCALE_TIERS = {value.name.lower(): value for value in ScaledQualityScaleTiers}
|
||||||
|
|
||||||
@ -32,7 +38,7 @@ ALL_RULES = [
|
|||||||
Rule("appropriate-polling", ScaledQualityScaleTiers.BRONZE),
|
Rule("appropriate-polling", ScaledQualityScaleTiers.BRONZE),
|
||||||
Rule("brands", ScaledQualityScaleTiers.BRONZE),
|
Rule("brands", ScaledQualityScaleTiers.BRONZE),
|
||||||
Rule("common-modules", ScaledQualityScaleTiers.BRONZE),
|
Rule("common-modules", ScaledQualityScaleTiers.BRONZE),
|
||||||
Rule("config-flow", ScaledQualityScaleTiers.BRONZE),
|
Rule("config-flow", ScaledQualityScaleTiers.BRONZE, config_flow),
|
||||||
Rule("config-flow-test-coverage", ScaledQualityScaleTiers.BRONZE),
|
Rule("config-flow-test-coverage", ScaledQualityScaleTiers.BRONZE),
|
||||||
Rule("dependency-transparency", ScaledQualityScaleTiers.BRONZE),
|
Rule("dependency-transparency", ScaledQualityScaleTiers.BRONZE),
|
||||||
Rule("docs-actions", ScaledQualityScaleTiers.BRONZE),
|
Rule("docs-actions", ScaledQualityScaleTiers.BRONZE),
|
||||||
@ -57,7 +63,9 @@ ALL_RULES = [
|
|||||||
Rule("integration-owner", ScaledQualityScaleTiers.SILVER),
|
Rule("integration-owner", ScaledQualityScaleTiers.SILVER),
|
||||||
Rule("log-when-unavailable", ScaledQualityScaleTiers.SILVER),
|
Rule("log-when-unavailable", ScaledQualityScaleTiers.SILVER),
|
||||||
Rule("parallel-updates", ScaledQualityScaleTiers.SILVER),
|
Rule("parallel-updates", ScaledQualityScaleTiers.SILVER),
|
||||||
Rule("reauthentication-flow", ScaledQualityScaleTiers.SILVER),
|
Rule(
|
||||||
|
"reauthentication-flow", ScaledQualityScaleTiers.SILVER, reauthentication_flow
|
||||||
|
),
|
||||||
Rule("test-coverage", ScaledQualityScaleTiers.SILVER),
|
Rule("test-coverage", ScaledQualityScaleTiers.SILVER),
|
||||||
# GOLD: [
|
# GOLD: [
|
||||||
Rule("devices", ScaledQualityScaleTiers.GOLD),
|
Rule("devices", ScaledQualityScaleTiers.GOLD),
|
||||||
@ -78,7 +86,7 @@ ALL_RULES = [
|
|||||||
Rule("entity-translations", ScaledQualityScaleTiers.GOLD),
|
Rule("entity-translations", ScaledQualityScaleTiers.GOLD),
|
||||||
Rule("exception-translations", ScaledQualityScaleTiers.GOLD),
|
Rule("exception-translations", ScaledQualityScaleTiers.GOLD),
|
||||||
Rule("icon-translations", ScaledQualityScaleTiers.GOLD),
|
Rule("icon-translations", ScaledQualityScaleTiers.GOLD),
|
||||||
Rule("reconfiguration-flow", ScaledQualityScaleTiers.GOLD),
|
Rule("reconfiguration-flow", ScaledQualityScaleTiers.GOLD, reconfiguration_flow),
|
||||||
Rule("repair-issues", ScaledQualityScaleTiers.GOLD),
|
Rule("repair-issues", ScaledQualityScaleTiers.GOLD),
|
||||||
Rule("stale-devices", ScaledQualityScaleTiers.GOLD),
|
Rule("stale-devices", ScaledQualityScaleTiers.GOLD),
|
||||||
# PLATINUM
|
# PLATINUM
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
"""Enforce that the integration implements entry unloading."""
|
"""Enforce that the integration implements entry unloading.
|
||||||
|
|
||||||
|
https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/config-entry-unloading/
|
||||||
|
"""
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
|
|
||||||
|
24
script/hassfest/quality_scale_validation/config_flow.py
Normal file
24
script/hassfest/quality_scale_validation/config_flow.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
"""Enforce that the integration implements config flow.
|
||||||
|
|
||||||
|
https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/config-flow/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from script.hassfest.model import Integration
|
||||||
|
|
||||||
|
|
||||||
|
def validate(integration: Integration) -> list[str] | None:
|
||||||
|
"""Validate that the integration implements config flow."""
|
||||||
|
|
||||||
|
if not integration.config_flow:
|
||||||
|
return [
|
||||||
|
"Integration does not set config_flow in its manifest "
|
||||||
|
f"homeassistant/components/{integration.domain}/manifest.json",
|
||||||
|
]
|
||||||
|
|
||||||
|
config_flow_file = integration.path / "config_flow.py"
|
||||||
|
if not config_flow_file.exists():
|
||||||
|
return [
|
||||||
|
"Integration does not implement config flow (is missing config_flow.py)",
|
||||||
|
]
|
||||||
|
|
||||||
|
return None
|
@ -0,0 +1,30 @@
|
|||||||
|
"""Enforce that the integration implements reauthentication flow.
|
||||||
|
|
||||||
|
https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/reauthentication-flow/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
|
||||||
|
from script.hassfest.model import Integration
|
||||||
|
|
||||||
|
|
||||||
|
def _has_async_function(module: ast.Module, name: str) -> bool:
|
||||||
|
"""Test if the module defines a function."""
|
||||||
|
return any(
|
||||||
|
type(item) is ast.AsyncFunctionDef and item.name == name
|
||||||
|
for item in ast.walk(module)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate(integration: Integration) -> list[str] | None:
|
||||||
|
"""Validate that the integration has a reauthentication flow."""
|
||||||
|
|
||||||
|
config_flow_file = integration.path / "config_flow.py"
|
||||||
|
config_flow = ast.parse(config_flow_file.read_text())
|
||||||
|
|
||||||
|
if not _has_async_function(config_flow, "async_step_reauth"):
|
||||||
|
return [
|
||||||
|
"Integration does not support a reauthentication flow "
|
||||||
|
f"(is missing `async_step_reauth` in {config_flow_file})"
|
||||||
|
]
|
||||||
|
return None
|
@ -0,0 +1,30 @@
|
|||||||
|
"""Enforce that the integration implements reconfiguration flow.
|
||||||
|
|
||||||
|
https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/reconfiguration-flow/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
|
||||||
|
from script.hassfest.model import Integration
|
||||||
|
|
||||||
|
|
||||||
|
def _has_async_function(module: ast.Module, name: str) -> bool:
|
||||||
|
"""Test if the module defines a function."""
|
||||||
|
return any(
|
||||||
|
type(item) is ast.AsyncFunctionDef and item.name == name
|
||||||
|
for item in ast.walk(module)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate(integration: Integration) -> list[str] | None:
|
||||||
|
"""Validate that the integration has a reconfiguration flow."""
|
||||||
|
|
||||||
|
config_flow_file = integration.path / "config_flow.py"
|
||||||
|
config_flow = ast.parse(config_flow_file.read_text())
|
||||||
|
|
||||||
|
if not _has_async_function(config_flow, "async_step_reconfigure"):
|
||||||
|
return [
|
||||||
|
"Integration does not support a reconfiguration flow "
|
||||||
|
f"(is missing `async_step_reconfigure` in {config_flow_file})"
|
||||||
|
]
|
||||||
|
return None
|
Loading…
x
Reference in New Issue
Block a user