From e41613e358925c49a414f30b5c754daa95772e14 Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Thu, 30 Jan 2025 12:39:26 +0800 Subject: [PATCH 1/2] [docs] document plugin/subplugin type deprecation --- docs/apis/plugintypes/index.md | 140 ++++++++++++++++++ docs/devupdate.md | 107 +++++++++++++ .../development/policies/deprecation/index.md | 1 + general/development/tools/metadata/index.md | 4 + 4 files changed, 252 insertions(+) diff --git a/docs/apis/plugintypes/index.md b/docs/apis/plugintypes/index.md index 49d939ee49..da0e06cc31 100644 --- a/docs/apis/plugintypes/index.md +++ b/docs/apis/plugintypes/index.md @@ -132,6 +132,146 @@ foreach ($pluginman->get_plugin_types() as $type => $dir) { +## Plugin type deprecation + + + +When a plugin or subplugin type is no longer needed or is replaced by another plugin type, it should be deprecated. +Using `components.json` or `subplugins.json` plugin types and subplugin types, respectively, can be marked as deprecated. + +The process for plugin/subplugin type deprecation differs slightly to normal [Deprecation](/general/development/policies/deprecation) process. +Unlike with code deprecation, where the deprecated class or method is usually expected to remain functional during the deprecation window, deprecated plugin/subplugin types are treated as end-of-life as soon as they are deprecated. + +Once deprecated, core will exclude plugins of the respective plugin type when performing common core-plugin communication, such as with hooks, callbacks, events, etc. +In the case of subplugins, the expectation is that the component code (the component under which the subplugins reside), will have been updated and all references to the subplugins removed/replaced, before the time of deprecation. + +Class autoloading and string resolution is still supported during the deprecation window, to assist with any plugin migration scripts that may be required. + +:::info limitations +Whilst both plugin and subplugin types can be deprecated, only those plugin types _not_ supporting subplugins can be deprecated presently. +::: + +### Deprecation process + +Deprecation follows a 3 stage process: + +1. The plugin/subplugin type is marked as deprecated (a core version bump is also required). +2. The plugin/subplugin type is marked as deleted (a core version bump is also required). +3. Final removal of the plugin/subplugin type from the respective config file. + +During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. This stage gives admins time to remove the affected plugins from the site, or migrate them to their replacement plugins. + +In second stage deprecation (deletion), if any affected plugins are still present (i.e. have not been uninstalled/migrated yet) site upgrade will be blocked. These plugins must be removed before continuing with site upgrade. + +In final stage deprecation (final removal), the relevant config changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. + +### Deprecating a plugin type + +To mark a plugin type as deprecated or deleted, edit `lib/components.json`, remove the plugin type from the `plugintypes` object and add it to `deprecatedplugintypes`. To mark a plugin type for stage 2 deprecation (deletion), edit the same file and move the plugin type from the `deprecatedplugintypes` object to the `deletedplugintypes` object. + +:::info Remember +Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. +::: + +:::tip Example of plugin type deprecation config values + +To mark a plugin type as deprecated in `components.json`, the plugin type should be removed from the `plugintypes` object, and added to a new `deprecatedplugintypes` object. + +```json title="lib/components.json demonstrating first stage deprecation of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deprecatedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +To mark a plugin type as deleted in `components.json`, the plugin type should be removed from the `deprecatedplugintypes` object, and added to a new `deletedplugintypes` object. If the `deprecatedplugintypes` object is now empty, it may be removed entirely from config. + +```json title="lib/components.json demonstrating second stage deprecation (deletion) of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deletedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +Third stage deprecation just removes the plugin type from the `deletedplugintypes` object. If the `deletedplugintypes` object is now empty, it may be removed entirely from config. + +```json title="lib/components.json demonstrating final stage deprecation of a plugin type. The process is the same for subplugin types." +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, +} +``` + +::: + +### Deprecating a subplugin type + +To mark a subplugin type as deprecated, edit the component's `subplugins.json` file, remove the subplugin type from the `subplugintypes` object and add it to the `deprecatedsubplugintypes` object. The mark a subplugin type for stage 2 deprecation (deletion), edit the same file and move the subplugin type from the `deprecatedsubplugintypes` object to the `deletedsubplugintypes` object. + +Following deletion, the plugin/subplugin type can be removed from the respective JSON entirely. + +:::info Remember +Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. +::: + +:::tip Example of subplugin type deprecation config values + +To mark a subplugin type as deprecated in a component's `subplugins.json`, the subplugin type should be removed from the `subplugintypes` object, and added to a new `deprecatedsubplugintypes` object. + +```json title="mod/lti/db/subplugins.json demonstrating first stage deprecation of a subplugin type" +{ + "subplugintypes": { + "ltiservice": "service" + }, + "deprecatedsubplugintypes": { + "ltisource": "source" + } +} +``` + +To mark a subplugin type as deleted in a component's `subplugins.json`, the subplugin type should be removed from the `deprecatedsubplugintypes` object, and added to a new `deletedsubplugintypes` object. If the `deprecatedsubplugintypes` object is now empty, it may be removed entirely from config. + +```json title="mod/lti/db/subplugins.json demonstrating second stage deprecation (deletion) of a subplugin type" +{ + "subplugintypes": { + "ltiservice": "service" + }, + "deletedsubplugintypes": { + "ltisource": "source" + } +} +``` + +Third stage deprecation just removes the subplugin type from the `deletedsubplugintypes` object. If this object is then empty, it may be removed entirely from config. + +```json title="mod/lti/db/subplugins.json demonstrating final stage deprecation of a subplugin type." +{ + "subplugintypes": { + "ltiservice": "service" + } +} +``` + +::: + ## See also - [Guidelines for contributing code](https://docs.moodle.org/dev/Guidelines_for_contributed_code) diff --git a/docs/devupdate.md b/docs/devupdate.md index ad4d87ab69..e9f34d09ff 100644 --- a/docs/devupdate.md +++ b/docs/devupdate.md @@ -113,3 +113,110 @@ $activity-icon-interactivecontent-bg: #c70827; Moodle has updated the version of PHPUnit used in core to version 11.4. Some tests may encounter issues as a result. Please see the [PHPUnit 11 Upgrade Guide](/general/development/tools/phpunit/upgrading-11) for assistance in updating any broken tests. + +::: + +## Plugin type deprecation + + + +A new process for plugin type and subplugin type deprecation has been introduced. + +Using `components.json` or `subplugins.json` plugin types and subplugin types, respectively, can be marked as deprecated or deleted. + +:::info +Plugin/subplugin type deprecation doesn't follow the same rules as code deprecation. Core considers deprecated plugins as end-of-life and will omit them from many core APIs. Things like hooks, callbacks and events will not include/call plugins of a deprecated type. +::: + +Deprecation follows a 3 stage process: + +1. The plugin/subplugin type is marked as deprecated (a core version bump is also required). +2. The plugin/subplugin type is marked as deleted (a core version bump is also required). +3. Final removal of the plugin/subplugin type from the respective config file. + +:::info Limitations +Currently, only those plugin types _not_ supporting subplugins can be deprecated. +::: + +During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. This stage gives admins time to remove the affected plugins from the site, or migrate them to their replacement plugins. + +In second stage deprecation (deletion), if any affected plugins are still present (i.e. have not been removed/uninstalled yet) site upgrade will be blocked. These plugins must be removed at this time to continue. + +In final stage deprecation (final removal), the relevant config changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. + +:::tip Example of the new plugin/subplugin type deprecation config values + +To mark a plugin type as deprecated in `components.json`, the plugin type should be removed from the `plugintypes` object, and added to a new `deprecatedplugintypes` object. + +```json title="lib/components.json demonstrating first stage deprecation of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deprecatedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +To mark a subplugin type as deprecated in a component's `subplugins.json`, the subplugin type should be removed from the `subplugintypes` object, and added to a new `deprecatedsubplugintypes` object. + +```json title="mod/lti/db/subplugins.json demonstrating first stage deprecation of a subplugin type" +{ + "subplugintypes": { + }, + "deprecatedsubplugintypes": { + "ltiservice": "service", + "ltisource": "source" + } +} +``` + +To mark a plugin type as deleted in `components.json`, the plugin type should be removed from the `deprecatedplugintypes` object, and added to a new `deletedplugintypes` object. + +```json title="lib/components.json demonstrating second stage deprecation (deletion) of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deprecatedplugintypes": { + }, + "deletedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +To mark a subplugin type as deleted in a component's `subplugins.json`, the subplugin type should be removed from the `deprecatedsubplugintypes` object, and added to a new `deletedsubplugintypes` object. + +```json title="mod/lti/db/subplugins.json demonstrating second stage deprecation (deletion) of a subplugin type" +{ + "deprecatedsubplugintypes": { + }, + "deletedsubplugintypes": { + "ltiservice": "service", + "ltisource": "source" + } +} +``` + +Third stage deprecation just removes the plugin/subplugin type from the respective `deletedplugintypes` or `deletedsubplugintypes` objects. If these objects are empty, they may also be removed entirely. + +```json title="lib/components.json demonstrating final stage deprecation of a plugin type. The process is the same for subplugin types." +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, +} +``` + +::: diff --git a/general/development/policies/deprecation/index.md b/general/development/policies/deprecation/index.md index 447077baef..ce23fb0a61 100644 --- a/general/development/policies/deprecation/index.md +++ b/general/development/policies/deprecation/index.md @@ -290,6 +290,7 @@ Named parameter arguments are available from PHP 8.0 onwards. - [Deprecation attributes](/docs/apis/core/deprecation/) - [External functions deprecation](/docs/apis/subsystems/external/writing-a-service#deprecation) - [Capabilities deprecation](/docs/apis/subsystems/access#deprecating-a-capability) +- [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation) - [Icon deprecation](./icon-deprecation.md) - [SCSS deprecation](./scss-deprecation.md) - [Behat step definition deprecation](../../tools/behat/writing.md#deprecating-a-step-definition) diff --git a/general/development/tools/metadata/index.md b/general/development/tools/metadata/index.md index a4704c428f..f724b34666 100644 --- a/general/development/tools/metadata/index.md +++ b/general/development/tools/metadata/index.md @@ -39,6 +39,8 @@ The name and location on disk of every plugin type, and subsystem is described i +Plugin types may also be marked as deprecated in this metadata. For more information, see [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation). + ## Subplugins Any plugin which supports subplugins must describe its subplugin types by name and path in that plugins `db/subplugins.json` location. @@ -48,6 +50,8 @@ This file requires that subplugins be specified as a set of key and value pairs - The name is the used as a prefix for all namespaces. - The path is the path that the plugins exist within. +Subplugin types may also be marked as deprecated in this metadata. For more information, see [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation). + In the following example the subplugins used in `mod_quiz` are described. The Quiz activity module is located in `mod/quiz`. It has two subplugin types, `quiz`, and `quizaccess` which are located in `mod/quiz/report`, and `mod/quiz/accessrule` respectively. From a071d4f1c11cd190854ce831f9abda9b4e89b7b1 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 6 Feb 2025 14:07:26 +0800 Subject: [PATCH 2/2] [docs] Reduce duplication and apply style fixes --- docs/apis/plugintypes/index.md | 36 +++++++++--- docs/devupdate.md | 101 +-------------------------------- 2 files changed, 29 insertions(+), 108 deletions(-) diff --git a/docs/apis/plugintypes/index.md b/docs/apis/plugintypes/index.md index da0e06cc31..02a8e3e49d 100644 --- a/docs/apis/plugintypes/index.md +++ b/docs/apis/plugintypes/index.md @@ -139,16 +139,18 @@ foreach ($pluginman->get_plugin_types() as $type => $dir) { When a plugin or subplugin type is no longer needed or is replaced by another plugin type, it should be deprecated. Using `components.json` or `subplugins.json` plugin types and subplugin types, respectively, can be marked as deprecated. -The process for plugin/subplugin type deprecation differs slightly to normal [Deprecation](/general/development/policies/deprecation) process. +The process for plugin and subplugin type deprecation differs slightly to the normal [Deprecation](/general/development/policies/deprecation) process. Unlike with code deprecation, where the deprecated class or method is usually expected to remain functional during the deprecation window, deprecated plugin/subplugin types are treated as end-of-life as soon as they are deprecated. -Once deprecated, core will exclude plugins of the respective plugin type when performing common core-plugin communication, such as with hooks, callbacks, events, etc. -In the case of subplugins, the expectation is that the component code (the component under which the subplugins reside), will have been updated and all references to the subplugins removed/replaced, before the time of deprecation. +Once deprecated, core will exclude plugins of the respective plugin type when performing common core-plugin communication, such as with hooks, callbacks, events, and-so-on. +In the case of subplugins, the subplugin owner (the component which the subplugin belongs to), **must** have been updated to remove or replace all references to the subplugins before the time of deprecation. Class autoloading and string resolution is still supported during the deprecation window, to assist with any plugin migration scripts that may be required. :::info limitations -Whilst both plugin and subplugin types can be deprecated, only those plugin types _not_ supporting subplugins can be deprecated presently. + +Whilst both plugin and subplugin types can be deprecated, only those plugin types which do _not_ support subplugins can be deprecated. + ::: ### Deprecation process @@ -159,18 +161,34 @@ Deprecation follows a 3 stage process: 2. The plugin/subplugin type is marked as deleted (a core version bump is also required). 3. Final removal of the plugin/subplugin type from the respective config file. -During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. This stage gives admins time to remove the affected plugins from the site, or migrate them to their replacement plugins. +#### First stage deprecation + +During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. + +This stage gives administrators time to remove the affected plugins from the site, or migrate them to their replacement plugins. + +#### Second stage deprecation + +The second stage deprecation is the deletion phase. + +If any affected plugins are still present (that is any which have not been uninstalled or migrated yet), the site upgrade will be blocked. -In second stage deprecation (deletion), if any affected plugins are still present (i.e. have not been uninstalled/migrated yet) site upgrade will be blocked. These plugins must be removed before continuing with site upgrade. +These plugins **must** be removed before continuing with site upgrade. -In final stage deprecation (final removal), the relevant config changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. +#### Final deprecation + +In the final deprecation stage the relevant configuration changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. ### Deprecating a plugin type -To mark a plugin type as deprecated or deleted, edit `lib/components.json`, remove the plugin type from the `plugintypes` object and add it to `deprecatedplugintypes`. To mark a plugin type for stage 2 deprecation (deletion), edit the same file and move the plugin type from the `deprecatedplugintypes` object to the `deletedplugintypes` object. +The first phase of plugin type deprecation involves describing the plugin in the `deprecatedplugintypes` configuration in `lib/components.json`. The plugin type must also be removed from the `plugintypes` object. + +The second phase of plugin type deprecation involves moving the entry from the `deprecatedplugintypes` object to the `deletedplugintypes` object. :::info Remember + Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. + ::: :::tip Example of plugin type deprecation config values @@ -229,7 +247,9 @@ To mark a subplugin type as deprecated, edit the component's `subplugins.json` f Following deletion, the plugin/subplugin type can be removed from the respective JSON entirely. :::info Remember + Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. + ::: :::tip Example of subplugin type deprecation config values diff --git a/docs/devupdate.md b/docs/devupdate.md index e9f34d09ff..d27eefac89 100644 --- a/docs/devupdate.md +++ b/docs/devupdate.md @@ -120,103 +120,4 @@ Please see the [PHPUnit 11 Upgrade Guide](/general/development/tools/phpunit/upg -A new process for plugin type and subplugin type deprecation has been introduced. - -Using `components.json` or `subplugins.json` plugin types and subplugin types, respectively, can be marked as deprecated or deleted. - -:::info -Plugin/subplugin type deprecation doesn't follow the same rules as code deprecation. Core considers deprecated plugins as end-of-life and will omit them from many core APIs. Things like hooks, callbacks and events will not include/call plugins of a deprecated type. -::: - -Deprecation follows a 3 stage process: - -1. The plugin/subplugin type is marked as deprecated (a core version bump is also required). -2. The plugin/subplugin type is marked as deleted (a core version bump is also required). -3. Final removal of the plugin/subplugin type from the respective config file. - -:::info Limitations -Currently, only those plugin types _not_ supporting subplugins can be deprecated. -::: - -During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. This stage gives admins time to remove the affected plugins from the site, or migrate them to their replacement plugins. - -In second stage deprecation (deletion), if any affected plugins are still present (i.e. have not been removed/uninstalled yet) site upgrade will be blocked. These plugins must be removed at this time to continue. - -In final stage deprecation (final removal), the relevant config changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. - -:::tip Example of the new plugin/subplugin type deprecation config values - -To mark a plugin type as deprecated in `components.json`, the plugin type should be removed from the `plugintypes` object, and added to a new `deprecatedplugintypes` object. - -```json title="lib/components.json demonstrating first stage deprecation of a plugin type" -{ - "plugintypes": { - ... - }, - "subsystems": { - ... - }, - "deprecatedplugintypes": { - "aiplacement": "ai/placement" - } -} -``` - -To mark a subplugin type as deprecated in a component's `subplugins.json`, the subplugin type should be removed from the `subplugintypes` object, and added to a new `deprecatedsubplugintypes` object. - -```json title="mod/lti/db/subplugins.json demonstrating first stage deprecation of a subplugin type" -{ - "subplugintypes": { - }, - "deprecatedsubplugintypes": { - "ltiservice": "service", - "ltisource": "source" - } -} -``` - -To mark a plugin type as deleted in `components.json`, the plugin type should be removed from the `deprecatedplugintypes` object, and added to a new `deletedplugintypes` object. - -```json title="lib/components.json demonstrating second stage deprecation (deletion) of a plugin type" -{ - "plugintypes": { - ... - }, - "subsystems": { - ... - }, - "deprecatedplugintypes": { - }, - "deletedplugintypes": { - "aiplacement": "ai/placement" - } -} -``` - -To mark a subplugin type as deleted in a component's `subplugins.json`, the subplugin type should be removed from the `deprecatedsubplugintypes` object, and added to a new `deletedsubplugintypes` object. - -```json title="mod/lti/db/subplugins.json demonstrating second stage deprecation (deletion) of a subplugin type" -{ - "deprecatedsubplugintypes": { - }, - "deletedsubplugintypes": { - "ltiservice": "service", - "ltisource": "source" - } -} -``` - -Third stage deprecation just removes the plugin/subplugin type from the respective `deletedplugintypes` or `deletedsubplugintypes` objects. If these objects are empty, they may also be removed entirely. - -```json title="lib/components.json demonstrating final stage deprecation of a plugin type. The process is the same for subplugin types." -{ - "plugintypes": { - ... - }, - "subsystems": { - ... - }, -} -``` - -::: +A new process for plugin type and subplugin type deprecation has been introduced. See [the Plugin Type deprecation](./apis/plugintypes/index.md#deprecating-a-plugin-type) and [Subplugin deprecation](./apis/plugintypes/index.md#deprecating-a-subplugin-type) documentation for further information.