From 8882f9b6bb3bb76c9aeb5381689a4bf9785cb187 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 10 Nov 2025 09:00:23 +0100 Subject: [PATCH] refactor composer package management --- .../Plugin/ComposerPluginsCommand.php | 20 ++---- app/Facades/Plugins.php | 3 +- app/Services/Helpers/PluginService.php | 68 ++++++++++++------- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/app/Console/Commands/Plugin/ComposerPluginsCommand.php b/app/Console/Commands/Plugin/ComposerPluginsCommand.php index 69a4c068f..cd347f652 100644 --- a/app/Console/Commands/Plugin/ComposerPluginsCommand.php +++ b/app/Console/Commands/Plugin/ComposerPluginsCommand.php @@ -3,7 +3,6 @@ namespace App\Console\Commands\Plugin; use App\Facades\Plugins; -use App\Models\Plugin; use Exception; use Illuminate\Console\Command; @@ -11,23 +10,16 @@ class ComposerPluginsCommand extends Command { protected $signature = 'p:plugin:composer'; - protected $description = 'Runs "composer require" on all installed plugins.'; + protected $description = 'Makes sure the needed composer packages for all installed plugins are available.'; public function handle(): void { - $plugins = Plugin::all(); - foreach ($plugins as $plugin) { - if (!$plugin->shouldLoad()) { - continue; - } + try { + Plugins::manageComposerPackages(); + } catch (Exception $exception) { + report($exception); - try { - Plugins::requireComposerPackages($plugin); - } catch (Exception $exception) { - report($exception); - - $this->error($exception->getMessage()); - } + $this->error($exception->getMessage()); } } } diff --git a/app/Facades/Plugins.php b/app/Facades/Plugins.php index 819d9648f..4a53f9e68 100644 --- a/app/Facades/Plugins.php +++ b/app/Facades/Plugins.php @@ -11,8 +11,7 @@ use Illuminate\Support\Facades\Facade; /** * @method static void loadPlugins() * @method static void loadPanelPlugins(Panel $panel) - * @method static void requireComposerPackages(Plugin $plugin) - * @method static void removeComposerPackages(Plugin $plugin) + * @method static void manageComposerPackages(?array $oldPackages = null) * @method static void runPluginMigrations(Plugin $plugin) * @method static void rollbackPluginMigrations(Plugin $plugin) * @method static void installPlugin(Plugin $plugin, bool $enable = true) diff --git a/app/Services/Helpers/PluginService.php b/app/Services/Helpers/PluginService.php index 65dfca945..b4606987e 100644 --- a/app/Services/Helpers/PluginService.php +++ b/app/Services/Helpers/PluginService.php @@ -150,34 +150,54 @@ class PluginService } } - public function requireComposerPackages(Plugin $plugin): void + /** @param null|string[] $oldPackages */ + public function manageComposerPackages(?array $newPackages = [], ?array $oldPackages = null): void { - if ($plugin->composer_packages) { - $composerPackages = collect(json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR)) - ->map(fn ($version, $package) => "$package:$version") - ->flatten() - ->unique() - ->toArray(); + $newPackages ??= []; - $result = Process::path(base_path())->timeout(600)->run(['composer', 'require', ...$composerPackages]); - if ($result->failed()) { - throw new Exception('Could not require composer packages: ' . $result->errorOutput()); + $plugins = Plugin::query()->orderBy('load_order')->get(); + foreach ($plugins as $plugin) { + if (!$plugin->composer_packages) { + continue; + } + + if (!$plugin->shouldLoad()) { + continue; + } + + try { + $pluginPackages = json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR); + + $newPackages = array_merge($newPackages, $pluginPackages); + } catch (Exception $exception) { + report($exception); } } - } - public function removeComposerPackages(Plugin $plugin): void - { - if ($plugin->composer_packages) { - $composerPackages = collect(json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR)) - ->map(fn ($version, $package) => "$package:$version") - ->flatten() - ->unique() - ->toArray(); + $oldPackages = collect($oldPackages) + ->filter(fn ($version, $package) => !array_key_exists($package, $newPackages)) + ->map(fn ($version, $package) => "$package:$version") + ->flatten() + ->unique() + ->toArray(); - $result = Process::path(base_path())->timeout(600)->run(['composer', 'remove', ...$composerPackages]); + if (count($oldPackages) > 0) { + $result = Process::path(base_path())->timeout(600)->run(['composer', 'remove', ...$oldPackages]); if ($result->failed()) { - throw new Exception('Could not remove composer packages: ' . $result->errorOutput()); + throw new Exception('Could not remove old composer packages: ' . $result->errorOutput()); + } + } + + $newPackages = collect($newPackages) + ->map(fn ($version, $package) => "$package:$version") + ->flatten() + ->unique() + ->toArray(); + + if (count($newPackages) > 0) { + $result = Process::path(base_path())->timeout(600)->run(['composer', 'require', ...$newPackages]); + if ($result->failed()) { + throw new Exception('Could not require new composer packages: ' . $result->errorOutput()); } } } @@ -234,7 +254,7 @@ class PluginService public function installPlugin(Plugin $plugin, bool $enable = true): void { try { - $this->requireComposerPackages($plugin); + $this->manageComposerPackages(json_decode($plugin->composer_packages, true, 512)); $this->runPluginMigrations($plugin); @@ -268,7 +288,7 @@ class PluginService public function uninstallPlugin(Plugin $plugin, bool $deleteFiles = false): void { try { - $this->removeComposerPackages($plugin); + $pluginPackages = json_decode($plugin->composer_packages, true, 512); $this->rollbackPluginMigrations($plugin); @@ -279,6 +299,8 @@ class PluginService } else { $this->setStatus($plugin, PluginStatus::NotInstalled); } + + $this->manageComposerPackages(oldPackages: $pluginPackages); } catch (Exception $exception) { $this->handlePluginException($plugin, $exception); }