diff --git a/homeassistant/components/solarlog/manifest.json b/homeassistant/components/solarlog/manifest.json index 9331628e027..b626da456a9 100644 --- a/homeassistant/components/solarlog/manifest.json +++ b/homeassistant/components/solarlog/manifest.json @@ -2,7 +2,7 @@ "domain": "solarlog", "name": "Solar-Log", "config_flow": true, - "documentation": "https://www.home-assistant.io/integration/solarlog", + "documentation": "https://www.home-assistant.io/integrations/solarlog", "dependencies": [], "codeowners": ["@Ernst79"], "requirements": ["sunwatcher==0.2.1"] diff --git a/script/hassfest/manifest.py b/script/hassfest/manifest.py index 2166830d9e4..7852953dc92 100644 --- a/script/hassfest/manifest.py +++ b/script/hassfest/manifest.py @@ -1,11 +1,17 @@ """Manifest validation.""" from typing import Dict +from urllib.parse import urlparse import voluptuous as vol from voluptuous.humanize import humanize_error from .model import Integration +DOCUMENTATION_URL_SCHEMA = "https" +DOCUMENTATION_URL_HOST = "www.home-assistant.io" +DOCUMENTATION_URL_PATH_PREFIX = "/integrations/" +DOCUMENTATION_URL_EXCEPTIONS = ["https://www.home-assistant.io/hassio"] + SUPPORTED_QUALITY_SCALES = [ "gold", "internal", @@ -13,6 +19,25 @@ SUPPORTED_QUALITY_SCALES = [ "silver", ] + +def documentation_url(value: str) -> str: + """Validate that a documentation url has the correct path and domain.""" + if value in DOCUMENTATION_URL_EXCEPTIONS: + return value + + parsed_url = urlparse(value) + if not parsed_url.scheme == DOCUMENTATION_URL_SCHEMA: + raise vol.Invalid("Documentation url is not prefixed with https") + if not parsed_url.netloc == DOCUMENTATION_URL_HOST: + raise vol.Invalid("Documentation url not hosted at www.home-assistant.io") + if not parsed_url.path.startswith(DOCUMENTATION_URL_PATH_PREFIX): + raise vol.Invalid( + "Documentation url does not begin with www.home-assistant.io/integrations" + ) + + return value + + MANIFEST_SCHEMA = vol.Schema( { vol.Required("domain"): str, @@ -23,9 +48,9 @@ MANIFEST_SCHEMA = vol.Schema( vol.All([vol.All(vol.Schema({}, extra=vol.ALLOW_EXTRA), vol.Length(min=1))]) ), vol.Optional("homekit"): vol.Schema({vol.Optional("models"): [str]}), - vol.Required( - "documentation" - ): vol.Url(), # pylint: disable=no-value-for-parameter + vol.Required("documentation"): vol.All( + vol.Url(), documentation_url # pylint: disable=no-value-for-parameter + ), vol.Optional("quality_scale"): vol.In(SUPPORTED_QUALITY_SCALES), vol.Required("requirements"): [str], vol.Required("dependencies"): [str],