[Docs] Cog Manager (#901)

* Cog manager docs

* Oops, kinda need this
This commit is contained in:
Will 2017-08-12 18:03:29 -04:00 committed by palmtree5
parent 85b0f34395
commit f78c33445c
4 changed files with 62 additions and 38 deletions

View File

@ -10,20 +10,15 @@ from core import checks
from core.config import Config from core.config import Config
from core.utils.chat_formatting import box from core.utils.chat_formatting import box
__all__ = ["CogManager"]
class CogManagerException(Exception):
pass
class InvalidPath(CogManagerException):
pass
class NoModuleFound(CogManagerException):
pass
class CogManager: class CogManager:
"""
This module allows you to load cogs from multiple directories and even from outside the bot
directory. You may also set a directory for downloader to install new cogs to, the default
being the :code:`cogs/` folder in the root bot directory.
"""
def __init__(self, paths: Tuple[str]=(), bot_dir: Path=Path.cwd()): def __init__(self, paths: Tuple[str]=(), bot_dir: Path=Path.cwd()):
self.conf = Config.get_conf(self, 2938473984732, True) self.conf = Config.get_conf(self, 2938473984732, True)
self.conf.register_global( self.conf.register_global(
@ -35,8 +30,7 @@ class CogManager:
async def paths(self) -> Tuple[Path, ...]: async def paths(self) -> Tuple[Path, ...]:
""" """
This will return all currently valid path directories. All currently valid path directories.
:return:
""" """
conf_paths = await self.conf.paths() conf_paths = await self.conf.paths()
other_paths = self._paths other_paths = self._paths
@ -50,8 +44,7 @@ class CogManager:
async def install_path(self) -> Path: async def install_path(self) -> Path:
""" """
Returns the install path for 3rd party cogs. The install path for 3rd party cogs.
:return:
""" """
p = Path(await self.conf.install_path()) p = Path(await self.conf.install_path())
return p.resolve() return p.resolve()
@ -60,8 +53,16 @@ class CogManager:
""" """
Install path setter, will return the absolute path to Install path setter, will return the absolute path to
the given path. the given path.
:param path:
:return: .. note::
The bot will not remember your old cog install path which means
that ALL PREVIOUSLY INSTALLED COGS will now be unfindable.
:param pathlib.Path path:
The new directory for cog installs.
:raises ValueError:
If :code:`path` is not an existing directory.
""" """
if not path.is_dir(): if not path.is_dir():
raise ValueError("The install path must be an existing directory.") raise ValueError("The install path must be an existing directory.")
@ -73,8 +74,12 @@ class CogManager:
def _ensure_path_obj(path: Union[Path, str]) -> Path: def _ensure_path_obj(path: Union[Path, str]) -> Path:
""" """
Guarantees an object will be a path object. Guarantees an object will be a path object.
:param path: :param path:
:return: :type path:
pathlib.Path or str
:rtype:
pathlib.Path
""" """
try: try:
path.exists() path.exists()
@ -88,10 +93,12 @@ class CogManager:
a side effect of removing all invalid paths from the saved path a side effect of removing all invalid paths from the saved path
list. list.
Will raise InvalidPath if given anything that does not resolve to
a directory.
:param path: :param path:
:return: Path to add.
:type path:
pathlib.Path or str
:raises ValueError:
If :code:`path` does not resolve to an existing directory.
""" """
path = self._ensure_path_obj(path) path = self._ensure_path_obj(path)
@ -100,7 +107,7 @@ class CogManager:
path = path.resolve() path = path.resolve()
if not path.is_dir(): if not path.is_dir():
raise InvalidPath("'{}' is not a valid directory.".format(path)) raise ValueError("'{}' is not a valid directory.".format(path))
if path == await self.install_path(): if path == await self.install_path():
raise ValueError("Cannot add the install path as an additional path.") raise ValueError("Cannot add the install path as an additional path.")
@ -112,8 +119,13 @@ class CogManager:
async def remove_path(self, path: Union[Path, str]) -> Tuple[Path, ...]: async def remove_path(self, path: Union[Path, str]) -> Tuple[Path, ...]:
""" """
Removes a path from the current paths list. Removes a path from the current paths list.
:param path:
:param path: Path to remove.
:type path:
pathlib.Path or str
:return: :return:
Tuple of new valid paths.
:rtype: tuple
""" """
path = self._ensure_path_obj(path) path = self._ensure_path_obj(path)
all_paths = list(await self.paths()) all_paths = list(await self.paths())
@ -125,19 +137,25 @@ class CogManager:
async def set_paths(self, paths_: List[Path]): async def set_paths(self, paths_: List[Path]):
""" """
Sets the current paths list. Sets the current paths list.
:param paths_:
:return: :param List[pathlib.Path] paths_:
List of paths to set.
""" """
str_paths = [str(p) for p in paths_] str_paths = [str(p) for p in paths_]
await self.conf.paths.set(str_paths) await self.conf.paths.set(str_paths)
async def find_cog(self, name: str) -> ModuleSpec: async def find_cog(self, name: str) -> ModuleSpec:
""" """
Finds a cog in the list of available path. Finds a cog in the list of available paths.
Raises NoModuleFound if unavailable.
:param name: :param name:
Name of the cog to find.
:raises RuntimeError:
If there is no cog with the given name.
:return: :return:
A module spec to be used for specialized cog loading.
:rtype:
importlib.machinery.ModuleSpec
""" """
resolved_paths = [str(p.resolve()) for p in await self.paths()] resolved_paths = [str(p.resolve()) for p in await self.paths()]
for finder, module_name, _ in pkgutil.iter_modules(resolved_paths): for finder, module_name, _ in pkgutil.iter_modules(resolved_paths):
@ -146,7 +164,7 @@ class CogManager:
if spec: if spec:
return spec return spec
raise NoModuleFound("No module by the name of '{}' was found" raise RuntimeError("No module by the name of '{}' was found"
" in any available path.".format(name)) " in any available path.".format(name))
@staticmethod @staticmethod
@ -156,7 +174,6 @@ class CogManager:
any time that a new module has been installed to a cog directory. any time that a new module has been installed to a cog directory.
*I think.* *I think.*
:return:
""" """
invalidate_caches() invalidate_caches()

View File

@ -11,8 +11,6 @@ import discord
import aiohttp import aiohttp
import asyncio import asyncio
from core.cog_manager import NoModuleFound
log = logging.getLogger("red") log = logging.getLogger("red")
OWNER_DISCLAIMER = ("⚠ **Only** the person who is hosting Red should be " OWNER_DISCLAIMER = ("⚠ **Only** the person who is hosting Red should be "
@ -30,7 +28,7 @@ class Core:
"""Loads a package""" """Loads a package"""
try: try:
spec = await ctx.bot.cog_mgr.find_cog(cog_name) spec = await ctx.bot.cog_mgr.find_cog(cog_name)
except NoModuleFound: except RuntimeError:
await ctx.send("No module by that name was found in any" await ctx.send("No module by that name was found in any"
" cog path.") " cog path.")
return return

View File

@ -0,0 +1,8 @@
.. cog manager docs
===========
Cog Manager
===========
.. automodule:: core.cog_manager
:members:

View File

@ -17,6 +17,7 @@ Welcome to Red - Discord Bot's documentation!
:caption: Red Development Framework Reference: :caption: Red Development Framework Reference:
framework_bank framework_bank
framework_cogmanager
framework_config framework_config
framework_downloader framework_downloader