mirror of
https://github.com/home-assistant/core
synced 2024-10-05 05:11:50 +00:00
Move version validation to resolver (#51311)
This commit is contained in:
parent
95362d4215
commit
5d6b6deed4
|
@ -47,7 +47,7 @@ DATA_CUSTOM_COMPONENTS = "custom_components"
|
|||
PACKAGE_CUSTOM_COMPONENTS = "custom_components"
|
||||
PACKAGE_BUILTIN = "homeassistant.components"
|
||||
CUSTOM_WARNING = (
|
||||
"You are using a custom integration %s which has not "
|
||||
"We found a custom integration %s which has not "
|
||||
"been tested by Home Assistant. This component might "
|
||||
"cause stability problems, be sure to disable it if you "
|
||||
"experience issues with Home Assistant"
|
||||
|
@ -290,13 +290,39 @@ class Integration:
|
|||
)
|
||||
continue
|
||||
|
||||
return cls(
|
||||
integration = cls(
|
||||
hass,
|
||||
f"{root_module.__name__}.{domain}",
|
||||
manifest_path.parent,
|
||||
manifest,
|
||||
)
|
||||
|
||||
if integration.is_built_in:
|
||||
return integration
|
||||
|
||||
_LOGGER.warning(CUSTOM_WARNING, integration.domain)
|
||||
try:
|
||||
AwesomeVersion(
|
||||
integration.version,
|
||||
[
|
||||
AwesomeVersionStrategy.CALVER,
|
||||
AwesomeVersionStrategy.SEMVER,
|
||||
AwesomeVersionStrategy.SIMPLEVER,
|
||||
AwesomeVersionStrategy.BUILDVER,
|
||||
AwesomeVersionStrategy.PEP440,
|
||||
],
|
||||
)
|
||||
except AwesomeVersionException:
|
||||
_LOGGER.error(
|
||||
"The custom integration '%s' does not have a "
|
||||
"valid version key (%s) in the manifest file and was blocked from loading. "
|
||||
"See https://developers.home-assistant.io/blog/2021/01/29/custom-integration-changes#versions for more details",
|
||||
integration.domain,
|
||||
integration.version,
|
||||
)
|
||||
return None
|
||||
return integration
|
||||
|
||||
return None
|
||||
|
||||
def __init__(
|
||||
|
@ -523,8 +549,6 @@ async def _async_get_integration(hass: HomeAssistant, domain: str) -> Integratio
|
|||
# Instead of using resolve_from_root we use the cache of custom
|
||||
# components to find the integration.
|
||||
if integration := (await async_get_custom_components(hass)).get(domain):
|
||||
validate_custom_integration_version(integration)
|
||||
_LOGGER.warning(CUSTOM_WARNING, integration.domain)
|
||||
return integration
|
||||
|
||||
from homeassistant import components # pylint: disable=import-outside-toplevel
|
||||
|
@ -744,31 +768,3 @@ def _lookup_path(hass: HomeAssistant) -> list[str]:
|
|||
if hass.config.safe_mode:
|
||||
return [PACKAGE_BUILTIN]
|
||||
return [PACKAGE_CUSTOM_COMPONENTS, PACKAGE_BUILTIN]
|
||||
|
||||
|
||||
def validate_custom_integration_version(integration: Integration) -> None:
|
||||
"""
|
||||
Validate the version of custom integrations.
|
||||
|
||||
Raises IntegrationNotFound when version is missing or not valid
|
||||
"""
|
||||
try:
|
||||
AwesomeVersion(
|
||||
integration.version,
|
||||
[
|
||||
AwesomeVersionStrategy.CALVER,
|
||||
AwesomeVersionStrategy.SEMVER,
|
||||
AwesomeVersionStrategy.SIMPLEVER,
|
||||
AwesomeVersionStrategy.BUILDVER,
|
||||
AwesomeVersionStrategy.PEP440,
|
||||
],
|
||||
)
|
||||
except AwesomeVersionException:
|
||||
_LOGGER.error(
|
||||
"The custom integration '%s' does not have a "
|
||||
"valid version key (%s) in the manifest file and was blocked from loading. "
|
||||
"See https://developers.home-assistant.io/blog/2021/01/29/custom-integration-changes#versions for more details",
|
||||
integration.domain,
|
||||
integration.version,
|
||||
)
|
||||
raise IntegrationNotFound(integration.domain) from None
|
||||
|
|
|
@ -127,37 +127,30 @@ async def test_log_warning_custom_component(hass, caplog, enable_custom_integrat
|
|||
"""Test that we log a warning when loading a custom component."""
|
||||
|
||||
await loader.async_get_integration(hass, "test_package")
|
||||
assert "You are using a custom integration test_package" in caplog.text
|
||||
assert "We found a custom integration test_package" in caplog.text
|
||||
|
||||
await loader.async_get_integration(hass, "test")
|
||||
assert "You are using a custom integration test " in caplog.text
|
||||
assert "We found a custom integration test " in caplog.text
|
||||
|
||||
|
||||
async def test_custom_integration_version_not_valid(hass, caplog):
|
||||
async def test_custom_integration_version_not_valid(
|
||||
hass, caplog, enable_custom_integrations
|
||||
):
|
||||
"""Test that we log a warning when custom integrations have a invalid version."""
|
||||
test_integration1 = loader.Integration(
|
||||
hass, "custom_components.test", None, {"domain": "test1", "version": "test"}
|
||||
)
|
||||
test_integration2 = loader.Integration(
|
||||
hass, "custom_components.test", None, {"domain": "test2"}
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test_no_version")
|
||||
|
||||
assert (
|
||||
"The custom integration 'test_no_version' does not have a valid version key (None) in the manifest file and was blocked from loading."
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
with patch("homeassistant.loader.async_get_custom_components") as mock_get:
|
||||
mock_get.return_value = {"test1": test_integration1, "test2": test_integration2}
|
||||
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test1")
|
||||
assert (
|
||||
"The custom integration 'test1' does not have a valid version key (test) in the manifest file and was blocked from loading."
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test2")
|
||||
assert (
|
||||
"The custom integration 'test2' does not have a valid version key (None) in the manifest file and was blocked from loading."
|
||||
in caplog.text
|
||||
)
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test2")
|
||||
assert (
|
||||
"The custom integration 'test_bad_version' does not have a valid version key (bad) in the manifest file and was blocked from loading."
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
|
||||
async def test_get_integration(hass):
|
||||
|
@ -471,19 +464,11 @@ async def test_get_custom_components_safe_mode(hass):
|
|||
|
||||
async def test_custom_integration_missing_version(hass, caplog):
|
||||
"""Test trying to load a custom integration without a version twice does not deadlock."""
|
||||
test_integration_1 = loader.Integration(
|
||||
hass, "custom_components.test1", None, {"domain": "test1"}
|
||||
)
|
||||
with patch("homeassistant.loader.async_get_custom_components") as mock_get:
|
||||
mock_get.return_value = {
|
||||
"test1": test_integration_1,
|
||||
}
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test_no_version")
|
||||
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test1")
|
||||
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test1")
|
||||
with pytest.raises(loader.IntegrationNotFound):
|
||||
await loader.async_get_integration(hass, "test_no_version")
|
||||
|
||||
|
||||
async def test_custom_integration_missing(hass, caplog):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Provide a mock integration."""
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"domain": "test_bad_version",
|
||||
"version": "bad"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
"""Provide a mock integration."""
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"domain": "test_no_version"
|
||||
}
|
Loading…
Reference in a new issue