refactor composer package management

This commit is contained in:
Boy132 2025-11-10 09:00:23 +01:00
parent 5d5ee27c3b
commit 8882f9b6bb
3 changed files with 52 additions and 39 deletions

View File

@ -3,7 +3,6 @@
namespace App\Console\Commands\Plugin; namespace App\Console\Commands\Plugin;
use App\Facades\Plugins; use App\Facades\Plugins;
use App\Models\Plugin;
use Exception; use Exception;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@ -11,23 +10,16 @@ class ComposerPluginsCommand extends Command
{ {
protected $signature = 'p:plugin:composer'; 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 public function handle(): void
{ {
$plugins = Plugin::all(); try {
foreach ($plugins as $plugin) { Plugins::manageComposerPackages();
if (!$plugin->shouldLoad()) { } catch (Exception $exception) {
continue; report($exception);
}
try { $this->error($exception->getMessage());
Plugins::requireComposerPackages($plugin);
} catch (Exception $exception) {
report($exception);
$this->error($exception->getMessage());
}
} }
} }
} }

View File

@ -11,8 +11,7 @@ use Illuminate\Support\Facades\Facade;
/** /**
* @method static void loadPlugins() * @method static void loadPlugins()
* @method static void loadPanelPlugins(Panel $panel) * @method static void loadPanelPlugins(Panel $panel)
* @method static void requireComposerPackages(Plugin $plugin) * @method static void manageComposerPackages(?array $oldPackages = null)
* @method static void removeComposerPackages(Plugin $plugin)
* @method static void runPluginMigrations(Plugin $plugin) * @method static void runPluginMigrations(Plugin $plugin)
* @method static void rollbackPluginMigrations(Plugin $plugin) * @method static void rollbackPluginMigrations(Plugin $plugin)
* @method static void installPlugin(Plugin $plugin, bool $enable = true) * @method static void installPlugin(Plugin $plugin, bool $enable = true)

View File

@ -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) { $newPackages ??= [];
$composerPackages = collect(json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR))
->map(fn ($version, $package) => "$package:$version")
->flatten()
->unique()
->toArray();
$result = Process::path(base_path())->timeout(600)->run(['composer', 'require', ...$composerPackages]); $plugins = Plugin::query()->orderBy('load_order')->get();
if ($result->failed()) { foreach ($plugins as $plugin) {
throw new Exception('Could not require composer packages: ' . $result->errorOutput()); 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 $oldPackages = collect($oldPackages)
{ ->filter(fn ($version, $package) => !array_key_exists($package, $newPackages))
if ($plugin->composer_packages) { ->map(fn ($version, $package) => "$package:$version")
$composerPackages = collect(json_decode($plugin->composer_packages, true, 512, JSON_THROW_ON_ERROR)) ->flatten()
->map(fn ($version, $package) => "$package:$version") ->unique()
->flatten() ->toArray();
->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()) { 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 public function installPlugin(Plugin $plugin, bool $enable = true): void
{ {
try { try {
$this->requireComposerPackages($plugin); $this->manageComposerPackages(json_decode($plugin->composer_packages, true, 512));
$this->runPluginMigrations($plugin); $this->runPluginMigrations($plugin);
@ -268,7 +288,7 @@ class PluginService
public function uninstallPlugin(Plugin $plugin, bool $deleteFiles = false): void public function uninstallPlugin(Plugin $plugin, bool $deleteFiles = false): void
{ {
try { try {
$this->removeComposerPackages($plugin); $pluginPackages = json_decode($plugin->composer_packages, true, 512);
$this->rollbackPluginMigrations($plugin); $this->rollbackPluginMigrations($plugin);
@ -279,6 +299,8 @@ class PluginService
} else { } else {
$this->setStatus($plugin, PluginStatus::NotInstalled); $this->setStatus($plugin, PluginStatus::NotInstalled);
} }
$this->manageComposerPackages(oldPackages: $pluginPackages);
} catch (Exception $exception) { } catch (Exception $exception) {
$this->handlePluginException($plugin, $exception); $this->handlePluginException($plugin, $exception);
} }