Skip to content

Commit

Permalink
fix: fill patch catch on plugin load/unload
Browse files Browse the repository at this point in the history
Also, update docs on `tutor config save`.

Note that we had to fix an issue where the plugin unload callback was
being called too late.
  • Loading branch information
regisb committed Dec 8, 2023
1 parent 11ba17a commit 55d466e
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 27 deletions.
4 changes: 0 additions & 4 deletions docs/plugins/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ Enable/disable a plugin::
tutor plugins enable myplugin
tutor plugins disable myplugin

After enabling or disabling a plugin, the environment should be re-generated with::

tutor config save

The full plugins CLI is described in the :ref:`reference documentation <cli_plugins>`.

.. _existing_plugins:
Expand Down
4 changes: 0 additions & 4 deletions docs/plugins/v0/gettingstarted.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ You can then enable your newly-created plugin::

tutor plugins enable googleanalytics

Update your environment to apply changes from your plugin::

tutor config save

You should be able to view your changes in every LMS and CMS settings file::

grep -r googleanalytics "$(tutor config printroot)/env/apps/openedx/settings/"
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ Our plugin is disabled, for now. To enable it, we run::
$ tutor plugins enable myplugin
Plugin myplugin enabled
Configuration saved to /home/yourusername/.local/share/tutor/config.yml
You should now re-generate your environment with `tutor config save`.
Environment generated in /home/yourusername/.local/share/tutor/env

At this point you could re-generate your environment with ``tutor config save``, but there would not be any change to your environment... because the plugin does not do anything. So let's get started and make some changes.
At this point your environment was updated, but there would not be any change there... because the plugin does not do anything. So let's get started and make some changes.

Modifying existing files with patches
-------------------------------------
Expand Down
6 changes: 4 additions & 2 deletions tutor/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,9 @@ def _enable_plugins(root: str) -> None:
enable_plugins(config)


@hooks.Actions.PLUGIN_UNLOADED.add()
# This is run with a very high priority such that it is called before the plugin hooks
# are actually cleared.
@hooks.Actions.PLUGIN_UNLOADED.add(priority=hooks.priorities.HIGH - 1)
def _remove_plugin_config_overrides_on_unload(
plugin: str, _root: str, config: Config
) -> None:
Expand All @@ -342,7 +344,7 @@ def _remove_plugin_config_overrides_on_unload(
fmt.echo_info(f" config - removing entry: {key}={value}")


@hooks.Actions.PLUGIN_UNLOADED.add(priority=100)
@hooks.Actions.PLUGIN_UNLOADED.add(priority=hooks.priorities.LOW)
def _update_enabled_plugins_on_unload(_plugin: str, _root: str, config: Config) -> None:
"""
Update the list of enabled plugins.
Expand Down
3 changes: 3 additions & 0 deletions tutor/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ def patch(self, name: str, separator: str = "\n", suffix: str = "") -> str:
try:
patches.append(self.render_str(patch))
except exceptions.TutorError:
import ipdb

ipdb.set_trace()
fmt.echo_error(f"Error rendering patch '{name}':\n{patch}")
raise
rendered = separator.join(patches)
Expand Down
32 changes: 17 additions & 15 deletions tutor/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,32 @@


@hooks.Actions.PLUGINS_LOADED.add()
def _convert_plugin_patches() -> None:
def _fill_patch_cache_on_load() -> None:
"""
Some patches are added as (name, content) tuples with the ENV_PATCHES
filter. We convert these patches to add them to ENV_PATCHES_DICT. This makes it
easier for end-user to declare patches, and it's more performant.
This action is run after plugins have been loaded.
"""
ENV_PATCHES_DICT.clear()
patches: t.Iterable[tuple[str, str]] = hooks.Filters.ENV_PATCHES.iterate()
for name, content in patches:
ENV_PATCHES_DICT.setdefault(name, [])
ENV_PATCHES_DICT[name].append(content)
_fill_patches_cache()


@hooks.Actions.PLUGIN_UNLOADED.add()
def _clear_plugin_patches(plugin: str, root: str, _config: Config) -> None:
def _fill_patch_cache_on_unload(plugin: str, root: str, _config: Config) -> None:
"""
After disabling a plugin, ENV_PATCHES_DICT should be cleared
and re-calculated.
This action is run after plugins have been unloaded.
"""
_fill_patches_cache()


def _fill_patches_cache() -> None:
"""
Some patches are added as (name, content) tuples with the ENV_PATCHES
filter. We convert these patches to add them to ENV_PATCHES_DICT. This makes it
easier for end-user to declare patches, and it's more performant.
"""
ENV_PATCHES_DICT.clear()
patches: t.Iterable[tuple[str, str]] = hooks.Filters.ENV_PATCHES.iterate()
for name, content in patches:
ENV_PATCHES_DICT.setdefault(name, [])
ENV_PATCHES_DICT[name].append(content)


def is_installed(name: str) -> bool:
Expand Down Expand Up @@ -135,6 +137,6 @@ def unload(plugin: str) -> None:
hooks.clear_all(context=hooks.Contexts.app(plugin).name)


@hooks.Actions.PLUGIN_UNLOADED.add(priority=50)
@hooks.Actions.PLUGIN_UNLOADED.add(priority=hooks.priorities.HIGH)
def _unload_on_disable(plugin: str, _root: str, _config: Config) -> None:
unload(plugin)

0 comments on commit 55d466e

Please sign in to comment.