Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin: new interface #1479

Merged
merged 30 commits into from
May 2, 2019
Merged

plugin: new interface #1479

merged 30 commits into from
May 2, 2019

Conversation

Exirel
Copy link
Contributor

@Exirel Exirel commented Feb 12, 2019

I was playing for a long time with the idea of a unified Sopel's Plugin interface: a way to abstract how plugins are loaded from the core, so that you can implement various way of finding and loading them without having to change how the bot behave and interact with commands, rules, events, etc.

This PR slightly changes how callables are registered, and totally change how they are reloaded.

Plugin Interface

The Plugin Interface is represented by the sopel.plugins.handlers.AbstractPluginHandler:

  • plugin.load(): load the plugin in sys.modules
  • plugin.reload(): reload the plugin
  • plugin.configure(settings): handle the configuration wizard for the plugin (if necessary)
  • plugin.setup(bot): setup the plugin (if necessary)
  • plugin.register(bot): register the plugin with the bot
  • plugin.shutdown(bot): take action on shutdown (if necessary)
  • plugin.is_loaded(): tell if the plugin is loaded
  • plugin.has_*() (configure, setup, shutdown): tell if the plugin has this particular method

Under the hood, I kept a lot of what is in sopel.loader, so it isn't a change that big!

What's next?

I would like to add this kind of plugin:

  • Python setup.py Entry Point based plugins: a Python package could define an entry point, and that would be used to discover plugins much more efficiently than the old technique of package namespace (as used by sopel_modules.*),
  • Python object plugins: an handler that would not take a python module, but an object, to gather its callable, its configure, setup, and shutdown methods,

but that'll be for another day!

Related issues, PR, and future works

@Exirel
Copy link
Contributor Author

Exirel commented Feb 12, 2019

This PR is kind of related to #1471, as it modifies Sopel's internals, and it will definitively makes CLI tools easier to make.

For instance, it'll be much easier to implement a "list all plugins" CLI tool, or "configure this module in particular", etc.

@Exirel
Copy link
Contributor Author

Exirel commented Feb 12, 2019

Edit: fixed!


Meh. Travis found a kind of cyclic import. Fine. I'll have to fix that one way or another. That'll be for tomorrow!

@Exirel
Copy link
Contributor Author

Exirel commented Mar 25, 2019

As said on IRC:

11:16:32 Yup, indeed, I forgot about config.core.extra. x)

So I need to update enumerate_plugins to load plugins from these directories ("extra" is a list).

@Exirel
Copy link
Contributor Author

Exirel commented Mar 25, 2019

As said on IRC: I merged #1490 in, so this PR will handle everything related to plugin's loading & reloading.

Also: so many things to fix, make, improve, and else. 😄

@Exirel
Copy link
Contributor Author

Exirel commented Mar 25, 2019

I've figure out a way to:

  • remove a circular import problem between sopel.loader, sopel.config, and sopel.plugins
  • reduce the usage of sopel.loader to a very minimal set of functions
  • put everything into sopel.cli.run and sopel.plugins instead

but I didn't add tests for sopel.plugins, which is not good, and I need to fix that.

And then, eventually, I'll ask for a review!

@Exirel Exirel force-pushed the plugin-interface branch 4 times, most recently from d31ac46 to ab8f174 Compare March 26, 2019 15:45
@dgw
Copy link
Member

dgw commented Apr 3, 2019

Not dug into this yet because it's still tagged WIP, but does this basically replace #990, #1053, and possibly other PRs that deal with module loading/unloading/reloading?

@Exirel
Copy link
Contributor Author

Exirel commented Apr 4, 2019

Yup, it does. It's not perfect, because I do not handle (yet) sub-module reloading, but that'll come in later.

docs/source/plugin.rst Outdated Show resolved Hide resolved
@Exirel
Copy link
Contributor Author

Exirel commented Apr 12, 2019

So, for testing purpose, I need #1557 to be merged: I want to test the startup routine of the bot, when it loads plugins. And for that, I need to be able to stop the JobScheduler, otherwise the test suite never stop running. That could be annoying.

Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I didn't go through the whole diff again, just a patchwork of changes made since my last review. But this is "core" enough to Sopel's operation that, once merged, any issues will probably bubble up very quickly as we all work on other stuff.

I'd like a review from one other @sopel-irc/rockstars before merging, so hopefully someone else is up to the task! 😅

Copy link
Contributor

@HumorBaby HumorBaby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up coming across some issues while testing this PR, but it's all related to the CLI (I'll put these in another issue). The plugin interface, however, looks good to me 🚀 (reload not testing given all the issues it has now anyway... can't be worse 😅, so it may be better to get this in, then re-frame the reload issues in the context of this new interface).

sopel/cli/run.py Show resolved Hide resolved
@Exirel
Copy link
Contributor Author

Exirel commented May 2, 2019

I ended up coming across some issues while testing this PR, but it's all related to the CLI

What kind of issues? 😮

@dgw dgw merged commit dd15c66 into sopel-irc:master May 2, 2019
@dgw
Copy link
Member

dgw commented May 2, 2019

I trust @HumorBaby to open that other issue when he's ready. Unlike some of us (*cough* me *cough*), he's good at remembering what he promised to do. 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants