diff --git a/custom_components/hacs/repositories/appdaemon.py b/custom_components/hacs/repositories/appdaemon.py index f271a39ef0f..62e15489280 100644 --- a/custom_components/hacs/repositories/appdaemon.py +++ b/custom_components/hacs/repositories/appdaemon.py @@ -4,11 +4,10 @@ from typing import TYPE_CHECKING -from aiogithubapi import AIOGitHubAPIException - from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent +from ..utils.filters import get_first_directory_in_directory from .base import HacsRepository if TYPE_CHECKING: @@ -32,25 +31,13 @@ def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/appdaemon/apps/{self.data.name}" - async def validate_repository(self): + async def validate_repository(self) -> bool: """Validate.""" await self.common_validate() # Custom step 1: Validate content. - try: - addir = await self.repository_object.get_contents("apps", self.ref) - except AIOGitHubAPIException: - raise HacsException( - f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" - ) from None - - if not isinstance(addir, list): - self.validate.errors.append(f"{self.string} Repository structure not compliant") - - self.content.path.remote = addir[0].path - self.content.objects = await self.repository_object.get_contents( - self.content.path.remote, self.ref - ) + # Find the first directory under apps/ + self.content.path.remote = f"apps/{self._get_apps_directory_from_tree()}" # Handle potential errors if self.validate.errors: @@ -60,7 +47,7 @@ async def validate_repository(self): return self.validate.success @concurrent(concurrenttasks=10, backoff_time=5) - async def update_repository(self, ignore_issues=False, force=False): + async def update_repository(self, ignore_issues: bool = False, force: bool = False) -> None: """Update.""" if not await self.common_update(ignore_issues, force) and not force: return @@ -71,11 +58,7 @@ async def update_repository(self, ignore_issues=False, force=False): self.content.path.remote = "" if self.content.path.remote == "apps": - addir = await self.repository_object.get_contents(self.content.path.remote, self.ref) - self.content.path.remote = addir[0].path - self.content.objects = await self.repository_object.get_contents( - self.content.path.remote, self.ref - ) + self.content.path.remote = f"apps/{self._get_apps_directory_from_tree()}" # Set local path self.content.path.local = self.localpath @@ -91,3 +74,12 @@ async def update_repository(self, ignore_issues=False, force=False): "repository_id": self.data.id, }, ) + + def _get_apps_directory_from_tree(self) -> str: + """Get the first apps directory from the repository tree.""" + if not (app_dir := get_first_directory_in_directory(self.tree, "apps")): + raise HacsException( + f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant. " + "Expected to find at least one directory under '/apps/'" + ) + return app_dir diff --git a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0.json b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0.json index 2c6690f69e1..ab44bec4843 100644 --- a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0.json +++ b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0.json @@ -11,14 +11,21 @@ "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { - "path": "appdaemons", + "path": "apps", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { - "path": "appdaemons/example.yaml", + "path": "apps/example", + "mode": "040000", + "type": "tree", + "sha": "f484d249c660418515fb01c2b9662073663c242e", + "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" + }, + { + "path": "apps/example/example.yaml", "mode": "100755", "type": "blob", "size": 75, diff --git a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/2.0.0.json b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/2.0.0.json index 2c6690f69e1..ab44bec4843 100644 --- a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/2.0.0.json +++ b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/2.0.0.json @@ -11,14 +11,21 @@ "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { - "path": "appdaemons", + "path": "apps", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { - "path": "appdaemons/example.yaml", + "path": "apps/example", + "mode": "040000", + "type": "tree", + "sha": "f484d249c660418515fb01c2b9662073663c242e", + "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" + }, + { + "path": "apps/example/example.yaml", "mode": "100755", "type": "blob", "size": 75, diff --git a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/main.json b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/main.json index 2c6690f69e1..ab44bec4843 100644 --- a/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/main.json +++ b/tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/main.json @@ -11,14 +11,21 @@ "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { - "path": "appdaemons", + "path": "apps", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { - "path": "appdaemons/example.yaml", + "path": "apps/example", + "mode": "040000", + "type": "tree", + "sha": "f484d249c660418515fb01c2b9662073663c242e", + "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" + }, + { + "path": "apps/example/example.yaml", "mode": "100755", "type": "blob", "size": 75, diff --git a/tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json index 26f29952c6b..4893cd2e257 100644 --- a/tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, diff --git a/tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json index cec58be4639..fb25c664967 100644 --- a/tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, diff --git a/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json index 0bae657a199..d763957fbd4 100644 --- a/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, diff --git a/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json index 7d1ca95d11e..496abf6751b 100644 --- a/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, diff --git a/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json index 06bfa9fb212..1ac694481c2 100644 --- a/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/appdaemon-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, diff --git a/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json b/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json index 7b05f62f6ab..19739b5b3e7 100644 --- a/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json +++ b/tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json @@ -2,8 +2,6 @@ "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, - "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1,