Move issue_registry to homeassistant.helpers (#77299)
* Move issue_registry to homeassistant.helpers * Add backwards compatibility
This commit is contained in:
parent
79ab794e6a
commit
dfed3ba75e
10 changed files with 174 additions and 159 deletions
|
@ -24,7 +24,13 @@ from .const import (
|
|||
SIGNAL_BOOTSTRAP_INTEGRATONS,
|
||||
)
|
||||
from .exceptions import HomeAssistantError
|
||||
from .helpers import area_registry, device_registry, entity_registry, recorder
|
||||
from .helpers import (
|
||||
area_registry,
|
||||
device_registry,
|
||||
entity_registry,
|
||||
issue_registry,
|
||||
recorder,
|
||||
)
|
||||
from .helpers.dispatcher import async_dispatcher_send
|
||||
from .helpers.typing import ConfigType
|
||||
from .setup import (
|
||||
|
@ -521,9 +527,10 @@ async def _async_set_up_integrations(
|
|||
|
||||
# Load the registries and cache the result of platform.uname().processor
|
||||
await asyncio.gather(
|
||||
area_registry.async_load(hass),
|
||||
device_registry.async_load(hass),
|
||||
entity_registry.async_load(hass),
|
||||
area_registry.async_load(hass),
|
||||
issue_registry.async_load(hass),
|
||||
hass.async_add_executor_job(_cache_uname_processor),
|
||||
)
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from . import issue_handler, websocket_api
|
||||
from .const import DOMAIN
|
||||
from .issue_handler import (
|
||||
ConfirmRepairFlow,
|
||||
from homeassistant.helpers.issue_registry import (
|
||||
IssueSeverity,
|
||||
async_create_issue,
|
||||
async_delete_issue,
|
||||
create_issue,
|
||||
delete_issue,
|
||||
)
|
||||
from .issue_registry import async_load as async_load_issue_registry
|
||||
from .models import IssueSeverity, RepairsFlow
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from . import issue_handler, websocket_api
|
||||
from .const import DOMAIN
|
||||
from .issue_handler import ConfirmRepairFlow
|
||||
from .models import RepairsFlow
|
||||
|
||||
__all__ = [
|
||||
"async_create_issue",
|
||||
|
@ -34,6 +34,5 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
|
||||
issue_handler.async_setup(hass)
|
||||
websocket_api.async_setup(hass)
|
||||
await async_load_issue_registry(hass)
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
"""The repairs integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
import functools as ft
|
||||
from typing import Any
|
||||
|
||||
from awesomeversion import AwesomeVersion, AwesomeVersionStrategy
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
|
@ -13,11 +11,16 @@ from homeassistant.exceptions import HomeAssistantError
|
|||
from homeassistant.helpers.integration_platform import (
|
||||
async_process_integration_platforms,
|
||||
)
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
|
||||
# pylint: disable-next=unused-import
|
||||
from homeassistant.helpers.issue_registry import ( # noqa: F401; Remove when integrations have been updated
|
||||
async_create_issue,
|
||||
async_delete_issue,
|
||||
async_get as async_get_issue_registry,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .issue_registry import async_get as async_get_issue_registry
|
||||
from .models import IssueSeverity, RepairsFlow, RepairsProtocol
|
||||
from .models import RepairsFlow, RepairsProtocol
|
||||
|
||||
|
||||
class ConfirmRepairFlow(RepairsFlow):
|
||||
|
@ -111,112 +114,3 @@ async def _register_repairs_platform(
|
|||
if not hasattr(platform, "async_create_fix_flow"):
|
||||
raise HomeAssistantError(f"Invalid repairs platform {platform}")
|
||||
hass.data[DOMAIN]["platforms"][integration_domain] = platform
|
||||
|
||||
|
||||
@callback
|
||||
def async_create_issue(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
issue_id: str,
|
||||
*,
|
||||
breaks_in_ha_version: str | None = None,
|
||||
data: dict[str, str | int | float | None] | None = None,
|
||||
is_fixable: bool,
|
||||
is_persistent: bool = False,
|
||||
issue_domain: str | None = None,
|
||||
learn_more_url: str | None = None,
|
||||
severity: IssueSeverity,
|
||||
translation_key: str,
|
||||
translation_placeholders: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
"""Create an issue, or replace an existing one."""
|
||||
# Verify the breaks_in_ha_version is a valid version string
|
||||
if breaks_in_ha_version:
|
||||
AwesomeVersion(
|
||||
breaks_in_ha_version,
|
||||
ensure_strategy=AwesomeVersionStrategy.CALVER,
|
||||
find_first_match=False,
|
||||
)
|
||||
|
||||
issue_registry = async_get_issue_registry(hass)
|
||||
issue_registry.async_get_or_create(
|
||||
domain,
|
||||
issue_id,
|
||||
breaks_in_ha_version=breaks_in_ha_version,
|
||||
data=data,
|
||||
is_fixable=is_fixable,
|
||||
is_persistent=is_persistent,
|
||||
issue_domain=issue_domain,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=severity,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=translation_placeholders,
|
||||
)
|
||||
|
||||
|
||||
def create_issue(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
issue_id: str,
|
||||
*,
|
||||
breaks_in_ha_version: str | None = None,
|
||||
data: dict[str, str | int | float | None] | None = None,
|
||||
is_fixable: bool,
|
||||
is_persistent: bool = False,
|
||||
issue_domain: str | None = None,
|
||||
learn_more_url: str | None = None,
|
||||
severity: IssueSeverity,
|
||||
translation_key: str,
|
||||
translation_placeholders: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
"""Create an issue, or replace an existing one."""
|
||||
return run_callback_threadsafe(
|
||||
hass.loop,
|
||||
ft.partial(
|
||||
async_create_issue,
|
||||
hass,
|
||||
domain,
|
||||
issue_id,
|
||||
breaks_in_ha_version=breaks_in_ha_version,
|
||||
data=data,
|
||||
is_fixable=is_fixable,
|
||||
is_persistent=is_persistent,
|
||||
issue_domain=issue_domain,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=severity,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=translation_placeholders,
|
||||
),
|
||||
).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_delete_issue(hass: HomeAssistant, domain: str, issue_id: str) -> None:
|
||||
"""Delete an issue.
|
||||
|
||||
It is not an error to delete an issue that does not exist.
|
||||
"""
|
||||
issue_registry = async_get_issue_registry(hass)
|
||||
issue_registry.async_delete(domain, issue_id)
|
||||
|
||||
|
||||
def delete_issue(hass: HomeAssistant, domain: str, issue_id: str) -> None:
|
||||
"""Delete an issue.
|
||||
|
||||
It is not an error to delete an issue that does not exist.
|
||||
"""
|
||||
return run_callback_threadsafe(
|
||||
hass.loop, async_delete_issue, hass, domain, issue_id
|
||||
).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_ignore_issue(
|
||||
hass: HomeAssistant, domain: str, issue_id: str, ignore: bool
|
||||
) -> None:
|
||||
"""Ignore an issue.
|
||||
|
||||
Will raise if the issue does not exist.
|
||||
"""
|
||||
issue_registry = async_get_issue_registry(hass)
|
||||
issue_registry.async_ignore(domain, issue_id, ignore)
|
||||
|
|
|
@ -4,16 +4,12 @@ from __future__ import annotations
|
|||
from typing import Protocol
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.backports.enum import StrEnum
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
|
||||
class IssueSeverity(StrEnum):
|
||||
"""Issue severity."""
|
||||
|
||||
CRITICAL = "critical"
|
||||
ERROR = "error"
|
||||
WARNING = "warning"
|
||||
# pylint: disable-next=unused-import
|
||||
from homeassistant.helpers.issue_registry import ( # noqa: F401; Remove when integrations have been updated
|
||||
IssueSeverity,
|
||||
)
|
||||
|
||||
|
||||
class RepairsFlow(data_entry_flow.FlowHandler):
|
||||
|
|
|
@ -18,10 +18,12 @@ from homeassistant.helpers.data_entry_flow import (
|
|||
FlowManagerIndexView,
|
||||
FlowManagerResourceView,
|
||||
)
|
||||
from homeassistant.helpers.issue_registry import (
|
||||
async_get as async_get_issue_registry,
|
||||
async_ignore_issue,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .issue_handler import async_ignore_issue
|
||||
from .issue_registry import async_get as async_get_issue_registry
|
||||
|
||||
|
||||
@callback
|
||||
|
|
|
@ -3,14 +3,18 @@ from __future__ import annotations
|
|||
|
||||
import dataclasses
|
||||
from datetime import datetime
|
||||
import functools as ft
|
||||
from typing import Any, cast
|
||||
|
||||
from awesomeversion import AwesomeVersion, AwesomeVersionStrategy
|
||||
|
||||
from homeassistant.backports.enum import StrEnum
|
||||
from homeassistant.const import __version__ as ha_version
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.storage import Store
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .models import IssueSeverity
|
||||
from .storage import Store
|
||||
|
||||
DATA_REGISTRY = "issue_registry"
|
||||
EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED = "repairs_issue_registry_updated"
|
||||
|
@ -20,6 +24,14 @@ STORAGE_VERSION_MINOR = 2
|
|||
SAVE_DELAY = 10
|
||||
|
||||
|
||||
class IssueSeverity(StrEnum):
|
||||
"""Issue severity."""
|
||||
|
||||
CRITICAL = "critical"
|
||||
ERROR = "error"
|
||||
WARNING = "warning"
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class IssueEntry:
|
||||
"""Issue Registry Entry."""
|
||||
|
@ -267,3 +279,112 @@ async def async_load(hass: HomeAssistant) -> None:
|
|||
assert DATA_REGISTRY not in hass.data
|
||||
hass.data[DATA_REGISTRY] = IssueRegistry(hass)
|
||||
await hass.data[DATA_REGISTRY].async_load()
|
||||
|
||||
|
||||
@callback
|
||||
def async_create_issue(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
issue_id: str,
|
||||
*,
|
||||
breaks_in_ha_version: str | None = None,
|
||||
data: dict[str, str | int | float | None] | None = None,
|
||||
is_fixable: bool,
|
||||
is_persistent: bool = False,
|
||||
issue_domain: str | None = None,
|
||||
learn_more_url: str | None = None,
|
||||
severity: IssueSeverity,
|
||||
translation_key: str,
|
||||
translation_placeholders: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
"""Create an issue, or replace an existing one."""
|
||||
# Verify the breaks_in_ha_version is a valid version string
|
||||
if breaks_in_ha_version:
|
||||
AwesomeVersion(
|
||||
breaks_in_ha_version,
|
||||
ensure_strategy=AwesomeVersionStrategy.CALVER,
|
||||
find_first_match=False,
|
||||
)
|
||||
|
||||
issue_registry = async_get(hass)
|
||||
issue_registry.async_get_or_create(
|
||||
domain,
|
||||
issue_id,
|
||||
breaks_in_ha_version=breaks_in_ha_version,
|
||||
data=data,
|
||||
is_fixable=is_fixable,
|
||||
is_persistent=is_persistent,
|
||||
issue_domain=issue_domain,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=severity,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=translation_placeholders,
|
||||
)
|
||||
|
||||
|
||||
def create_issue(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
issue_id: str,
|
||||
*,
|
||||
breaks_in_ha_version: str | None = None,
|
||||
data: dict[str, str | int | float | None] | None = None,
|
||||
is_fixable: bool,
|
||||
is_persistent: bool = False,
|
||||
issue_domain: str | None = None,
|
||||
learn_more_url: str | None = None,
|
||||
severity: IssueSeverity,
|
||||
translation_key: str,
|
||||
translation_placeholders: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
"""Create an issue, or replace an existing one."""
|
||||
return run_callback_threadsafe(
|
||||
hass.loop,
|
||||
ft.partial(
|
||||
async_create_issue,
|
||||
hass,
|
||||
domain,
|
||||
issue_id,
|
||||
breaks_in_ha_version=breaks_in_ha_version,
|
||||
data=data,
|
||||
is_fixable=is_fixable,
|
||||
is_persistent=is_persistent,
|
||||
issue_domain=issue_domain,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=severity,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=translation_placeholders,
|
||||
),
|
||||
).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_delete_issue(hass: HomeAssistant, domain: str, issue_id: str) -> None:
|
||||
"""Delete an issue.
|
||||
|
||||
It is not an error to delete an issue that does not exist.
|
||||
"""
|
||||
issue_registry = async_get(hass)
|
||||
issue_registry.async_delete(domain, issue_id)
|
||||
|
||||
|
||||
def delete_issue(hass: HomeAssistant, domain: str, issue_id: str) -> None:
|
||||
"""Delete an issue.
|
||||
|
||||
It is not an error to delete an issue that does not exist.
|
||||
"""
|
||||
return run_callback_threadsafe(
|
||||
hass.loop, async_delete_issue, hass, domain, issue_id
|
||||
).result()
|
||||
|
||||
|
||||
@callback
|
||||
def async_ignore_issue(
|
||||
hass: HomeAssistant, domain: str, issue_id: str, ignore: bool
|
||||
) -> None:
|
||||
"""Ignore an issue.
|
||||
|
||||
Will raise if the issue does not exist.
|
||||
"""
|
||||
issue_registry = async_get(hass)
|
||||
issue_registry.async_ignore(domain, issue_id, ignore)
|
|
@ -50,6 +50,7 @@ from homeassistant.helpers import (
|
|||
entity_platform,
|
||||
entity_registry,
|
||||
intent,
|
||||
issue_registry,
|
||||
recorder as recorder_helper,
|
||||
restore_state,
|
||||
storage,
|
||||
|
@ -297,9 +298,10 @@ async def async_test_home_assistant(loop, load_registries=True):
|
|||
# Load the registries
|
||||
if load_registries:
|
||||
await asyncio.gather(
|
||||
area_registry.async_load(hass),
|
||||
device_registry.async_load(hass),
|
||||
entity_registry.async_load(hass),
|
||||
area_registry.async_load(hass),
|
||||
issue_registry.async_load(hass),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
|
|
@ -14,12 +14,11 @@ from homeassistant.components.repairs import (
|
|||
)
|
||||
from homeassistant.components.repairs.const import DOMAIN
|
||||
from homeassistant.components.repairs.issue_handler import (
|
||||
async_ignore_issue,
|
||||
async_process_repairs_platforms,
|
||||
)
|
||||
from homeassistant.components.repairs.models import IssueSeverity
|
||||
from homeassistant.const import __version__ as ha_version
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_ignore_issue
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import mock_platform
|
||||
|
|
|
@ -9,14 +9,11 @@ import pytest
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components.repairs import (
|
||||
RepairsFlow,
|
||||
async_create_issue,
|
||||
issue_registry,
|
||||
)
|
||||
from homeassistant.components.repairs import RepairsFlow, async_create_issue
|
||||
from homeassistant.components.repairs.const import DOMAIN
|
||||
from homeassistant.const import __version__ as ha_version
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import mock_platform
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
"""Test the repairs websocket API."""
|
||||
from homeassistant.components.repairs import async_create_issue, issue_registry
|
||||
from homeassistant.components.repairs.const import DOMAIN
|
||||
from homeassistant.components.repairs.issue_handler import (
|
||||
async_delete_issue,
|
||||
async_ignore_issue,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.helpers import issue_registry
|
||||
|
||||
from tests.common import async_capture_events, flush_store
|
||||
|
||||
|
||||
async def test_load_issues(hass: HomeAssistant) -> None:
|
||||
"""Make sure that we can load/save data correctly."""
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
|
||||
issues = [
|
||||
{
|
||||
"breaks_in_ha_version": "2022.9",
|
||||
|
@ -68,7 +62,7 @@ async def test_load_issues(hass: HomeAssistant) -> None:
|
|||
)
|
||||
|
||||
for issue in issues:
|
||||
async_create_issue(
|
||||
issue_registry.async_create_issue(
|
||||
hass,
|
||||
issue["domain"],
|
||||
issue["issue_id"],
|
||||
|
@ -105,7 +99,9 @@ async def test_load_issues(hass: HomeAssistant) -> None:
|
|||
"issue_id": "issue_4",
|
||||
}
|
||||
|
||||
async_ignore_issue(hass, issues[0]["domain"], issues[0]["issue_id"], True)
|
||||
issue_registry.async_ignore_issue(
|
||||
hass, issues[0]["domain"], issues[0]["issue_id"], True
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 5
|
||||
|
@ -115,7 +111,7 @@ async def test_load_issues(hass: HomeAssistant) -> None:
|
|||
"issue_id": "issue_1",
|
||||
}
|
||||
|
||||
async_delete_issue(hass, issues[2]["domain"], issues[2]["issue_id"])
|
||||
issue_registry.async_delete_issue(hass, issues[2]["domain"], issues[2]["issue_id"])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 6
|
||||
|
@ -175,6 +171,7 @@ async def test_load_issues(hass: HomeAssistant) -> None:
|
|||
assert issue4_registry2 == issue4
|
||||
|
||||
|
||||
@pytest.mark.parametrize("load_registries", [False])
|
||||
async def test_loading_issues_from_storage(hass: HomeAssistant, hass_storage) -> None:
|
||||
"""Test loading stored issues on start."""
|
||||
hass_storage[issue_registry.STORAGE_KEY] = {
|
||||
|
@ -215,12 +212,13 @@ async def test_loading_issues_from_storage(hass: HomeAssistant, hass_storage) ->
|
|||
},
|
||||
}
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await issue_registry.async_load(hass)
|
||||
|
||||
registry: issue_registry.IssueRegistry = hass.data[issue_registry.DATA_REGISTRY]
|
||||
assert len(registry.issues) == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("load_registries", [False])
|
||||
async def test_migration_1_1(hass: HomeAssistant, hass_storage) -> None:
|
||||
"""Test migration from version 1.1."""
|
||||
hass_storage[issue_registry.STORAGE_KEY] = {
|
||||
|
@ -244,7 +242,7 @@ async def test_migration_1_1(hass: HomeAssistant, hass_storage) -> None:
|
|||
},
|
||||
}
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await issue_registry.async_load(hass)
|
||||
|
||||
registry: issue_registry.IssueRegistry = hass.data[issue_registry.DATA_REGISTRY]
|
||||
assert len(registry.issues) == 2
|
Loading…
Add table
Reference in a new issue