From 16614168a7c8cb00bc88b71c6bf281aee2375733 Mon Sep 17 00:00:00 2001 From: Seputaes Date: Tue, 26 Feb 2019 21:07:05 -0800 Subject: [PATCH] [Downloader] Install SHARED_LIBRARY requirements (#2384) SHARED_LIBRARY Installable types did not have the requirements as defined in info.json automatically installed. This change updates the installation of libraries to also install their requirements. Resolves #2381 --- redbot/cogs/downloader/downloader.py | 6 ++++-- redbot/cogs/downloader/repo_manager.py | 10 +++++++-- redbot/pytest/downloader.py | 25 +++++++++++++++++++++++ tests/cogs/downloader/test_downloader.py | 16 +++++++++++++++ tests/cogs/downloader/test_installable.py | 11 ++++++++++ 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/redbot/cogs/downloader/downloader.py b/redbot/cogs/downloader/downloader.py index 9a2cfa7f6..5454e5bc6 100644 --- a/redbot/cogs/downloader/downloader.py +++ b/redbot/cogs/downloader/downloader.py @@ -140,7 +140,9 @@ class Downloader(commands.Cog): failed = [] for repo in repos: - if not await repo.install_libraries(target_dir=self.SHAREDLIB_PATH): + if not await repo.install_libraries( + target_dir=self.SHAREDLIB_PATH, req_target_dir=self.LIB_PATH + ): failed.extend(repo.available_libraries) # noinspection PyTypeChecker @@ -314,7 +316,7 @@ class Downloader(commands.Cog): await self._add_to_installed(cog) - await repo.install_libraries(self.SHAREDLIB_PATH) + await repo.install_libraries(target_dir=self.SHAREDLIB_PATH, req_target_dir=self.LIB_PATH) await ctx.send(_("Cog `{cog_name}` successfully installed.").format(cog_name=cog_name)) if cog.install_msg is not None: diff --git a/redbot/cogs/downloader/repo_manager.py b/redbot/cogs/downloader/repo_manager.py index e17aabcca..80581308c 100644 --- a/redbot/cogs/downloader/repo_manager.py +++ b/redbot/cogs/downloader/repo_manager.py @@ -404,7 +404,7 @@ class Repo(RepoJSONMixin): return await cog.copy_to(target_dir=target_dir) async def install_libraries( - self, target_dir: Path, libraries: Tuple[Installable] = () + self, target_dir: Path, req_target_dir: Path, libraries: Tuple[Installable] = () ) -> bool: """Install shared libraries to the target directory. @@ -415,6 +415,8 @@ class Repo(RepoJSONMixin): ---------- target_dir : pathlib.Path Directory to install shared libraries to. + req_target_dir : pathlib.Path + Directory to install shared library requirements to. libraries : `tuple` of `Installable` A subset of available libraries. @@ -433,7 +435,11 @@ class Repo(RepoJSONMixin): if len(libraries) > 0: ret = True for lib in libraries: - ret = ret and await lib.copy_to(target_dir=target_dir) + ret = ( + ret + and await self.install_requirements(cog=lib, target_dir=req_target_dir) + and await lib.copy_to(target_dir=target_dir) + ) return ret return True diff --git a/redbot/pytest/downloader.py b/redbot/pytest/downloader.py index 8260d17ff..591441bf3 100644 --- a/redbot/pytest/downloader.py +++ b/redbot/pytest/downloader.py @@ -14,7 +14,9 @@ __all__ = [ "repo_norun", "bot_repo", "INFO_JSON", + "LIBRARY_INFO_JSON", "installable", + "library_installable", "fake_run_noprint", ] @@ -92,6 +94,19 @@ INFO_JSON = { "type": "COG", } +LIBRARY_INFO_JSON = { + "author": ("seputaes",), + "bot_version": (3, 0, 0), + "description": "A long library description", + "hidden": False, # libraries are always hidden, this tests it will be flipped + "install_msg": "A library install message", + "required_cogs": {}, + "requirements": ("tabulate"), + "short": "A short library description", + "tags": ("libtag1", "libtag2"), + "type": "SHARED_LIBRARY", +} + @pytest.fixture def installable(tmpdir): @@ -101,3 +116,13 @@ def installable(tmpdir): cog_info = Installable(Path(str(cog_path))) return cog_info + + +@pytest.fixture +def library_installable(tmpdir): + lib_path = tmpdir.mkdir("test_repo").mkdir("test_lib") + info_path = lib_path.join("info.json") + info_path.write_text(json.dumps(LIBRARY_INFO_JSON), "utf-8") + + cog_info = Installable(Path(str(lib_path))) + return cog_info diff --git a/tests/cogs/downloader/test_downloader.py b/tests/cogs/downloader/test_downloader.py index f9a9831bf..57186baaa 100644 --- a/tests/cogs/downloader/test_downloader.py +++ b/tests/cogs/downloader/test_downloader.py @@ -38,6 +38,22 @@ async def test_add_repo(monkeypatch, repo_manager): assert squid.available_modules == [] +@pytest.mark.asyncio +async def test_lib_install_requirements(monkeypatch, library_installable, repo, tmpdir): + monkeypatch.setattr("redbot.cogs.downloader.repo_manager.Repo._run", fake_run_noprint) + monkeypatch.setattr( + "redbot.cogs.downloader.repo_manager.Repo.available_libraries", (library_installable,) + ) + + lib_path = Path(str(tmpdir)) / "cog_data_path" / "lib" + sharedlib_path = lib_path / "cog_shared" + sharedlib_path.mkdir(parents=True, exist_ok=True) + + result = await repo.install_libraries(target_dir=sharedlib_path, req_target_dir=lib_path) + + assert result is True + + @pytest.mark.asyncio async def test_remove_repo(monkeypatch, repo_manager): monkeypatch.setattr("redbot.cogs.downloader.repo_manager.Repo._run", fake_run_noprint) diff --git a/tests/cogs/downloader/test_installable.py b/tests/cogs/downloader/test_installable.py index 3d1765a34..5f1489e86 100644 --- a/tests/cogs/downloader/test_installable.py +++ b/tests/cogs/downloader/test_installable.py @@ -15,6 +15,17 @@ def test_process_info_file(installable): assert getattr(installable, k) == v +def test_process_lib_info_file(library_installable): + for k, v in LIBRARY_INFO_JSON.items(): + if k == "type": + assert library_installable.type == InstallableType.SHARED_LIBRARY + elif k == "hidden": + # libraries are always hidden, even if False + assert library_installable.hidden is True + else: + assert getattr(library_installable, k) == v + + # noinspection PyProtectedMember def test_location_is_dir(installable): assert installable._location.exists()