diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | dev/README.rst | 45 | ||||
| -rw-r--r-- | dev/bot/__init__.py | 24 | ||||
| -rw-r--r-- | dev/bot/__main__.py | 34 | ||||
| -rw-r--r-- | dev/bot/cog.py | 33 | ||||
| -rw-r--r-- | docs/changelog.rst | 4 | ||||
| -rw-r--r-- | docs/development.rst | 2 | ||||
| -rw-r--r-- | docs/index.rst | 2 | ||||
| -rw-r--r-- | tox.ini | 2 | 
9 files changed, 148 insertions, 1 deletions
| @@ -134,3 +134,6 @@ dmypy.json  # Vscode  .vscode + +# Development & prototyping environment +/bot/ diff --git a/dev/README.rst b/dev/README.rst new file mode 100644 index 00000000..b1535962 --- /dev/null +++ b/dev/README.rst @@ -0,0 +1,45 @@ +Local Development & Testing +=========================== + +To test your features locally, there are a few possible approaches: + +1. Install your local copy of botcore into a pre-existing project such as bot +2. Use the provided template from the :repo-file:`dev/bot <dev/bot>` folder + +See below for more info on both approaches. + +What's going to be common between them is you'll need to write code to test your feature. +This might mean adding new commands, modifying existing ones, changing utilities, etc. +The steps below should provide most of the groundwork you need, but the exact requirements will +vary by the feature you're working on. + + +Option 1 +-------- +1. Navigate to the project you want to install bot-core in, such as bot or sir-lancebot +2. Run ``pip install /path/to/botcore`` in the project's environment + +   - The path provided to install should be the root directory of this project on your maching. +     That is, the folder which contains the ``pyproject.toml`` file. +   - Make sure to install in the correct environment. Most Python Discord projects use +     poetry, so you can run ``poetry run pip install /path/to/botcore``. + +3. You can now use features from your local bot-core changes. +   To load new changes, run the install command again. + + +Option 2 +-------- +1. Copy the :repo-file:`bot template folder <dev/bot>` to the root of your project. +   This copy is going to be git-ignored, so you're free to modify it however you like. +2. Run the project + +   - Locally: You can run it on your system using ``python -m bot`` +   - Docker: You can run on docker using ``docker compose up -d bot``. + +3. You can now test your changes. You do not need to do anything to reinstall the +   library if you modify your code. + +.. tip:: +   The docker-compose included contains services from our other applications +   to help you test out certain features. Use them as needed. diff --git a/dev/bot/__init__.py b/dev/bot/__init__.py new file mode 100644 index 00000000..71871209 --- /dev/null +++ b/dev/bot/__init__.py @@ -0,0 +1,24 @@ +import asyncio +import logging +import os +import sys + +import botcore + +if os.name == "nt": +    # Change the event loop policy on Windows to avoid exceptions on exit +    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + +# Some basic logging to get existing loggers to show +logging.getLogger().addHandler(logging.StreamHandler()) +logging.getLogger().setLevel(logging.DEBUG) +logging.getLogger("discord").setLevel(logging.ERROR) + + +class Bot(botcore.BotBase): +    """Sample Bot implementation.""" + +    async def setup_hook(self) -> None: +        """Load extensions on startup.""" +        await super().setup_hook() +        asyncio.create_task(self.load_extensions(sys.modules[__name__])) diff --git a/dev/bot/__main__.py b/dev/bot/__main__.py new file mode 100644 index 00000000..00ebdefc --- /dev/null +++ b/dev/bot/__main__.py @@ -0,0 +1,34 @@ +import asyncio +import os + +import aiohttp +import discord +import dotenv +from discord.ext import commands + +import botcore +from . import Bot + +dotenv.load_dotenv() +botcore.utils.apply_monkey_patches() + +roles = os.getenv("ALLOWED_ROLES") +roles = [int(role) for role in roles.split(",")] if roles else [] + +bot = Bot( +    guild_id=int(os.getenv("GUILD_ID")), +    http_session=None,  # type: ignore # We need to instantiate the session in an async context +    allowed_roles=roles, +    command_prefix=commands.when_mentioned_or(os.getenv("PREFIX", "!")), +    intents=discord.Intents.all(), +    description="Bot-core test bot.", +) + + +async def main() -> None: +    """Run the bot.""" +    bot.http_session = aiohttp.ClientSession() +    async with bot: +        await bot.start(os.getenv("TOKEN")) + +asyncio.run(main()) diff --git a/dev/bot/cog.py b/dev/bot/cog.py new file mode 100644 index 00000000..7746c54e --- /dev/null +++ b/dev/bot/cog.py @@ -0,0 +1,33 @@ +from discord.ext import commands + +from . import Bot + + +class Cog(commands.Cog): +    """A simple discord.py cog.""" + +    def __init__(self, _bot: Bot): +        self.bot = _bot + +    @commands.Cog.listener() +    async def on_ready(self) -> None: +        """Print a message when the client (re)connects.""" +        print("Client is ready.") + +    @commands.command() +    async def reload(self, ctx: commands.Context) -> None: +        """Reload all available cogs.""" +        message = await ctx.send(":hourglass_flowing_sand: Reloading") +        for ext in list(self.bot.extensions): +            await self.bot.reload_extension(ext) +        await message.edit(content=":white_check_mark: Done") + +    @commands.command() +    async def ping(self, ctx: commands.Context) -> None: +        """Test if the bot is online.""" +        await ctx.send("We are live!") + + +async def setup(_bot: Bot) -> None: +    """Install the cog.""" +    await _bot.add_cog(Cog(_bot)) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8dce8564..b5d049d9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,10 @@  Changelog  ========= +- :bug:`107` Declare aiodns as a project dependency. +- :support:`107` Add a sample project with boilerplate and documentation explaining how to develop for bot-core. + +  - :release:`7.5.0 <23rd July 2022>`  - :feature:`101` Add a utility to clean a string or referenced message's content diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 00000000..25b8e0a7 --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,2 @@ +.. Stub file to expose the README to sphinx +.. include:: ../dev/README.rst diff --git a/docs/index.rst b/docs/index.rst index 0a375b90..aee7b269 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,6 +17,7 @@ Reference     :caption: Other:     :hidden: +   development     changelog @@ -26,4 +27,5 @@ Extras  * :ref:`genindex`  * :ref:`search`  * :repo-file:`Information <docs/README.md>` +* :doc:`development`  * :doc:`changelog` @@ -3,7 +3,7 @@ max-line-length=120  docstring-convention=all  import-order-style=pycharm  application_import_names=botcore,docs,tests -exclude=.cache,.venv,.git,constants.py +exclude=.cache,.venv,.git,constants.py,bot/  ignore=      B311,W503,E226,S311,T000,E731      # Missing Docstrings | 
