Update HACS
This commit is contained in:
@@ -29,7 +29,6 @@ from .enums import ConfigurationType, HacsDisabledReason, HacsStage, LovelaceMod
|
||||
from .frontend import async_register_frontend
|
||||
from .utils.configuration_schema import hacs_config_combined
|
||||
from .utils.data import HacsData
|
||||
from .utils.platform_setup import async_setup_entity_platforms
|
||||
from .utils.queue_manager import QueueManager
|
||||
from .utils.version import version_left_higher_or_equal_then_right
|
||||
from .websocket import async_register_websocket_commands
|
||||
@@ -169,9 +168,7 @@ async def async_initialize_integration(
|
||||
hacs.log.info("Update entities are only supported when using UI configuration")
|
||||
|
||||
else:
|
||||
await async_setup_entity_platforms(
|
||||
hacs,
|
||||
hass,
|
||||
hass.config_entries.async_setup_platforms(
|
||||
config_entry,
|
||||
[Platform.SENSOR, Platform.UPDATE]
|
||||
if hacs.configuration.experimental
|
||||
|
||||
@@ -28,10 +28,11 @@ from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_FINAL_WRITE, Platform
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.issue_registry import async_create_issue, IssueSeverity
|
||||
from homeassistant.loader import Integration
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .const import TV
|
||||
from .const import DOMAIN, TV
|
||||
from .enums import (
|
||||
ConfigurationType,
|
||||
HacsCategory,
|
||||
@@ -54,7 +55,6 @@ from .repositories import RERPOSITORY_CLASSES
|
||||
from .utils.decode import decode_content
|
||||
from .utils.json import json_loads
|
||||
from .utils.logger import LOGGER
|
||||
from .utils.platform_setup import async_setup_entity_platforms
|
||||
from .utils.queue_manager import QueueManager
|
||||
from .utils.store import async_load_from_store, async_save_to_store
|
||||
|
||||
@@ -187,8 +187,8 @@ class HacsRepositories:
|
||||
|
||||
_default_repositories: set[str] = field(default_factory=set)
|
||||
_repositories: list[HacsRepository] = field(default_factory=list)
|
||||
_repositories_by_full_name: dict[str, str] = field(default_factory=dict)
|
||||
_repositories_by_id: dict[str, str] = field(default_factory=dict)
|
||||
_repositories_by_full_name: dict[str, HacsRepository] = field(default_factory=dict)
|
||||
_repositories_by_id: dict[str, HacsRepository] = field(default_factory=dict)
|
||||
_removed_repositories: list[RemovedRepository] = field(default_factory=list)
|
||||
|
||||
@property
|
||||
@@ -213,8 +213,15 @@ class HacsRepositories:
|
||||
if repo_id == "0":
|
||||
return
|
||||
|
||||
if self.is_registered(repository_id=repo_id):
|
||||
return
|
||||
if registered_repo := self._repositories_by_id.get(repo_id):
|
||||
if registered_repo.data.full_name == repository.data.full_name:
|
||||
return
|
||||
|
||||
self.unregister(registered_repo)
|
||||
|
||||
registered_repo.data.full_name = repository.data.full_name
|
||||
registered_repo.data.new = False
|
||||
repository = registered_repo
|
||||
|
||||
if repository not in self._repositories:
|
||||
self._repositories.append(repository)
|
||||
@@ -563,11 +570,6 @@ class HacsBase:
|
||||
if repository_id is not None:
|
||||
repository.data.id = repository_id
|
||||
|
||||
if str(repository.data.id) != "0" and (
|
||||
exists := self.repositories.get_by_id(repository.data.id)
|
||||
):
|
||||
self.repositories.unregister(exists)
|
||||
|
||||
else:
|
||||
if self.hass is not None and ((check and repository.data.new) or self.status.new):
|
||||
self.async_dispatch(
|
||||
@@ -730,10 +732,7 @@ class HacsBase:
|
||||
entry=self.configuration.config_entry,
|
||||
platforms=platforms,
|
||||
)
|
||||
|
||||
await async_setup_entity_platforms(
|
||||
self, self.hass, self.configuration.config_entry, platforms
|
||||
)
|
||||
self.hass.config_entries.async_setup_platforms(self.configuration.config_entry, platforms)
|
||||
|
||||
@callback
|
||||
def async_dispatch(self, signal: HacsDispatchEvent, data: dict | None = None) -> None:
|
||||
@@ -881,14 +880,30 @@ class HacsBase:
|
||||
continue
|
||||
if repository.data.full_name in self.common.ignored_repositories:
|
||||
continue
|
||||
if repository.data.installed and removed.removal_type != "critical":
|
||||
self.log.warning(
|
||||
"You have '%s' installed with HACS "
|
||||
"this repository has been removed from HACS, please consider removing it. "
|
||||
"Removal reason (%s)",
|
||||
repository.data.full_name,
|
||||
removed.reason,
|
||||
)
|
||||
if repository.data.installed:
|
||||
if removed.removal_type != "critical":
|
||||
if self.configuration.experimental:
|
||||
async_create_issue(
|
||||
hass=self.hass,
|
||||
domain=DOMAIN,
|
||||
issue_id=f"removed_{repository.data.id}",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="removed",
|
||||
translation_placeholders={
|
||||
"name": repository.data.full_name,
|
||||
"reason": removed.reason,
|
||||
"repositry_id": repository.data.id,
|
||||
},
|
||||
)
|
||||
self.log.warning(
|
||||
"You have '%s' installed with HACS "
|
||||
"this repository has been removed from HACS, please consider removing it. "
|
||||
"Removal reason (%s)",
|
||||
repository.data.full_name,
|
||||
removed.reason,
|
||||
)
|
||||
else:
|
||||
need_to_save = True
|
||||
repository.remove()
|
||||
|
||||
@@ -6,7 +6,7 @@ from aiogithubapi.common.const import ACCEPT_HEADERS
|
||||
NAME_SHORT = "HACS"
|
||||
DOMAIN = "hacs"
|
||||
CLIENT_ID = "395a8e669c5de9f7c6e8"
|
||||
MINIMUM_HA_VERSION = "2022.4.0"
|
||||
MINIMUM_HA_VERSION = "2022.10.0"
|
||||
|
||||
TV = TypeVar("TV")
|
||||
|
||||
|
||||
@@ -8,8 +8,11 @@ from homeassistant.components.http import HomeAssistantView
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .hacs_frontend import locate_dir
|
||||
from .hacs_frontend.version import VERSION as FE_VERSION
|
||||
from .hacs_frontend import locate_dir, VERSION as FE_VERSION
|
||||
from .hacs_frontend_experimental import (
|
||||
locate_dir as experimental_locate_dir,
|
||||
VERSION as EXPERIMENTAL_FE_VERSION,
|
||||
)
|
||||
|
||||
URL_BASE = "/hacsfiles"
|
||||
|
||||
@@ -30,6 +33,11 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
|
||||
"<HacsFrontend> Frontend development mode enabled. Do not run in production!"
|
||||
)
|
||||
hass.http.register_view(HacsFrontendDev())
|
||||
elif hacs.configuration.experimental:
|
||||
hacs.log.info("<HacsFrontend> Using experimental frontend")
|
||||
hass.http.register_static_path(
|
||||
f"{URL_BASE}/frontend", experimental_locate_dir(), cache_headers=False
|
||||
)
|
||||
else:
|
||||
#
|
||||
hass.http.register_static_path(f"{URL_BASE}/frontend", locate_dir(), cache_headers=False)
|
||||
@@ -56,7 +64,9 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
|
||||
cache_headers=use_cache,
|
||||
)
|
||||
|
||||
hacs.frontend_version = FE_VERSION
|
||||
hacs.frontend_version = (
|
||||
FE_VERSION if not hacs.configuration.experimental else EXPERIMENTAL_FE_VERSION
|
||||
)
|
||||
|
||||
# Add to sidepanel if needed
|
||||
if DOMAIN not in hass.data.get("frontend_panels", {}):
|
||||
@@ -70,7 +80,7 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
|
||||
"name": "hacs-frontend",
|
||||
"embed_iframe": True,
|
||||
"trust_external": False,
|
||||
"js_url": f"/hacsfiles/frontend/entrypoint.js?hacstag={FE_VERSION}",
|
||||
"js_url": f"/hacsfiles/frontend/entrypoint.js?hacstag={hacs.frontend_version}",
|
||||
}
|
||||
},
|
||||
require_admin=True,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
try {
|
||||
new Function("import('/hacsfiles/frontend/main-7bc9a818.js')")();
|
||||
new Function("import('/hacsfiles/frontend/main-ad130be7.js')")();
|
||||
} catch (err) {
|
||||
var el = document.createElement('script');
|
||||
el.src = '/hacsfiles/frontend/main-7bc9a818.js';
|
||||
el.src = '/hacsfiles/frontend/main-ad130be7.js';
|
||||
el.type = 'module';
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"./src/main.ts": "main-7bc9a818.js"
|
||||
"./src/main.ts": "main-ad130be7.js"
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
VERSION="20220714083628"
|
||||
VERSION="20220906112053"
|
||||
@@ -8,7 +8,8 @@
|
||||
"websocket_api",
|
||||
"frontend",
|
||||
"persistent_notification",
|
||||
"lovelace"
|
||||
"lovelace",
|
||||
"repairs"
|
||||
],
|
||||
"documentation": "https://hacs.xyz/docs/configuration/start",
|
||||
"domain": "hacs",
|
||||
@@ -18,5 +19,5 @@
|
||||
"requirements": [
|
||||
"aiogithubapi>=22.2.4"
|
||||
],
|
||||
"version": "1.26.2"
|
||||
"version": "1.28.3"
|
||||
}
|
||||
@@ -18,7 +18,7 @@ from aiogithubapi import (
|
||||
from aiogithubapi.const import BASE_API_URL
|
||||
from aiogithubapi.objects.repository import AIOGitHubAPIRepository
|
||||
import attr
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers import device_registry as dr, issue_registry as ir
|
||||
|
||||
from ..const import DOMAIN
|
||||
from ..enums import ConfigurationType, HacsDispatchEvent, RepositoryFile
|
||||
@@ -734,6 +734,7 @@ class HacsRepository:
|
||||
)
|
||||
|
||||
await self.async_remove_entity_device()
|
||||
ir.async_delete_issue(self.hacs.hass, DOMAIN, f"removed_{self.data.id}")
|
||||
|
||||
async def remove_local_directory(self) -> None:
|
||||
"""Check the local directory."""
|
||||
@@ -993,7 +994,12 @@ class HacsRepository:
|
||||
releases.append(release)
|
||||
return releases
|
||||
|
||||
async def common_update_data(self, ignore_issues: bool = False, force: bool = False) -> None:
|
||||
async def common_update_data(
|
||||
self,
|
||||
ignore_issues: bool = False,
|
||||
force: bool = False,
|
||||
retry=False,
|
||||
) -> None:
|
||||
"""Common update data."""
|
||||
releases = []
|
||||
try:
|
||||
@@ -1072,6 +1078,20 @@ class HacsRepository:
|
||||
for treefile in self.tree:
|
||||
self.treefiles.append(treefile.full_path)
|
||||
except (AIOGitHubAPIException, HacsException) as exception:
|
||||
if (
|
||||
not retry
|
||||
and self.ref is not None
|
||||
and str(exception).startswith("GitHub returned 404")
|
||||
):
|
||||
# Handle tags/branches being deleted.
|
||||
self.data.selected_tag = None
|
||||
self.ref = self.version_to_download()
|
||||
self.logger.warning(
|
||||
"%s Selected version/branch %s has been removed, falling back to default",
|
||||
self.string,
|
||||
self.ref,
|
||||
)
|
||||
return await self.common_update_data(ignore_issues, force, True)
|
||||
if not self.hacs.status.startup and not ignore_issues:
|
||||
self.logger.error("%s %s", self.string, exception)
|
||||
if not ignore_issues:
|
||||
|
||||
@@ -3,8 +3,10 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from homeassistant.helpers.issue_registry import async_create_issue, IssueSeverity
|
||||
from homeassistant.loader import async_get_custom_components
|
||||
|
||||
from ..const import DOMAIN
|
||||
from ..enums import HacsCategory, HacsDispatchEvent, HacsGitHubRepo, RepositoryFile
|
||||
from ..exceptions import AddonRepositoryException, HacsException
|
||||
from ..utils.decode import decode_content
|
||||
@@ -36,13 +38,27 @@ class HacsIntegrationRepository(HacsRepository):
|
||||
|
||||
async def async_post_installation(self):
|
||||
"""Run post installation steps."""
|
||||
self.pending_restart = True
|
||||
if self.data.config_flow:
|
||||
if self.data.full_name != HacsGitHubRepo.INTEGRATION:
|
||||
await self.reload_custom_components()
|
||||
if self.data.first_install:
|
||||
self.pending_restart = False
|
||||
return
|
||||
self.pending_restart = True
|
||||
|
||||
if self.pending_restart and self.hacs.configuration.experimental:
|
||||
self.logger.debug("%s Creating restart_required issue", self.string)
|
||||
async_create_issue(
|
||||
hass=self.hacs.hass,
|
||||
domain=DOMAIN,
|
||||
issue_id=f"restart_required_{self.data.id}_{self.ref}",
|
||||
is_fixable=True,
|
||||
issue_domain=self.data.domain or DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="restart_required",
|
||||
translation_placeholders={
|
||||
"name": self.display_name,
|
||||
},
|
||||
)
|
||||
|
||||
async def validate_repository(self):
|
||||
"""Validate."""
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
"""Sensor platform for HACS."""
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.core import callback
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .base import HacsBase
|
||||
|
||||
from .const import DOMAIN
|
||||
from .entity import HacsSystemEntity
|
||||
from .enums import ConfigurationType
|
||||
@@ -16,6 +20,10 @@ async def async_setup_platform(hass, _config, async_add_entities, _discovery_inf
|
||||
|
||||
async def async_setup_entry(hass, _config_entry, async_add_devices):
|
||||
"""Setup sensor platform."""
|
||||
hacs: HacsBase = hass.data.get(DOMAIN)
|
||||
if hacs.configuration.experimental:
|
||||
return
|
||||
|
||||
async_add_devices([HACSSensor(hacs=hass.data.get(DOMAIN))])
|
||||
|
||||
|
||||
|
||||
@@ -53,5 +53,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"restart_required": {
|
||||
"title": "Restart required",
|
||||
"fix_flow": {
|
||||
"step": {
|
||||
"confirm_restart": {
|
||||
"title": "Restart required",
|
||||
"description": "Restart of Home Assistant is required to finish download/update of {name}, click submit to restart now."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"removed": {
|
||||
"title": "Repository removed from HACS",
|
||||
"description": "{name} has been removed from HACS for {reason} visit the [HACS Panel](/hacs/repository/{repositry_id}) to remove it."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@ import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.util import json as json_util
|
||||
|
||||
from ..base import HacsBase
|
||||
from ..enums import HacsDispatchEvent, HacsGitHubRepo
|
||||
from ..enums import HacsDisabledReason, HacsDispatchEvent, HacsGitHubRepo
|
||||
from ..repositories.base import TOPIC_FILTER, HacsManifest, HacsRepository
|
||||
from .logger import LOGGER
|
||||
from .path import is_safe
|
||||
@@ -116,8 +117,21 @@ class HacsData:
|
||||
async def restore(self):
|
||||
"""Restore saved data."""
|
||||
self.hacs.status.new = False
|
||||
hacs = await async_load_from_store(self.hacs.hass, "hacs") or {}
|
||||
repositories = await async_load_from_store(self.hacs.hass, "repositories") or {}
|
||||
try:
|
||||
hacs = await async_load_from_store(self.hacs.hass, "hacs") or {}
|
||||
except HomeAssistantError:
|
||||
hacs = {}
|
||||
|
||||
try:
|
||||
repositories = await async_load_from_store(self.hacs.hass, "repositories") or {}
|
||||
except HomeAssistantError as exception:
|
||||
self.hacs.log.error(
|
||||
"Could not read %s, restore the file from a backup - %s",
|
||||
self.hacs.hass.config.path(".storage/hacs.repositories"),
|
||||
exception,
|
||||
)
|
||||
self.hacs.disable_hacs(HacsDisabledReason.RESTORE)
|
||||
return False
|
||||
|
||||
if not hacs and not repositories:
|
||||
# Assume new install
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -21,7 +21,7 @@ def version_left_higher_then_right(left: str, right: str) -> bool | None:
|
||||
and right_version.strategy != AwesomeVersionStrategy.UNKNOWN
|
||||
):
|
||||
return left_version > right_version
|
||||
except (AwesomeVersionException, AttributeError):
|
||||
except (AwesomeVersionException, AttributeError, KeyError):
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
@@ -26,4 +26,4 @@ class Validator(ActionValidationBase):
|
||||
if [ignore for ignore in IGNORED if ignore in line]:
|
||||
continue
|
||||
return
|
||||
raise ValidationException("The repository does not have issues enabled")
|
||||
raise ValidationException("The repository does not have images in the Readme file")
|
||||
|
||||
@@ -9,7 +9,6 @@ from typing import TYPE_CHECKING
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from ..enums import HacsGitHubRepo
|
||||
from ..repositories.base import HacsRepository
|
||||
from .base import ActionValidationBase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user