diff --git a/homeassistant/components/airgradient/quality_scale.yaml b/homeassistant/components/airgradient/quality_scale.yaml new file mode 100644 index 00000000000..d244807a656 --- /dev/null +++ b/homeassistant/components/airgradient/quality_scale.yaml @@ -0,0 +1,2 @@ +rules: + IQS001: done diff --git a/script/hassfest/__main__.py b/script/hassfest/__main__.py index f0b9ad25dd0..81670de5afd 100644 --- a/script/hassfest/__main__.py +++ b/script/hassfest/__main__.py @@ -23,6 +23,7 @@ from . import ( metadata, mqtt, mypy_config, + quality_scale, requirements, services, ssdp, @@ -43,6 +44,7 @@ INTEGRATION_PLUGINS = [ json, manifest, mqtt, + quality_scale, requirements, services, ssdp, diff --git a/script/hassfest/quality_scale.py b/script/hassfest/quality_scale.py new file mode 100644 index 00000000000..9fe99b922af --- /dev/null +++ b/script/hassfest/quality_scale.py @@ -0,0 +1,57 @@ +"""Validate integration quality scale files.""" + +from __future__ import annotations + +import voluptuous as vol +from voluptuous.humanize import humanize_error + +from homeassistant.exceptions import HomeAssistantError +from homeassistant.util.yaml import load_yaml_dict + +from .model import Config, Integration + +SCHEMA = vol.Schema( + { + vol.Required("rules"): vol.Schema( + { + str: vol.Any( + vol.In(["todo", "done"]), + vol.Schema( + { + vol.Required("status"): vol.In(["todo", "done", "exempt"]), + vol.Optional("comment"): str, + } + ), + ) + } + ) + } +) + + +def validate_iqs_file(config: Config, integration: Integration) -> None: + """Validate quality scale file for integration.""" + iqs_file = integration.path / "quality_scale.yaml" + if not iqs_file.is_file(): + return + + name = str(iqs_file) + + try: + data = load_yaml_dict(name) + except HomeAssistantError: + integration.add_error("quality_scale", "Invalid quality_scale.yaml") + return + + try: + SCHEMA(data) + except vol.Invalid as err: + integration.add_error( + "quality_scale", f"Invalid {name}: {humanize_error(data, err)}" + ) + + +def validate(integrations: dict[str, Integration], config: Config) -> None: + """Handle YAML files inside integrations.""" + for integration in integrations.values(): + validate_iqs_file(config, integration)