mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 00:07:10 +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: >
|
||||
This is not possible because the integrations generates entities
|
||||
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:
|
||||
status: done
|
||||
comment: |
|
||||
|
@ -12,7 +12,13 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.util.yaml import load_yaml_dict
|
||||
|
||||
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}
|
||||
|
||||
@ -32,7 +38,7 @@ ALL_RULES = [
|
||||
Rule("appropriate-polling", ScaledQualityScaleTiers.BRONZE),
|
||||
Rule("brands", 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("dependency-transparency", ScaledQualityScaleTiers.BRONZE),
|
||||
Rule("docs-actions", ScaledQualityScaleTiers.BRONZE),
|
||||
@ -57,7 +63,9 @@ ALL_RULES = [
|
||||
Rule("integration-owner", ScaledQualityScaleTiers.SILVER),
|
||||
Rule("log-when-unavailable", ScaledQualityScaleTiers.SILVER),
|
||||
Rule("parallel-updates", ScaledQualityScaleTiers.SILVER),
|
||||
Rule("reauthentication-flow", ScaledQualityScaleTiers.SILVER),
|
||||
Rule(
|
||||
"reauthentication-flow", ScaledQualityScaleTiers.SILVER, reauthentication_flow
|
||||
),
|
||||
Rule("test-coverage", ScaledQualityScaleTiers.SILVER),
|
||||
# GOLD: [
|
||||
Rule("devices", ScaledQualityScaleTiers.GOLD),
|
||||
@ -78,7 +86,7 @@ ALL_RULES = [
|
||||
Rule("entity-translations", ScaledQualityScaleTiers.GOLD),
|
||||
Rule("exception-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("stale-devices", ScaledQualityScaleTiers.GOLD),
|
||||
# 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
|
||||
|
||||
|
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