What is deprecation?
Deprecation, in its programming sense, is the process of taking older code and marking it as no longer being useful within the codebase, usually because it has been superseded by newer code. The deprecated code is not immediately removed from the codebase because doing so may cause regression errors.
Why is deprecation needed?
In an open source project, the end use of the codebase varies. People may have customisations and plugins that depend on a function that has been targeted for deprecation. Rather than simply removing a function, we must gracefully deprecate the function over a period covered by a number of released versions.
Moodle Core deprecation process
Once it is decided that a function should be deprecated, a two-step process should be followed.
Step 1. Immediate action
Deprecation affects only the current master version, in other words, the deprecation only becomes affective after the next major release.
- If the function is not a member of a class (in other words, it is an independent function), it should be moved, with its PHPDoc and all comments, to lib/deprecationlib.php, which is included everywhere. If the function is a class member, it will need to be deprecated in its current location.
- A debugging message should be added to the function so that, when developer debugging mode is on, attention is drawn to the deprecation. The message should state that the function being called has been deprecated. If the function has been replaced, the user should be directed to the alternative.
debugging('Function foobar() is deprecated, please use class foobarbaz instead', DEBUG_DEVELOPER);
- If the deprecated function has been replaced with a new function, ideally the new function should be called from the deprecated function, so that the new functionality is used. This will make maintenance easier moving forward.
- A @deprecated tag should be added to the PHPDoc for the function description so that IDEs describing the function will note that it is deprecated.
- There will need to be an issue associated with the initial part of the deprecation. A second issue needs to be created to finish the job. The first issue will be blocked by the second and a link needs to be added to the issues to indicate that. The second issue needs to be a sub-task of an appropriate deprecation META. For example, if the current version is 2.3.2, the function will be marked as deprecated in 2.4 and should normally be removed for 2.6, so the second issue should be a subtask of a deprecation META for the 2.6 version (MDL-34434). This second issue should include instructions on how to remove the function so that when it comes time to do so, the task is trivial for any developer.
Longer deprecation periods can be considered for functions that are widely used.
Step 2. Final deprecation
- If a function has been marked as deprecated for 2.x (eg. 2.4) and set for removal at 2.x+2 (eg. 2.6), soon after the release of 2.x+1.1 (eg. 2.5.1), the 2.x+2 deprecation META will be processed. This means that the deprecated function will be removed before 2.x+2, but only in the master version. This allows any potential regressions caused by the removal of the function to be exposed as soon as possible.
- All content of the function is removed and in the skeleton that remains, an error statement should be included that reports that the function has been removed. You can direct developers to new function(s) in this message.
throw new coding_exception('check_potential_filename() can not be used any more, please use new file API');
- The PHPDoc for the function should have @param and @return tags removed to reduce the temptation for developers to consider using the function and make it obvious in IDEs that the function has been deprecated. The @deprecated tag should remain.