New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Composer-based plugin manager framework ("zygote") #2755
Comments
While this looks somewhat reasonable in words, I can say this is probably never going to happen due to the amount of work it will require. I'm not a fan of doing a tremendous amount of reworking to achieve simple goals. 2 out of 3 of the problems listed can be resolved with relatively little changes. As far as a plugin manager goes, we already have tools like Sheep for this and I don't see the benefit of reinventing that that justifies the work it's going to require. |
In addition, as I wrote on discord, composer is simply not designed for this job. You can't have installed modules which depend on the project itself, and this issue makes no apparent attempt to address this problem. |
(this doesn't even begin to dive into how confusing composer would be for the average non-technical user...) |
As I wrote on Discord, the dependency graph is:
There is no cyclic dependency at all.
If you read the issue carefully, users don't have to know about composer at all. All they need to do is to type a plugin name in |
Two problems that I forgot to mention: Too new pluginsIf the user is running an outdated PocketMine version, it might be difficult to locate the correct branch to fetch plugins from. Performance of startupAs we all know, loading from source is much slower than loading from phar. There are two excuses:
|
it's also false in recent months |
I disagree on that number 3 can be resolved with simple solutions. Developing a plugin repository/manager system is indeed complex, and doing it together with composer library resolution is one of the solutions I'm looking at. |
Another advantage/disadvantage: Editing source becomes much harder. You have to either clone it in a separate directory or perform very dangerous and unstable in-vendor editing, both of which are not easy for non-professionals. However, non-professionals should not be editing the source anyway, so I would say this is more an advantage than a disadvantage. |
Details of plugin searching:
Users shall receive a big warning (or even be disallowed) if more than one module simultaneously use |
Closed in favour of #2811 |
I noticed that this approach could also be used to handle multiple API channels. For example, if we split PocketMine's network module into a separate library While splitting PocketMine into a library sounds like tedious work, it ends up that we only need to remove the plugin loader logic from the core and accept an array of plugin description in the main function. It seems to be less complex than I expected. Regarding the management of zygote.php, I would alternatively propose that zygote be written in a native executable language such as Go or Rust, such that it is easier to self-update and manage the PHP binaries in the same tool. I am not sure if this should be within the context of the pmmp/PocketMine-MP repo, but for sure this is useful for version management in the long run. Regarding running from source, it appears that the first stackoverflow answer here is misleading; it is possible to use I propose to reinitiate research on this approach of plugin loading. |
An alternative design is to have
This allows multiple compatible client versions to have the same protocol. In that case it is possible that we specify the full client version |
I have updated the details in the proposal to define behaviour more precisely. |
Motivation
The current plugin loading system has lots of problems:
Proposal
PocketMine only distributes an installer, which manages PHP versions, PocketMine updates and plugins.
The
zygote
toolzygote
is a native executable that manages PocketMine versions with the following usage:Parameters
Subcommands
zygote init
Initialize the versions file if it is not already present.
zygote install
Install required tools in
./.zygote
, runninginit
if required; also auto-updates tools.A dummy composer project is created in
./zygote/stage
, with a composer.json generated from theversions.txt
.zygote run
Run the server, running
install
if not yet staged.zygote run
also triggers azygote install --dry-run
and a self-update of zygote, unless the--no--update
option is set.The
versions.txt
fileEach line specifies a dependency in one of the following types:
pocketmine <version>
: the PocketMine semantic version, e.g.pocketmine 4
. Also accepts a local path in place of the version. (If the local path is version-like, use./
)minecraft <version>
: the client version to support, e.g.minecraft 1.6.200
<plugin name> <version>
: installs an official plugin with the given semantic version, e.g.mineflow 1.3
. This is equivalent topmmp-plugins/<plugin name> <version>
.<packagist name> <version>
: installs an unofficial plugin with the given semantic version, e.g.aieuo/mineflow 1.3
dev <local path>
: installs a plugin in a local directory, relative to parent ofversions.txt
(not cwd).Note that versions are automatically prepended with a
^
if no comparators like>
,~
,=
, etc. are found.Restructuring PocketMine
The plugin loader logic is removed from PocketMine. Instead, the
pocketmine\server
function accepts a$plugins
array that specifies the plugin descriptions, as specified in the next section.Platform requirement checking shall have been performed by composer, so they may be removed from the startup script.
PocketMine is released on Packagist as
pocketmine/pocketmine-mp
. The protocol-dependent network module is split into a separate library.Writing plugins
A plugin is distributed as a composer library with
autoload.files
loading a file like the following:The
api
,extensions
andmcpe-protocool
attributes are removed since it is solved by composer dependencies. Other fields are consistent with current plugin.yml format.Containerization support
Container images can be built by running
zygote install
during build and runningzygote run
during execution.Old proposal
Proposal
The PocketMine installation is reformed into this structure:
zygote.php
start.cmd/start.sh is just a simple alias to execute
php zygote.php
. No looping logic is required.When started without any arguments, zygote.php does the following:
versions.txt
zygote.php loads versions.txt, which contains:
dev
to load from a local clone of pmmp/PocketMine-MP.git)For example:
composer install
Generate a stage/composer.json based on the dependencies from above, and run composer install.
To improve performance, don't run composer install if filemtime(stage/composer.json) > filemtime(versions.txt)
The magic behind: official platform (e.g. Poggit) submits a modified version of the plugin onto Packagist, including the appropriate composer.json and preserves backward compatibility
Check for zygote.php updates
Otherwise, users will never be motivated to update this script
Rate limit this check to prevent slowing down frequent restarts
Self invocation
Execute
$PHP_BINARY __FILE__ --start $args
, where $args is the list of plugin directories scannedzygote.php --start
When invoked with --start, zygote.php should do the job of PocketMine.php
In particular, it is responsible for invoking
new pocketmine\Server
and creating stdio—logger adaptersIn addition, zygote.php shall instantiate plugin classes and pass them as objects to
Server::__construct
When --start exits with code 42 (a magic number), or if a command line option was passed, the original zygote process should restart it.
Problems
Management of zygote.php
This file tends to be enormous. Should we make it a phar? In that case, how do we manage the development workflow?
Preprocessing
Naive Packagist distribution prohibits preprocessing to be performed. Is it possible to only publish preprocessed code to Packagist?
Custom plugin loaders
This issue increases the sophistication of loading plugins in custom formats.
However, custom plugin loaders are less necessary since we have composer installer. New plugin frameworks can easily be created by extending the PluginBase class. With #2043, this is not difficult.
After all, all the mess with DevTools and PharPluginLoader are unnecessary when all plugins are in composer folders.
The only non-plugin.yml plugin loader used extensively is ScriptPluginLoader. Can we work out a simple alternative? This needs more discussion.
The text was updated successfully, but these errors were encountered: