sopel-irc / sopel

:robot::speech_balloon: An easy-to-use and highly extensible IRC Bot framework. Formerly Willie.
https://sopel.chat
Other
948 stars 403 forks source link

Broken plugin symlink -> `PluginError` in CLI #2269

Closed dgw closed 10 months ago

dgw commented 2 years ago

Description

The sopel-plugins command should gracefully handle things that look like plugins but can't be loaded. It does this in some cases (like Python file plugins with syntax errors), but not all. There's room for improvement.

For example, I recently symlinked a file in ~/.sopel/plugins so it would point to my local repository for that plugin (not yet converted to an entry-point or package) for testing. I did the ln -s command wrong, so the link was broken: pluginfile.py -> ./pluginfile.py, which is a circular reference.

Logs

Traceback (most recent call last):
  File "/home/dgw/.local/bin/sopel-plugins", line 33, in <module>
    sys.exit(load_entry_point('sopel', 'console_scripts', 'sopel-plugins')())
  File "/home/dgw/github/sopel/sopel/cli/plugins.py", line 556, in main
    return handle_list(options)
  File "/home/dgw/github/sopel/sopel/cli/plugins.py", line 174, in handle_list
    for name, info in plugins.get_usable_plugins(settings).items()
  File "/home/dgw/github/sopel/sopel/plugins/__init__.py", line 225, in get_usable_plugins
    plugins_info = collections.OrderedDict(
  File "/home/dgw/github/sopel/sopel/plugins/__init__.py", line 225, in <genexpr>
    plugins_info = collections.OrderedDict(
  File "/home/dgw/github/sopel/sopel/plugins/__init__.py", line 185, in enumerate_plugins
    for plugin in all_plugins:
  File "/home/dgw/github/sopel/sopel/plugins/__init__.py", line 124, in find_directory_plugins
    yield handlers.PyFilePlugin(abspath)
  File "/home/dgw/github/sopel/sopel/plugins/handlers.py", line 440, in __init__
    raise exceptions.PluginError('Invalid Sopel plugin: %s' % filename)
sopel.plugins.exceptions.PluginError: Invalid Sopel plugin: /home/dgw/.sopel/plugins/bombbot.py

Environment

dgw commented 10 months ago

Just to note, this came up again on IRC today and I reverified it with Python 3.10.12 on Ubuntu 22.04 (WSL1) + current master (d9b6a74f1d4835ecc6544881ad5b38338e1a0f4f). Breaks both sopel-plugins and sopel, the latter even if the config uses enable-only for loading plugins and broken symlink is for a plugin that isn't listed in core.enable. Updated traceback:

Traceback (most recent call last):
  File "/home/dgw/.local/bin/sopel-plugins", line 8, in <module>
    sys.exit(main())
  File "/home/dgw/github/sopel-irc/sopel/sopel/cli/plugins.py", line 555, in main
    return handle_list(options)
  File "/home/dgw/github/sopel-irc/sopel/sopel/cli/plugins.py", line 174, in handle_list
    for name, info in plugins.get_usable_plugins(settings).items()
  File "/home/dgw/github/sopel-irc/sopel/sopel/plugins/__init__.py", line 228, in get_usable_plugins
    plugins_info = collections.OrderedDict(
  File "/home/dgw/github/sopel-irc/sopel/sopel/plugins/__init__.py", line 228, in <genexpr>
    plugins_info = collections.OrderedDict(
  File "/home/dgw/github/sopel-irc/sopel/sopel/plugins/__init__.py", line 188, in enumerate_plugins
    for plugin in all_plugins:
  File "/home/dgw/github/sopel-irc/sopel/sopel/plugins/__init__.py", line 127, in find_directory_plugins
    yield handlers.PyFilePlugin(abspath)
  File "/home/dgw/github/sopel-irc/sopel/sopel/plugins/handlers.py", line 477, in __init__
    raise exceptions.PluginError('Invalid Sopel plugin: %s' % filename)
sopel.plugins.exceptions.PluginError: Invalid Sopel plugin: /home/dgw/.sopel/plugins/duel.py
SnoopJ commented 10 months ago

Confirmed that this does impact Windows as well as Linux (and presumably MacOS, but I cannot test this). I have a test for the sopel-plugins command that reproduces the fault, will open a PR once I have a tentative fix. I can probably adapt my test to work more directly with the core of Sopel, I just couldn't find a suitable example to work from in the tests.