Join GitHub today
Late composer installation for plugin libraries #2811
This issue serves as a milder alternative to #2755, which radically changed plugin installation methods.
Compared to #2755, this issue does not aim to resolve issues with NIH class loading and built-in plugin manager (#2504). The sole purpose is to allow automatic installation of library dependencies (not plugin dependencies) to prevent problems of (unwarned) conflicting library versions while making it easier to use libraries in plugins.
This proposal introduces a new optional file
The responsibility of the server includes the merging of such dependencies, and the selection/detection of incompatibility of shared libraries.
This shall enable single-instance libraries, which currently requires a plugin format known as "API plugins".
Conflict with PMMP dependencies
There are two options:
Plugins must be loaded on startup
Do we really need to allow loading plugins after the server starts? I even suggest removing the /reload command. Is it so hard to restart the server?
To emulate the performance boost currently offered by packaging plugins in phar files, it is possible to lazily package the ad-hoc vendor directory into a phar too.
Plugins can still be edited, but libraries cannot be edited without the danger of being overwritten. Nonetheless, it is not our responsibility to ensure that plugins (much less only libraries) can be edited. Observing that editing libraries is not prevalent right now, and it is usually unnecessary to edit libraries (because they are usually better-coded than plugins and do not have direct impact on users), this concern is dismissed. Users may still fork the library and produce their own version if they are professional enough; but they won't notice they want to edit a library otherwise anyway.
Libraries must be open-source
This is not true. Composer supports local/VCS-based library requirement.
Plugin approval systems like Poggit will run into problems, because libraries are installed from a source that only its author has access to change.
It is possible for such approval platforms to modify the composer.json such that the library version is locked at a specific version, but this would result in problems when merging multiple plugins using the same library.
Another issue is https://www.google.com/amp/s/www.theregister.co.uk/AMP/2016/03/23/npm_left_pad_chaos/ But let's go the dangerous way of thinking: since npm is doing this for years, it should be ok.
Existing deployment workflow
This is a pure feature addition. Existing workflows do not have to be broken.
Consider adding extra include paths as a config in pocketmine.yml or alike.
here's the problem.
It may appear that some of your code changes are indeed reloaded when you run /reload, but this is not what is actually happening.
No, not at all, otherwise it might cause other problems such as problems with statics that you might not 100% be aware of. Live code swap is always dangerous, and even software much more professional than PocketMine like Android is still having trouble implementing proper code swap that does not lead to crashes that otherwise wouldn't happen.
Because I often add some new features or urgently fix some bugs when the server is running normally.
It has NEVER been and WILL never be possible to reload plugin code without restarting the server. It is only possible to load absolutely new code, so this has nothing to do with urgent fixed.
This issue is discussing about the removal of the ability to load absolutely new plugins, which rarely happens. (If you are updating a plugin, you must restart anyway)
The proposal is still facing difficulties with plugin loaders.
This is a very problematic issue. Fortunately, we don't have many plugins that load other plugins on startup (much less after startup - see #2825). The most popular example is DevTools (others like ZipPluginLoader and AllAPILoader are nonstandard and pretty much hated by some conservative members of the community). So, why don't we disallow late composer installation only for these specific plugins?
Hence, the solution is like this:
The pseudocode becomes like this: