Support in service descriptions for input sections (#116100)

This commit is contained in:
Erik Montnemery 2024-06-25 20:00:48 +02:00 committed by GitHub
parent c4b277b6ab
commit 75c7ae7c69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 198 additions and 95 deletions

View file

@ -26,6 +26,23 @@ def exists(value: Any) -> Any:
return value
def unique_field_validator(fields: Any) -> Any:
"""Validate the inputs don't have duplicate keys under different sections."""
all_fields = set()
for key, value in fields.items():
if value and "fields" in value:
for key in value["fields"]:
if key in all_fields:
raise vol.Invalid(f"Duplicate use of field {key} in service.")
all_fields.add(key)
else:
if key in all_fields:
raise vol.Invalid(f"Duplicate use of field {key} in service.")
all_fields.add(key)
return fields
CORE_INTEGRATION_FIELD_SCHEMA = vol.Schema(
{
vol.Optional("example"): exists,
@ -44,6 +61,13 @@ CORE_INTEGRATION_FIELD_SCHEMA = vol.Schema(
}
)
CORE_INTEGRATION_SECTION_SCHEMA = vol.Schema(
{
vol.Optional("collapsed"): bool,
vol.Required("fields"): vol.Schema({str: CORE_INTEGRATION_FIELD_SCHEMA}),
}
)
CUSTOM_INTEGRATION_FIELD_SCHEMA = CORE_INTEGRATION_FIELD_SCHEMA.extend(
{
vol.Optional("description"): str,
@ -57,7 +81,17 @@ CORE_INTEGRATION_SERVICE_SCHEMA = vol.Any(
vol.Optional("target"): vol.Any(
selector.TargetSelector.CONFIG_SCHEMA, None
),
vol.Optional("fields"): vol.Schema({str: CORE_INTEGRATION_FIELD_SCHEMA}),
vol.Optional("fields"): vol.All(
vol.Schema(
{
str: vol.Any(
CORE_INTEGRATION_FIELD_SCHEMA,
CORE_INTEGRATION_SECTION_SCHEMA,
)
}
),
unique_field_validator,
),
}
),
None,
@ -107,7 +141,7 @@ def grep_dir(path: pathlib.Path, glob_pattern: str, search_pattern: str) -> bool
return False
def validate_services(config: Config, integration: Integration) -> None:
def validate_services(config: Config, integration: Integration) -> None: # noqa: C901
"""Validate services."""
try:
data = load_yaml_dict(str(integration.path / "services.yaml"))
@ -200,6 +234,9 @@ def validate_services(config: Config, integration: Integration) -> None:
# The same check is done for the description in each of the fields of the
# service schema.
for field_name, field_schema in service_schema.get("fields", {}).items():
if "fields" in field_schema:
# This is a section
continue
if "name" not in field_schema:
try:
strings["services"][service_name]["fields"][field_name]["name"]
@ -233,6 +270,20 @@ def validate_services(config: Config, integration: Integration) -> None:
f"Service {service_name} has a field {field_name} with a selector with a translation key {translation_key} that is not in the translations file",
)
# The same check is done for the description in each of the sections of the
# service schema.
for section_name, section_schema in service_schema.get("fields", {}).items():
if "fields" not in section_schema:
# This is not a section
continue
try:
strings["services"][service_name]["sections"][section_name]["name"]
except KeyError:
integration.add_error(
"services",
f"Service {service_name} has a section {section_name} with no name {error_msg_suffix}",
)
def validate(integrations: dict[str, Integration], config: Config) -> None:
"""Handle dependencies for integrations."""