Add version to hassfest for custom integrations (#45523)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Joakim Sørensen 2021-01-25 13:31:14 +01:00 committed by GitHub
parent 1c0a74f18a
commit edfb8c3423
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 4 deletions

View File

@ -13,6 +13,7 @@ pre-commit==2.9.3
pylint==2.6.0 pylint==2.6.0
astroid==2.4.2 astroid==2.4.2
pipdeptree==1.0.0 pipdeptree==1.0.0
awesomeversion==21.1.3
pylint-strict-informational==0.1 pylint-strict-informational==0.1
pytest-aiohttp==0.3.0 pytest-aiohttp==0.3.0
pytest-cov==2.10.1 pytest-cov==2.10.1

View File

@ -183,7 +183,7 @@ def print_integrations_status(config, integrations, *, show_fixable_errors=True)
print(f"Integration {integration.domain}{extra}:") print(f"Integration {integration.domain}{extra}:")
for error in integration.errors: for error in integration.errors:
if show_fixable_errors or not error.fixable: if show_fixable_errors or not error.fixable:
print("*", error) print("*", "[ERROR]", error)
for warning in integration.warnings: for warning in integration.warnings:
print("*", "[WARNING]", warning) print("*", "[WARNING]", warning)
print() print()

View File

@ -2,6 +2,8 @@
from typing import Dict from typing import Dict
from urllib.parse import urlparse from urllib.parse import urlparse
from awesomeversion import AwesomeVersion
from awesomeversion.strategy import AwesomeVersionStrategy
import voluptuous as vol import voluptuous as vol
from voluptuous.humanize import humanize_error from voluptuous.humanize import humanize_error
@ -49,6 +51,21 @@ def verify_uppercase(value: str):
return value return value
def verify_version(value: str):
"""Verify the version."""
version = AwesomeVersion(value)
if version.strategy not in [
AwesomeVersionStrategy.CALVER,
AwesomeVersionStrategy.SEMVER,
AwesomeVersionStrategy.SIMPLEVER,
AwesomeVersionStrategy.BUILDVER,
]:
raise vol.Invalid(
f"'{version}' is not a valid version. This will cause a future version of Home Assistant to block this integration.",
)
return value
MANIFEST_SCHEMA = vol.Schema( MANIFEST_SCHEMA = vol.Schema(
{ {
vol.Required("domain"): str, vol.Required("domain"): str,
@ -94,21 +111,45 @@ MANIFEST_SCHEMA = vol.Schema(
} }
) )
CUSTOM_INTEGRATION_MANIFEST_SCHEMA = MANIFEST_SCHEMA.extend(
{
vol.Optional("version"): vol.All(str, verify_version),
}
)
def validate_version(integration: Integration):
"""
Validate the version of the integration.
Will be removed when the version key is no longer optional for custom integrations.
"""
if not integration.manifest.get("version"):
integration.add_warning(
"manifest",
"No 'version' key in the manifest file. This will cause a future version of Home Assistant to block this integration.",
)
return
def validate_manifest(integration: Integration): def validate_manifest(integration: Integration):
"""Validate manifest.""" """Validate manifest."""
try: try:
if integration.core:
MANIFEST_SCHEMA(integration.manifest) MANIFEST_SCHEMA(integration.manifest)
else:
CUSTOM_INTEGRATION_MANIFEST_SCHEMA(integration.manifest)
except vol.Invalid as err: except vol.Invalid as err:
integration.add_error( integration.add_error(
"manifest", f"Invalid manifest: {humanize_error(integration.manifest, err)}" "manifest", f"Invalid manifest: {humanize_error(integration.manifest, err)}"
) )
integration.manifest = None
return
if integration.manifest["domain"] != integration.path.name: if integration.manifest["domain"] != integration.path.name:
integration.add_error("manifest", "Domain does not match dir name") integration.add_error("manifest", "Domain does not match dir name")
if not integration.core:
validate_version(integration)
def validate(integrations: Dict[str, Integration], config): def validate(integrations: Dict[str, Integration], config):
"""Handle all integrations manifests.""" """Handle all integrations manifests."""

View File

@ -74,6 +74,11 @@ class Integration:
"""Integration domain.""" """Integration domain."""
return self.path.name return self.path.name
@property
def core(self) -> bool:
"""Core integration."""
return self.path.as_posix().startswith("homeassistant/components")
@property @property
def disabled(self) -> Optional[str]: def disabled(self) -> Optional[str]:
"""List of disabled.""" """List of disabled."""