mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2026-05-27 09:06:43 -04:00
Fix wrong info being loaded into InstalledModule (#6720)
This commit is contained in:
@@ -154,9 +154,10 @@ async def installed_cogs() -> Tuple[InstalledModule, ...]:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
installed = await _config.installed_cogs()
|
installed = await _config.installed_cogs()
|
||||||
|
install_path = await _cog_mgr.install_path()
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return tuple(
|
return tuple(
|
||||||
InstalledModule.from_json(cog_json, _repo_manager)
|
InstalledModule.from_json(cog_json, _repo_manager, base_target_dir=install_path)
|
||||||
for repo_json in installed.values()
|
for repo_json in installed.values()
|
||||||
for cog_json in repo_json.values()
|
for cog_json in repo_json.values()
|
||||||
)
|
)
|
||||||
@@ -174,7 +175,7 @@ async def installed_libraries() -> Tuple[InstalledModule, ...]:
|
|||||||
installed = await _config.installed_libraries()
|
installed = await _config.installed_libraries()
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return tuple(
|
return tuple(
|
||||||
InstalledModule.from_json(lib_json, _repo_manager)
|
InstalledModule.from_json(lib_json, _repo_manager, base_target_dir=SHAREDLIB_PATH)
|
||||||
for repo_json in installed.values()
|
for repo_json in installed.values()
|
||||||
for lib_json in repo_json.values()
|
for lib_json in repo_json.values()
|
||||||
)
|
)
|
||||||
@@ -388,8 +389,8 @@ async def _install_cogs(
|
|||||||
for commit, cogs_to_install in cogs_by_commit.items():
|
for commit, cogs_to_install in cogs_by_commit.items():
|
||||||
await repo.checkout(commit)
|
await repo.checkout(commit)
|
||||||
for cog in cogs_to_install:
|
for cog in cogs_to_install:
|
||||||
if await cog.copy_to(await _cog_mgr.install_path()):
|
if install_location := await cog.copy_to(await _cog_mgr.install_path()):
|
||||||
installed.append(InstalledModule.from_installable(cog))
|
installed.append(InstalledModule.from_installable(cog, install_location))
|
||||||
else:
|
else:
|
||||||
failed.append(cog)
|
failed.append(cog)
|
||||||
await repo.checkout(exit_to_commit)
|
await repo.checkout(exit_to_commit)
|
||||||
|
|||||||
@@ -67,7 +67,14 @@ class Installable(RepoJSONMixin):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, location: Path, repo: Optional[Repo] = None, commit: str = ""):
|
def __init__(
|
||||||
|
self,
|
||||||
|
location: Path,
|
||||||
|
repo: Optional[Repo] = None,
|
||||||
|
commit: str = "",
|
||||||
|
*,
|
||||||
|
info_file: Optional[Path] = None,
|
||||||
|
):
|
||||||
"""Base installable initializer.
|
"""Base installable initializer.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -97,7 +104,7 @@ class Installable(RepoJSONMixin):
|
|||||||
self.tags: Tuple[str, ...]
|
self.tags: Tuple[str, ...]
|
||||||
self.type: InstallableType
|
self.type: InstallableType
|
||||||
|
|
||||||
super().__init__(location)
|
super().__init__(location, info_file=info_file)
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
@@ -111,14 +118,14 @@ class Installable(RepoJSONMixin):
|
|||||||
"""`str` : The name of this package."""
|
"""`str` : The name of this package."""
|
||||||
return self._location.stem
|
return self._location.stem
|
||||||
|
|
||||||
async def copy_to(self, target_dir: Path) -> bool:
|
async def copy_to(self, target_dir: Path) -> Optional[Path]:
|
||||||
"""
|
"""
|
||||||
Copies this cog/shared_lib to the given directory. This
|
Copies this cog/shared_lib to the given directory. This
|
||||||
will overwrite any files in the target directory.
|
will overwrite any files in the target directory.
|
||||||
|
|
||||||
:param pathlib.Path target_dir: The installation directory to install to.
|
:param pathlib.Path target_dir: The installation directory to install to.
|
||||||
:return: Status of installation
|
:return: Install location of the cog or None in case of copy failure.
|
||||||
:rtype: bool
|
:rtype: `Path`, optional
|
||||||
"""
|
"""
|
||||||
copy_func: Callable[..., Any]
|
copy_func: Callable[..., Any]
|
||||||
if self._location.is_file():
|
if self._location.is_file():
|
||||||
@@ -126,13 +133,14 @@ class Installable(RepoJSONMixin):
|
|||||||
else:
|
else:
|
||||||
copy_func = functools.partial(shutil.copytree, dirs_exist_ok=True)
|
copy_func = functools.partial(shutil.copytree, dirs_exist_ok=True)
|
||||||
|
|
||||||
|
dst = target_dir / self._location.name
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
copy_func(src=str(self._location), dst=str(target_dir / self._location.name))
|
copy_func(src=str(self._location), dst=str(dst))
|
||||||
except: # noqa: E722
|
except: # noqa: E722
|
||||||
log.exception("Error occurred when copying path: %s", self._location)
|
log.exception("Error occurred when copying path: %s", self._location)
|
||||||
return False
|
return None
|
||||||
return True
|
return dst
|
||||||
|
|
||||||
def _read_info_file(self) -> None:
|
def _read_info_file(self) -> None:
|
||||||
super()._read_info_file()
|
super()._read_info_file()
|
||||||
@@ -160,8 +168,13 @@ class InstalledModule(Installable):
|
|||||||
commit: str = "",
|
commit: str = "",
|
||||||
pinned: bool = False,
|
pinned: bool = False,
|
||||||
json_repo_name: str = "",
|
json_repo_name: str = "",
|
||||||
|
*,
|
||||||
|
info_file: Optional[Path] = None,
|
||||||
|
install_location: Path,
|
||||||
):
|
):
|
||||||
super().__init__(location=location, repo=repo, commit=commit)
|
info_file = info_file or install_location / self.INFO_FILE_NAME
|
||||||
|
super().__init__(location=location, repo=repo, commit=commit, info_file=info_file)
|
||||||
|
self._install_location = install_location
|
||||||
self.pinned: bool = pinned if self.type is InstallableType.COG else False
|
self.pinned: bool = pinned if self.type is InstallableType.COG else False
|
||||||
# this is here so that Downloader could use real repo name instead of "MISSING_REPO"
|
# this is here so that Downloader could use real repo name instead of "MISSING_REPO"
|
||||||
self._json_repo_name = json_repo_name
|
self._json_repo_name = json_repo_name
|
||||||
@@ -178,10 +191,10 @@ class InstalledModule(Installable):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(
|
def from_json(
|
||||||
cls, data: Dict[str, Union[str, bool]], repo_mgr: RepoManager
|
cls, data: Dict[str, Union[str, bool]], repo_mgr: RepoManager, *, base_target_dir: Path
|
||||||
) -> InstalledModule:
|
) -> InstalledModule:
|
||||||
repo_name = cast(str, data["repo_name"])
|
repo_name = cast(str, data["repo_name"])
|
||||||
cog_name = cast(str, data["module_name"])
|
module_name = cast(str, data["module_name"])
|
||||||
commit = cast(str, data.get("commit", ""))
|
commit = cast(str, data.get("commit", ""))
|
||||||
pinned = cast(bool, data.get("pinned", False))
|
pinned = cast(bool, data.get("pinned", False))
|
||||||
|
|
||||||
@@ -192,14 +205,26 @@ class InstalledModule(Installable):
|
|||||||
else:
|
else:
|
||||||
repo_folder = repo_mgr.repos_folder / "MISSING_REPO"
|
repo_folder = repo_mgr.repos_folder / "MISSING_REPO"
|
||||||
|
|
||||||
location = repo_folder / cog_name
|
location = repo_folder / module_name
|
||||||
|
install_location = base_target_dir / module_name
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
location=location, repo=repo, commit=commit, pinned=pinned, json_repo_name=repo_name
|
location=location,
|
||||||
|
repo=repo,
|
||||||
|
commit=commit,
|
||||||
|
pinned=pinned,
|
||||||
|
json_repo_name=repo_name,
|
||||||
|
install_location=install_location,
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_installable(cls, module: Installable, *, pinned: bool = False) -> InstalledModule:
|
def from_installable(
|
||||||
|
cls, module: Installable, install_location: Path, *, pinned: bool = False
|
||||||
|
) -> InstalledModule:
|
||||||
return cls(
|
return cls(
|
||||||
location=module._location, repo=module.repo, commit=module.commit, pinned=pinned
|
location=module._location,
|
||||||
|
repo=module.repo,
|
||||||
|
commit=module.commit,
|
||||||
|
pinned=pinned,
|
||||||
|
install_location=install_location,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Tuple
|
from typing import Any, Dict, Optional, Tuple
|
||||||
|
|
||||||
from .info_schemas import REPO_SCHEMA, update_mixin
|
from .info_schemas import REPO_SCHEMA, update_mixin
|
||||||
from .log import log
|
from .log import log
|
||||||
@@ -9,7 +9,7 @@ from .log import log
|
|||||||
class RepoJSONMixin:
|
class RepoJSONMixin:
|
||||||
INFO_FILE_NAME = "info.json"
|
INFO_FILE_NAME = "info.json"
|
||||||
|
|
||||||
def __init__(self, repo_folder: Path):
|
def __init__(self, repo_folder: Path, *, info_file: Optional[Path] = None):
|
||||||
self._repo_folder = repo_folder
|
self._repo_folder = repo_folder
|
||||||
|
|
||||||
self.author: Tuple[str, ...]
|
self.author: Tuple[str, ...]
|
||||||
@@ -17,7 +17,7 @@ class RepoJSONMixin:
|
|||||||
self.short: str
|
self.short: str
|
||||||
self.description: str
|
self.description: str
|
||||||
|
|
||||||
self._info_file = repo_folder / self.INFO_FILE_NAME
|
self._info_file = info_file or repo_folder / self.INFO_FILE_NAME
|
||||||
self._info: Dict[str, Any]
|
self._info: Dict[str, Any]
|
||||||
|
|
||||||
self._read_info_file()
|
self._read_info_file()
|
||||||
|
|||||||
@@ -866,10 +866,11 @@ class Repo(RepoJSONMixin):
|
|||||||
if not target_dir.exists():
|
if not target_dir.exists():
|
||||||
raise ValueError("That target directory does not exist.")
|
raise ValueError("That target directory does not exist.")
|
||||||
|
|
||||||
if not await cog.copy_to(target_dir=target_dir):
|
install_location = await cog.copy_to(target_dir=target_dir)
|
||||||
|
if not install_location:
|
||||||
raise errors.CopyingError("There was an issue during copying of cog's files")
|
raise errors.CopyingError("There was an issue during copying of cog's files")
|
||||||
|
|
||||||
return InstalledModule.from_installable(cog)
|
return InstalledModule.from_installable(cog, install_location)
|
||||||
|
|
||||||
async def install_libraries(
|
async def install_libraries(
|
||||||
self, target_dir: Path, req_target_dir: Path, libraries: Iterable[Installable] = ()
|
self, target_dir: Path, req_target_dir: Path, libraries: Iterable[Installable] = ()
|
||||||
@@ -907,11 +908,11 @@ class Repo(RepoJSONMixin):
|
|||||||
for lib in libraries:
|
for lib in libraries:
|
||||||
if not (
|
if not (
|
||||||
await self.install_requirements(cog=lib, target_dir=req_target_dir)
|
await self.install_requirements(cog=lib, target_dir=req_target_dir)
|
||||||
and await lib.copy_to(target_dir=target_dir)
|
and (install_location := await lib.copy_to(target_dir=target_dir))
|
||||||
):
|
):
|
||||||
failed.append(lib)
|
failed.append(lib)
|
||||||
else:
|
else:
|
||||||
installed.append(InstalledModule.from_installable(lib))
|
installed.append(InstalledModule.from_installable(lib, install_location))
|
||||||
return (tuple(installed), tuple(failed))
|
return (tuple(installed), tuple(failed))
|
||||||
return ((), ())
|
return ((), ())
|
||||||
|
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ def installed_cog(tmpdir):
|
|||||||
cog_path = tmpdir.mkdir("test_repo").mkdir("test_installed_cog")
|
cog_path = tmpdir.mkdir("test_repo").mkdir("test_installed_cog")
|
||||||
info_path = cog_path.join("info.json")
|
info_path = cog_path.join("info.json")
|
||||||
info_path.write_text(json.dumps(INFO_JSON), "utf-8")
|
info_path.write_text(json.dumps(INFO_JSON), "utf-8")
|
||||||
|
location = Path(str(cog_path))
|
||||||
|
|
||||||
cog_info = InstalledModule(Path(str(cog_path)))
|
cog_info = InstalledModule(location, install_location=location)
|
||||||
return cog_info
|
return cog_info
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user