mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[V3 Downloader] Allow to specify minimum and maximum bot version in info.json (#2605)
* feat(downloader): add `min_bot_version` and `max_bot_version` Adds actually working way of specifying minimum and maximum bot version and removes not working `bot_version` BREAKING CHANGE: - removal of `bot_version` attribute in `Installable` * test(downloader): `Installable` tests fix for new bot version attributes * docs(changelog): added changelog entries for this PR
This commit is contained in:
parent
07f127ffe4
commit
24ac111782
@ -60,6 +60,8 @@ Downloader
|
|||||||
* Fixed bug, that caused Downloader to include submodules on cog list (`#2590`_)
|
* Fixed bug, that caused Downloader to include submodules on cog list (`#2590`_)
|
||||||
* ``[p]cog uninstall`` allows to uninstall multiple cogs now (`#2592`_)
|
* ``[p]cog uninstall`` allows to uninstall multiple cogs now (`#2592`_)
|
||||||
* ``[p]cog uninstall`` will now remove cog from installed cogs even if it can't find the cog in install path anymore (`#2595`_)
|
* ``[p]cog uninstall`` will now remove cog from installed cogs even if it can't find the cog in install path anymore (`#2595`_)
|
||||||
|
* ``[p]cog install`` will not allow to install cogs which aren't suitable for installed version of Red anymore (`#2605`_)
|
||||||
|
* Cog Developers now have to use ``min_bot_version`` in form of version string instead of ``bot_version`` in info.json and they can also use ``max_bot_version`` to specify maximum version of Red, more in :doc:`framework_downloader`. (`#2605`_)
|
||||||
|
|
||||||
---
|
---
|
||||||
Mod
|
Mod
|
||||||
@ -141,5 +143,6 @@ Utility Functions
|
|||||||
.. _#2600: https://github.com/Cog-Creators/Red-DiscordBot/pull/2600
|
.. _#2600: https://github.com/Cog-Creators/Red-DiscordBot/pull/2600
|
||||||
.. _#2602: https://github.com/Cog-Creators/Red-DiscordBot/pull/2602
|
.. _#2602: https://github.com/Cog-Creators/Red-DiscordBot/pull/2602
|
||||||
.. _#2604: https://github.com/Cog-Creators/Red-DiscordBot/pull/2604
|
.. _#2604: https://github.com/Cog-Creators/Red-DiscordBot/pull/2604
|
||||||
|
.. _#2605: https://github.com/Cog-Creators/Red-DiscordBot/pull/2605
|
||||||
.. _#2606: https://github.com/Cog-Creators/Red-DiscordBot/pull/2606
|
.. _#2606: https://github.com/Cog-Creators/Red-DiscordBot/pull/2606
|
||||||
.. _#2620: https://github.com/Cog-Creators/Red-DiscordBot/pull/2620
|
.. _#2620: https://github.com/Cog-Creators/Red-DiscordBot/pull/2620
|
||||||
|
|||||||
@ -30,7 +30,10 @@ Keys common to both repo and cog info.json (case sensitive)
|
|||||||
Keys specific to the cog info.json (case sensitive)
|
Keys specific to the cog info.json (case sensitive)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- ``bot_version`` (list of integer) - Min version number of Red in the format ``(MAJOR, MINOR, PATCH)``
|
- ``min_bot_version`` (string) - Min version number of Red in the format ``MAJOR.MINOR.MICRO``
|
||||||
|
|
||||||
|
- ``max_bot_version`` (string) - Max version number of Red in the format ``MAJOR.MINOR.MICRO``,
|
||||||
|
if ``min_bot_version`` is newer than ``max_bot_version``, ``max_bot_version`` will be ignored
|
||||||
|
|
||||||
- ``hidden`` (bool) - Determines if a cog is visible in the cog list for a repo.
|
- ``hidden`` (bool) - Determines if a cog is visible in the cog list for a repo.
|
||||||
|
|
||||||
|
|||||||
@ -119,8 +119,14 @@ class VersionInfo:
|
|||||||
"dev_release": self.dev_release,
|
"dev_release": self.dev_release,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __lt__(self, other: "VersionInfo") -> bool:
|
def _generate_comparison_tuples(
|
||||||
tups: _List[_Tuple[int, int, int, int, int, int, int]] = []
|
self, other: "VersionInfo"
|
||||||
|
) -> _List[
|
||||||
|
_Tuple[int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float]]
|
||||||
|
]:
|
||||||
|
tups: _List[
|
||||||
|
_Tuple[int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float]]
|
||||||
|
] = []
|
||||||
for obj in (self, other):
|
for obj in (self, other):
|
||||||
tups.append(
|
tups.append(
|
||||||
(
|
(
|
||||||
@ -133,8 +139,20 @@ class VersionInfo:
|
|||||||
obj.dev_release if obj.dev_release is not None else _inf,
|
obj.dev_release if obj.dev_release is not None else _inf,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
return tups
|
||||||
|
|
||||||
|
def __lt__(self, other: "VersionInfo") -> bool:
|
||||||
|
tups = self._generate_comparison_tuples(other)
|
||||||
return tups[0] < tups[1]
|
return tups[0] < tups[1]
|
||||||
|
|
||||||
|
def __eq__(self, other: "VersionInfo") -> bool:
|
||||||
|
tups = self._generate_comparison_tuples(other)
|
||||||
|
return tups[0] == tups[1]
|
||||||
|
|
||||||
|
def __le__(self, other: "VersionInfo") -> bool:
|
||||||
|
tups = self._generate_comparison_tuples(other)
|
||||||
|
return tups[0] <= tups[1]
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
ret = f"{self.major}.{self.minor}.{self.micro}"
|
ret = f"{self.major}.{self.minor}.{self.micro}"
|
||||||
if self.releaselevel != self.FINAL:
|
if self.releaselevel != self.FINAL:
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from sys import path as syspath
|
|||||||
from typing import Tuple, Union, Iterable
|
from typing import Tuple, Union, Iterable
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import checks, commands, Config
|
from redbot.core import checks, commands, Config, version_info as red_version_info
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.data_manager import cog_data_path
|
from redbot.core.data_manager import cog_data_path
|
||||||
from redbot.core.i18n import Translator, cog_i18n
|
from redbot.core.i18n import Translator, cog_i18n
|
||||||
@ -303,6 +303,26 @@ class Downloader(commands.Cog):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
ignore_max = cog.min_bot_version > cog.max_bot_version
|
||||||
|
if (
|
||||||
|
cog.min_bot_version > red_version_info
|
||||||
|
or not ignore_max
|
||||||
|
and cog.max_bot_version < red_version_info
|
||||||
|
):
|
||||||
|
await ctx.send(
|
||||||
|
_("This cog requires at least Red version {min_version}").format(
|
||||||
|
min_version=cog.min_bot_version
|
||||||
|
)
|
||||||
|
+ (
|
||||||
|
""
|
||||||
|
if ignore_max
|
||||||
|
else _(" and at most {max_version}").format(max_version=cog.max_bot_version)
|
||||||
|
)
|
||||||
|
+ _(", but you have {current_version}, aborting install.").format(
|
||||||
|
current_version=red_version_info
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if not await repo.install_requirements(cog, self.LIB_PATH):
|
if not await repo.install_requirements(cog, self.LIB_PATH):
|
||||||
libraries = humanize_list(tuple(map(inline, cog.requirements)))
|
libraries = humanize_list(tuple(map(inline, cog.requirements)))
|
||||||
|
|||||||
@ -8,6 +8,8 @@ from typing import MutableMapping, Any, TYPE_CHECKING
|
|||||||
from .log import log
|
from .log import log
|
||||||
from .json_mixins import RepoJSONMixin
|
from .json_mixins import RepoJSONMixin
|
||||||
|
|
||||||
|
from redbot.core import __version__, version_info as red_version_info, VersionInfo
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .repo_manager import RepoManager
|
from .repo_manager import RepoManager
|
||||||
|
|
||||||
@ -72,7 +74,8 @@ class Installable(RepoJSONMixin):
|
|||||||
self.repo_name = self._location.parent.stem
|
self.repo_name = self._location.parent.stem
|
||||||
|
|
||||||
self.author = ()
|
self.author = ()
|
||||||
self.bot_version = (3, 0, 0)
|
self.min_bot_version = red_version_info
|
||||||
|
self.max_bot_version = red_version_info
|
||||||
self.min_python_version = (3, 5, 1)
|
self.min_python_version = (3, 5, 1)
|
||||||
self.hidden = False
|
self.hidden = False
|
||||||
self.disabled = False
|
self.disabled = False
|
||||||
@ -157,10 +160,16 @@ class Installable(RepoJSONMixin):
|
|||||||
self.author = author
|
self.author = author
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bot_version = tuple(info.get("bot_version", [3, 0, 0]))
|
min_bot_version = VersionInfo.from_str(str(info.get("min_bot_version", __version__)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
bot_version = self.bot_version
|
min_bot_version = self.min_bot_version
|
||||||
self.bot_version = bot_version
|
self.min_bot_version = min_bot_version
|
||||||
|
|
||||||
|
try:
|
||||||
|
max_bot_version = VersionInfo.from_str(str(info.get("max_bot_version", __version__)))
|
||||||
|
except ValueError:
|
||||||
|
max_bot_version = self.max_bot_version
|
||||||
|
self.max_bot_version = max_bot_version
|
||||||
|
|
||||||
try:
|
try:
|
||||||
min_python_version = tuple(info.get("min_python_version", [3, 5, 1]))
|
min_python_version = tuple(info.get("min_python_version", [3, 5, 1]))
|
||||||
|
|||||||
@ -83,7 +83,8 @@ def bot_repo(event_loop):
|
|||||||
# Installable
|
# Installable
|
||||||
INFO_JSON = {
|
INFO_JSON = {
|
||||||
"author": ("tekulvw",),
|
"author": ("tekulvw",),
|
||||||
"bot_version": (3, 0, 0),
|
"min_bot_version": "3.0.0",
|
||||||
|
"max_bot_version": "3.0.2",
|
||||||
"description": "A long description",
|
"description": "A long description",
|
||||||
"hidden": False,
|
"hidden": False,
|
||||||
"install_msg": "A post-installation message",
|
"install_msg": "A post-installation message",
|
||||||
@ -96,7 +97,8 @@ INFO_JSON = {
|
|||||||
|
|
||||||
LIBRARY_INFO_JSON = {
|
LIBRARY_INFO_JSON = {
|
||||||
"author": ("seputaes",),
|
"author": ("seputaes",),
|
||||||
"bot_version": (3, 0, 0),
|
"min_bot_version": "3.0.0",
|
||||||
|
"max_bot_version": "3.0.2",
|
||||||
"description": "A long library description",
|
"description": "A long library description",
|
||||||
"hidden": False, # libraries are always hidden, this tests it will be flipped
|
"hidden": False, # libraries are always hidden, this tests it will be flipped
|
||||||
"install_msg": "A library install message",
|
"install_msg": "A library install message",
|
||||||
|
|||||||
@ -5,12 +5,15 @@ import pytest
|
|||||||
|
|
||||||
from redbot.pytest.downloader import *
|
from redbot.pytest.downloader import *
|
||||||
from redbot.cogs.downloader.installable import Installable, InstallableType
|
from redbot.cogs.downloader.installable import Installable, InstallableType
|
||||||
|
from redbot.core import VersionInfo
|
||||||
|
|
||||||
|
|
||||||
def test_process_info_file(installable):
|
def test_process_info_file(installable):
|
||||||
for k, v in INFO_JSON.items():
|
for k, v in INFO_JSON.items():
|
||||||
if k == "type":
|
if k == "type":
|
||||||
assert installable.type == InstallableType.COG
|
assert installable.type == InstallableType.COG
|
||||||
|
elif k in ("min_bot_version", "max_bot_version"):
|
||||||
|
assert getattr(installable, k) == VersionInfo.from_str(v)
|
||||||
else:
|
else:
|
||||||
assert getattr(installable, k) == v
|
assert getattr(installable, k) == v
|
||||||
|
|
||||||
@ -19,6 +22,8 @@ def test_process_lib_info_file(library_installable):
|
|||||||
for k, v in LIBRARY_INFO_JSON.items():
|
for k, v in LIBRARY_INFO_JSON.items():
|
||||||
if k == "type":
|
if k == "type":
|
||||||
assert library_installable.type == InstallableType.SHARED_LIBRARY
|
assert library_installable.type == InstallableType.SHARED_LIBRARY
|
||||||
|
elif k in ("min_bot_version", "max_bot_version"):
|
||||||
|
assert getattr(library_installable, k) == VersionInfo.from_str(v)
|
||||||
elif k == "hidden":
|
elif k == "hidden":
|
||||||
# libraries are always hidden, even if False
|
# libraries are always hidden, even if False
|
||||||
assert library_installable.hidden is True
|
assert library_installable.hidden is True
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user