[Docs] Update downloader framework docs (#914)

* Update installable

* Update Repo manager
This commit is contained in:
Will 2017-08-13 19:00:10 -04:00 committed by GitHub
parent 0ba6d9a5af
commit c6762234e6
4 changed files with 133 additions and 73 deletions

View File

@ -1,3 +1,8 @@
__all__ = ["DownloaderException", "GitException", "InvalidRepoName", "ExistingGitRepo",
"MissingGitRepo", "CloningError", "CurrentHashError", "HardResetError",
"UpdateError", "GitDiffError", "PipError"]
class DownloaderException(Exception):
"""
Base class for Downloader exceptions.
@ -14,7 +19,7 @@ class GitException(DownloaderException):
class InvalidRepoName(DownloaderException):
"""
Throw when a repo name is invalid. Check
the message for a more detailed reason.
the message for a more detailed reason.
"""
pass
@ -22,7 +27,7 @@ class InvalidRepoName(DownloaderException):
class ExistingGitRepo(DownloaderException):
"""
Thrown when trying to clone into a folder where a
git repo already exists.
git repo already exists.
"""
pass
@ -30,7 +35,7 @@ class ExistingGitRepo(DownloaderException):
class MissingGitRepo(DownloaderException):
"""
Thrown when a git repo is expected to exist but
does not.
does not.
"""
pass
@ -45,7 +50,7 @@ class CloningError(GitException):
class CurrentHashError(GitException):
"""
Thrown when git returns a non zero exit code attempting
to determine the current commit hash.
to determine the current commit hash.
"""
pass
@ -53,7 +58,7 @@ class CurrentHashError(GitException):
class HardResetError(GitException):
"""
Thrown when there is an issue trying to execute a hard reset
(usually prior to a repo update).
(usually prior to a repo update).
"""
pass

View File

@ -18,42 +18,19 @@ class InstallableType(Enum):
class Installable(RepoJSONMixin):
"""
Base class for anything the Downloader cog can install.
- Modules
- Repo Libraries
- Other stuff?
- Modules
- Repo Libraries
- Other stuff?
"""
INFO_FILE_DESCRIPTION = """
The info.json file may exist inside every package folder in the repo,
it is optional however. This string describes the valid keys within
an info file (and maybe how the Downloader cog uses them).
KEYS (case sensitive):
author (list of strings) - list of names of authors of the cog
bot_version (list of integer) - Min version number of Red in the
format (MAJOR, MINOR, PATCH)
description (string) - A long description of the cog that appears
when a user executes `!cog info`
hidden (bool) - Determines if a cog is available for install.
install_msg (string) - The message that gets displayed when a cog is
installed
required_cogs (map of cogname to repo URL) - A map of required cogs
that this cog depends on. Downloader will not deal with this
functionality but it may be useful for other cogs.
requirements (list of strings) - list of required libraries that are
passed to pip on cog install. SHARED_LIBRARIES do NOT go in this
list.
short (string) - A short description of the cog that appears when
a user executes `!cog list`
tags (list of strings) - A list of strings that are related to the
functionality of the cog. Used to aid in searching.
type (string) - Optional, defaults to COG. Must be either COG or
SHARED_LIBRARY. If SHARED_LIBRARY then HIDDEN will be True.
"""
def __init__(self, location: Path):
"""
Base installable initializer.
:param location: Location (file or folder) to the installable.
"""
super().__init__(location)
@ -90,9 +67,11 @@ class Installable(RepoJSONMixin):
async def copy_to(self, target_dir: Path) -> bool:
"""
Copies this cog/shared_lib to the given directory. This
will overwrite any files in the target directory
:param target_dir: The installation directory to install to.
:return: bool - status of installation
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
"""
if self._location.is_file():
copy_func = shutil.copy2
@ -120,7 +99,8 @@ class Installable(RepoJSONMixin):
def _process_info_file(self, info_file_path: Path=None) -> MutableMapping[str, Any]:
"""
Processes an information file. Loads dependencies among other
information into this object.
information into this object.
:type info_file_path:
:param info_file_path: Optional path to information file, defaults to `self.__info_file`
:return: Raw information dictionary

View File

@ -3,7 +3,7 @@ import json
import os
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from typing import Tuple, MutableMapping
from typing import Tuple, MutableMapping, Union
from subprocess import run as sp_run, PIPE
from sys import executable
import pkgutil
@ -166,7 +166,8 @@ class Repo(RepoJSONMixin):
async def clone(self) -> Tuple[str]:
"""
Clones a new repo.
:return: List of available modules from this repo.
:return: List of available module names from this repo.
"""
exists, path = self._existing_git_repo()
if exists:
@ -203,6 +204,7 @@ class Repo(RepoJSONMixin):
async def current_branch(self) -> str:
"""
Determines the current branch using git commands.
:return: Current branch name
"""
exists, _ = self._existing_git_repo()
@ -226,6 +228,7 @@ class Repo(RepoJSONMixin):
async def current_commit(self, branch: str=None) -> str:
"""
Determines the current commit hash of the repo.
:param branch: Override for repo's branch attribute
:return: Commit hash string
"""
@ -253,8 +256,8 @@ class Repo(RepoJSONMixin):
async def hard_reset(self, branch: str=None) -> None:
"""
Performs a hard reset on the current repo.
:param branch: Override for repo branch attribute.
:return:
"""
if branch is None:
branch = self.branch
@ -280,8 +283,9 @@ class Repo(RepoJSONMixin):
async def update(self) -> (str, str):
"""
Updates the current branch of this repo.
:return: Old commit hash
:return: New commit hash
:return: tuple of (old commit hash, new commit hash)
:rtype: tuple
"""
curr_branch = await self.current_branch()
old_commit = await self.current_commit(branch=curr_branch)
@ -308,9 +312,11 @@ class Repo(RepoJSONMixin):
async def install_cog(self, cog: Installable, target_dir: Path) -> bool:
"""
Copies a cog to the target directory.
:param cog:
:param target_dir:
:return: bool - if installation succeeded
:param Installable cog: Cog to install.
:param pathlib.Path target_dir: Directory to install the cog in.
:return: Installation success status.
:rtype: bool
"""
if cog not in self.available_cogs:
raise DownloaderException("That cog does not exist in this repo")
@ -326,10 +332,12 @@ class Repo(RepoJSONMixin):
async def install_libraries(self, target_dir: Path, libraries: Tuple[Installable]=()) -> bool:
"""
Copies all shared libraries (or a given subset) to the target
directory.
:param target_dir:
:param libraries: A subset of available libraries
:return: bool - all copies succeeded
directory.
:param pathlib.Path target_dir: Directory to install shared libraries to.
:param tuple(Installable) libraries: A subset of available libraries.
:return: Status of all installs.
:rtype: bool
"""
if libraries:
if not all([i in self.available_libraries for i in libraries]):
@ -344,11 +352,13 @@ class Repo(RepoJSONMixin):
async def install_requirements(self, cog: Installable, target_dir: Path) -> bool:
"""
Installs the requirements defined by the requirements
attribute on the cog object and puts them in the given
target directory.
:param cog:
:param target_dir:
:return:
attribute on the cog object and puts them in the given
target directory.
:param Installable cog: Cog for which to install requirements.
:param pathlib.Path target_dir: Path to which to install requirements.
:return: Status of requirements install.
:rtype: bool
"""
if not target_dir.is_dir():
raise ValueError("Target directory is not a directory.")
@ -359,10 +369,12 @@ class Repo(RepoJSONMixin):
async def install_raw_requirements(self, requirements: Tuple[str], target_dir: Path) -> bool:
"""
Installs a list of requirements using pip and places them into
the given target directory.
:param requirements:
:param target_dir:
:return:
the given target directory.
:param tuple(str) requirements: List of requirement names to install via pip.
:param pathlib.Path target_dir: Directory to install requirements to.
:return: Status of all requirements install.
:rtype: bool
"""
if len(requirements) == 0:
return True
@ -388,7 +400,8 @@ class Repo(RepoJSONMixin):
def available_cogs(self) -> Tuple[Installable]:
"""
Returns a list of available cogs (not shared libraries and not hidden).
:return: tuple(installable)
:rtype: tuple(Installable)
"""
# noinspection PyTypeChecker
return tuple(
@ -400,6 +413,8 @@ class Repo(RepoJSONMixin):
def available_libraries(self) -> Tuple[Installable]:
"""
Returns a list of available shared libraries in this repo.
:rtype: tuple(Installable)
"""
# noinspection PyTypeChecker
return tuple(
@ -447,10 +462,12 @@ class RepoManager:
async def add_repo(self, url: str, name: str, branch: str="master") -> Repo:
"""
Adds a repo and clones it.
:param url:
:param name:
:param branch:
:return:
:param url: URL of git repo to clone.
:param name: Internal name of repo.
:param branch: Branch to clone.
:return: New repo object representing cloned repo.
:rtype: Repo
"""
name = self.validate_and_normalize_repo_name(name)
if self.does_repo_exist(name):
@ -469,27 +486,31 @@ class RepoManager:
return r
def get_repo(self, name: str) -> Repo:
def get_repo(self, name: str) -> Union[Repo, None]:
"""
Returns a repo object with the given name.
:param name: Repo name
:return: Repo object or None
:return: Repo object or ``None`` if repo does not exist.
:rtype: Union[Repo, None]
"""
return self._repos.get(name, None)
def get_all_repo_names(self) -> Tuple[str]:
"""
Returns a tuple of all repo names
:return:
:rtype: tuple(str)
"""
# noinspection PyTypeChecker
return tuple(self._repos.keys())
async def delete_repo(self, name: str):
"""
Deletes a repo and its' folders with the given name.
:param name:
:return:
Deletes a repo and its folders with the given name.
:param name: Name of the repo to delete.
:raises MissingGitRepo: If the repo does not exist.
"""
repo = self.get_repo(name)
if repo is None:
@ -506,10 +527,11 @@ class RepoManager:
async def update_all_repos(self) -> MutableMapping[Repo, Tuple[str, str]]:
"""
Calls repo.update() on all repos, returns a mapping of repos
that received new commits to a tuple containing old and
new commit hashes.
Calls :py:meth:`Repo.update` on all repos.
:return:
A mapping of :py:class:`Repo` objects that received new commits to a tuple containing old and
new commit hashes.
"""
ret = {}
for _, repo in self._repos.items():

View File

@ -1,7 +1,45 @@
.. downloader framework reference
Downloader Framework Reference
==============================
Downloader Framework
====================
Info.json
*********
The info.json file may exist inside every package folder in the repo,
it is optional however. This string describes the valid keys within
an info file (and maybe how the Downloader cog uses them).
KEYS (case sensitive):
- ``author`` (list of strings) - list of names of authors of the cog
- ``bot_version`` (list of integer) - Min version number of Red in the format ``(MAJOR, MINOR, PATCH)``
- ``description`` (string) - A long description of the cog that appears when a user executes ```!cog info``.
- ``hidden`` (bool) - Determines if a cog is available for install.
- ``install_msg`` (string) - The message that gets displayed when a cog is installed
- ``required_cogs`` (map of cogname to repo URL) - A map of required cogs that this cog depends on.
Downloader will not deal with this functionality but it may be useful for other cogs.
- ``requirements`` (list of strings) - list of required libraries that are
passed to pip on cog install. ``SHARED_LIBRARIES`` do NOT go in this
list.
- ``short`` (string) - A short description of the cog that appears when
a user executes `!cog list`
- ``tags`` (list of strings) - A list of strings that are related to the
functionality of the cog. Used to aid in searching.
- ``type`` (string) - Optional, defaults to ``COG``. Must be either ``COG`` or
``SHARED_LIBRARY``. If ``SHARED_LIBRARY`` then ``hidden`` will be ``True``.
API Reference
*************
.. automodule:: cogs.downloader.json_mixins
@ -10,14 +48,29 @@ Downloader Framework Reference
.. automodule:: cogs.downloader.installable
Installable
^^^^^^^^^^^
.. autoclass:: Installable
:members:
.. automodule:: cogs.downloader.repo_manager
Repo
^^^^
.. autoclass:: Repo
:members:
Repo Manager
^^^^^^^^^^^^
.. autoclass:: RepoManager
:members:
Exceptions
^^^^^^
.. automodule:: cogs.downloader.errors
:members: