async def get_repository_manifest_content(self): """Get the content of the hacs.json file.""" if not "hacs.json" in [x.filename for x in self.tree]: if self.hacs.action: raise HacsException( "::error:: No hacs.json file in the root of the repository." ) return if self.hacs.action: self.logger.info("Found hacs.json") self.ref = version_to_install(self) try: manifest = await self.repository_object.get_contents( "hacs.json", self.ref) self.repository_manifest = HacsManifest.from_dict( json.loads(manifest.content)) self.data.update_data(json.loads(manifest.content)) except (AIOGitHubAPIException, Exception) as exception: # Gotta Catch 'Em All if self.hacs.action: raise HacsException( f"::error:: hacs.json file is not valid ({exception}).") if self.hacs.action: self.logger.info("hacs.json is valid")
def dummy_repository_base(repository=None): if repository is None: repository = HacsRepository() repository.hacs.hass = HomeAssistant() repository.hacs.hass.data = {"custom_components": []} repository.hacs.system.config_path = tempfile.gettempdir() repository.logger = getLogger("test.test") repository.data.full_name = "test/test" repository.data.domain = "test" repository.data.last_version = "3" repository.data.selected_tag = "3" repository.ref = version_to_install(repository) repository.integration_manifest = {"config_flow": False, "domain": "test"} repository.data.published_tags = ["1", "2", "3"] repository.data.update_data(repository_data) return repository
async def async_install_repository(repository): """Common installation steps of the repository.""" hacs = get_hacs() persistent_directory = None await repository.update_repository() if repository.content.path.local is None: raise HacsException("repository.content.path.local is None") repository.validate.errors = [] if not repository.can_install: raise HacsException( "The version of Home Assistant is not compatible with this version" ) version = version_to_install(repository) if version == repository.data.default_branch: repository.ref = version else: repository.ref = f"tags/{version}" if repository.data.installed and repository.data.category == "netdaemon": persistent_directory = await hacs.hass.async_add_executor_job( BackupNetDaemon, repository) await hacs.hass.async_add_executor_job(persistent_directory.create) elif repository.data.persistent_directory: if os.path.exists( f"{repository.content.path.local}/{repository.data.persistent_directory}" ): persistent_directory = Backup( f"{repository.content.path.local}/{repository.data.persistent_directory}", tempfile.gettempdir() + "/hacs_persistent_directory/", ) await hacs.hass.async_add_executor_job(persistent_directory.create) if repository.data.installed and not repository.content.single: backup = Backup(repository.content.path.local) await hacs.hass.async_add_executor_job(backup.create) if repository.data.zip_release and version != repository.data.default_branch: await repository.download_zip_files(repository) else: await download_content(repository) if repository.validate.errors: for error in repository.validate.errors: repository.logger.error(error) if repository.data.installed and not repository.content.single: await hacs.hass.async_add_executor_job(backup.restore) if repository.data.installed and not repository.content.single: await hacs.hass.async_add_executor_job(backup.cleanup) if persistent_directory is not None: await hacs.hass.async_add_executor_job(persistent_directory.restore) await hacs.hass.async_add_executor_job(persistent_directory.cleanup) if repository.validate.success: if repository.data.full_name not in repository.hacs.common.installed: if repository.data.full_name == "hacs/integration": repository.hacs.common.installed.append( repository.data.full_name) repository.data.installed = True repository.data.installed_commit = repository.data.last_commit if version == repository.data.default_branch: repository.data.installed_version = None else: repository.data.installed_version = version
async def common_update_data(repository, ignore_issues=False): """Common update data.""" hacs = get_hacs() releases = [] try: repository_object = await get_repository(hacs.session, hacs.configuration.token, repository.data.full_name) repository.repository_object = repository_object repository.data.update_data(repository_object.attributes) except (AIOGitHubAPIException, HacsException) as exception: if not hacs.status.startup: repository.logger.error("%s %s", repository, exception) if not ignore_issues: repository.validate.errors.append("Repository does not exist.") raise HacsException(exception) from None # Make sure the repository is not archived. if repository.data.archived and not ignore_issues: repository.validate.errors.append("Repository is archived.") raise HacsRepositoryArchivedException("Repository is archived.") # Make sure the repository is not in the blacklist. if is_removed(repository.data.full_name) and not ignore_issues: repository.validate.errors.append("Repository is in the blacklist.") raise HacsException("Repository is in the blacklist.") # Get releases. try: releases = await get_releases( repository.repository_object, repository.data.show_beta, hacs.configuration.release_limit, ) if releases: repository.data.releases = True repository.releases.objects = [x for x in releases if not x.draft] repository.data.published_tags = [ x.tag_name for x in repository.releases.objects ] repository.data.last_version = next( iter(repository.data.published_tags)) except (AIOGitHubAPIException, HacsException): repository.data.releases = False if not repository.force_branch: repository.ref = version_to_install(repository) if repository.data.releases: for release in repository.releases.objects or []: if release.tag_name == repository.ref: assets = release.assets if assets: downloads = next( iter(assets)).attributes.get("download_count") repository.data.downloads = downloads repository.logger.debug("%s Running checks against %s", repository, repository.ref.replace("tags/", "")) try: repository.tree = await get_tree(repository.repository_object, repository.ref) if not repository.tree: raise HacsException("No files in tree") repository.treefiles = [] for treefile in repository.tree: repository.treefiles.append(treefile.full_path) except (AIOGitHubAPIException, HacsException) as exception: if not hacs.status.startup: repository.logger.error("%s %s", repository, exception) if not ignore_issues: raise HacsException(exception) from None
def test_version_to_install(): repository = dummy_repository_base() repository.data.selected_tag = "master" assert version_to_install(repository) == "master" repository = dummy_repository_base() repository.data.default_branch = None repository.data.last_version = None repository.data.selected_tag = None assert version_to_install(repository) == "master" repository = dummy_repository_base() repository.data.selected_tag = "2" assert version_to_install(repository) == "2" repository = dummy_repository_base() repository.data.selected_tag = None assert version_to_install(repository) == "3" repository = dummy_repository_base() repository.data.selected_tag = None repository.data.last_version = None assert version_to_install(repository) == "master" repository = dummy_repository_base() repository.data.selected_tag = "2" repository.data.last_version = None assert version_to_install(repository) == "2" repository = dummy_repository_base() repository.data.selected_tag = "master" repository.data.last_version = None assert version_to_install(repository) == "master" repository = dummy_repository_base() repository.data.selected_tag = "3" repository.data.last_version = "3" version_to_install(repository) assert repository.data.selected_tag is None repository = dummy_repository_base() repository.data.default_branch = "dev" repository.data.last_version = None repository.data.selected_tag = None assert version_to_install(repository) == "dev" repository = dummy_repository_base() repository.data.default_branch = "master" repository.data.last_version = "2" assert version_to_install(repository) == "2"