Fix wrong info being loaded into InstalledModule (#6720)

This commit is contained in:
Jakub Kuczys
2026-05-24 20:55:15 +02:00
committed by GitHub
parent 174237ae06
commit 443fa9f64f
5 changed files with 55 additions and 27 deletions
+5 -4
View File
@@ -154,9 +154,10 @@ async def installed_cogs() -> Tuple[InstalledModule, ...]:
"""
installed = await _config.installed_cogs()
install_path = await _cog_mgr.install_path()
# noinspection PyTypeChecker
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 cog_json in repo_json.values()
)
@@ -174,7 +175,7 @@ async def installed_libraries() -> Tuple[InstalledModule, ...]:
installed = await _config.installed_libraries()
# noinspection PyTypeChecker
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 lib_json in repo_json.values()
)
@@ -388,8 +389,8 @@ async def _install_cogs(
for commit, cogs_to_install in cogs_by_commit.items():
await repo.checkout(commit)
for cog in cogs_to_install:
if await cog.copy_to(await _cog_mgr.install_path()):
installed.append(InstalledModule.from_installable(cog))
if install_location := await cog.copy_to(await _cog_mgr.install_path()):
installed.append(InstalledModule.from_installable(cog, install_location))
else:
failed.append(cog)
await repo.checkout(exit_to_commit)
+40 -15
View File
@@ -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.
Parameters
@@ -97,7 +104,7 @@ class Installable(RepoJSONMixin):
self.tags: Tuple[str, ...]
self.type: InstallableType
super().__init__(location)
super().__init__(location, info_file=info_file)
def __eq__(self, other: Any) -> bool:
# noinspection PyProtectedMember
@@ -111,14 +118,14 @@ class Installable(RepoJSONMixin):
"""`str` : The name of this package."""
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
will overwrite any files in the target directory.
:param pathlib.Path target_dir: The installation directory to install to.
:return: Status of installation
:rtype: bool
:return: Install location of the cog or None in case of copy failure.
:rtype: `Path`, optional
"""
copy_func: Callable[..., Any]
if self._location.is_file():
@@ -126,13 +133,14 @@ class Installable(RepoJSONMixin):
else:
copy_func = functools.partial(shutil.copytree, dirs_exist_ok=True)
dst = target_dir / self._location.name
# noinspection PyBroadException
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
log.exception("Error occurred when copying path: %s", self._location)
return False
return True
return None
return dst
def _read_info_file(self) -> None:
super()._read_info_file()
@@ -160,8 +168,13 @@ class InstalledModule(Installable):
commit: str = "",
pinned: bool = False,
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
# this is here so that Downloader could use real repo name instead of "MISSING_REPO"
self._json_repo_name = json_repo_name
@@ -178,10 +191,10 @@ class InstalledModule(Installable):
@classmethod
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:
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", ""))
pinned = cast(bool, data.get("pinned", False))
@@ -192,14 +205,26 @@ class InstalledModule(Installable):
else:
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(
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
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(
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,
)
+3 -3
View File
@@ -1,6 +1,6 @@
import json
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 .log import log
@@ -9,7 +9,7 @@ from .log import log
class RepoJSONMixin:
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.author: Tuple[str, ...]
@@ -17,7 +17,7 @@ class RepoJSONMixin:
self.short: 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._read_info_file()
+5 -4
View File
@@ -866,10 +866,11 @@ class Repo(RepoJSONMixin):
if not target_dir.exists():
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")
return InstalledModule.from_installable(cog)
return InstalledModule.from_installable(cog, install_location)
async def install_libraries(
self, target_dir: Path, req_target_dir: Path, libraries: Iterable[Installable] = ()
@@ -907,11 +908,11 @@ class Repo(RepoJSONMixin):
for lib in libraries:
if not (
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)
else:
installed.append(InstalledModule.from_installable(lib))
installed.append(InstalledModule.from_installable(lib, install_location))
return (tuple(installed), tuple(failed))
return ((), ())
+2 -1
View File
@@ -129,8 +129,9 @@ def installed_cog(tmpdir):
cog_path = tmpdir.mkdir("test_repo").mkdir("test_installed_cog")
info_path = cog_path.join("info.json")
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