diff --git a/extensions/package-manager/src/Command/CheckForUpdatesHandler.php b/extensions/package-manager/src/Command/CheckForUpdatesHandler.php index b2cd64c4a..e4dab09dc 100755 --- a/extensions/package-manager/src/Command/CheckForUpdatesHandler.php +++ b/extensions/package-manager/src/Command/CheckForUpdatesHandler.php @@ -9,17 +9,15 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; +use Flarum\PackageManager\Composer\ComposerAdapter; use Flarum\PackageManager\Exception\ComposerCommandFailedException; use Flarum\PackageManager\LastUpdateCheck; -use Flarum\PackageManager\OutputLogger; use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; class CheckForUpdatesHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -28,16 +26,10 @@ class CheckForUpdatesHandler */ protected $lastUpdateCheck; - /** - * @var OutputLogger - */ - protected $logger; - - public function __construct(Application $composer, LastUpdateCheck $lastUpdateCheck, OutputLogger $logger) + public function __construct(ComposerAdapter $composer, LastUpdateCheck $lastUpdateCheck) { $this->composer = $composer; $this->lastUpdateCheck = $lastUpdateCheck; - $this->logger = $logger; } /** @@ -109,23 +101,19 @@ class CheckForUpdatesHandler */ protected function runComposerCommand(bool $minorOnly): string { - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'outdated', - '-D' => true, - '--minor-only' => $minorOnly, - '--format' => 'json', - ]); + $output = $this->composer->run( + new ArrayInput([ + 'command' => 'outdated', + '-D' => true, + '--minor-only' => $minorOnly, + '--format' => 'json', + ]) + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerCommandFailedException('', $output); + if ($output->getExitCode() !== 0) { + throw new ComposerCommandFailedException('', $output->getContents()); } - return $output; + return $output->getContents(); } } diff --git a/extensions/package-manager/src/Command/GlobalUpdateHandler.php b/extensions/package-manager/src/Command/GlobalUpdateHandler.php index 5a67f94c7..d5032bf9a 100644 --- a/extensions/package-manager/src/Command/GlobalUpdateHandler.php +++ b/extensions/package-manager/src/Command/GlobalUpdateHandler.php @@ -9,19 +9,17 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; use Flarum\Bus\Dispatcher as FlarumDispatcher; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Flarum\PackageManager\Event\FlarumUpdated; use Flarum\PackageManager\Exception\ComposerUpdateFailedException; -use Flarum\PackageManager\OutputLogger; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Input\StringInput; class GlobalUpdateHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -35,17 +33,11 @@ class GlobalUpdateHandler */ protected $commandDispatcher; - /** - * @var OutputLogger - */ - protected $logger; - - public function __construct(Application $composer, Dispatcher $events, FlarumDispatcher $commandDispatcher, OutputLogger $logger) + public function __construct(ComposerAdapter $composer, Dispatcher $events, FlarumDispatcher $commandDispatcher) { $this->composer = $composer; $this->events = $events; $this->commandDispatcher = $commandDispatcher; - $this->logger = $logger; } /** @@ -55,22 +47,12 @@ class GlobalUpdateHandler { $command->actor->assertAdmin(); - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'update', - '--prefer-dist' => true, - '--no-dev' => true, - '-a' => true, - '--with-all-dependencies' => true, - ]); + $output = $this->composer->run( + new StringInput("update --prefer-dist --no-dev -a --with-all-dependencies") + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerUpdateFailedException('*', $output); + if ($output->getExitCode() !== 0) { + throw new ComposerUpdateFailedException('*', $output->getContents()); } $this->commandDispatcher->dispatch( diff --git a/extensions/package-manager/src/Command/MajorUpdateHandler.php b/extensions/package-manager/src/Command/MajorUpdateHandler.php index f59006776..a1dd5d89f 100644 --- a/extensions/package-manager/src/Command/MajorUpdateHandler.php +++ b/extensions/package-manager/src/Command/MajorUpdateHandler.php @@ -9,21 +9,19 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; use Flarum\Foundation\Paths; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Support\Arr; use Flarum\PackageManager\Event\FlarumUpdated; use Flarum\PackageManager\Exception\ComposerUpdateFailedException; use Flarum\PackageManager\LastUpdateCheck; -use Flarum\PackageManager\OutputLogger; use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; class MajorUpdateHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -37,11 +35,6 @@ class MajorUpdateHandler */ protected $events; - /** - * @var OutputLogger - */ - protected $logger; - /** * @var Paths */ @@ -52,12 +45,11 @@ class MajorUpdateHandler */ protected $composerJson; - public function __construct(Application $composer, LastUpdateCheck $lastUpdateCheck, Dispatcher $events, OutputLogger $logger, Paths $paths) + public function __construct(ComposerAdapter $composer, LastUpdateCheck $lastUpdateCheck, Dispatcher $events, Paths $paths) { $this->composer = $composer; $this->lastUpdateCheck = $lastUpdateCheck; $this->events = $events; - $this->logger = $logger; $this->paths = $paths; } @@ -128,6 +120,7 @@ class MajorUpdateHandler protected function revertComposerJson(): void { $composerJsonPath = $this->paths->base . '/composer.json'; + // @todo use filesystem for all file_get_contents file_put_contents($composerJsonPath, $this->composerJson); } @@ -136,24 +129,20 @@ class MajorUpdateHandler */ protected function runCommand(bool $dryRun): void { - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'update', - '--prefer-dist' => true, - '--no-plugins' => true, - '--no-dev' => true, - '-a' => true, - '--with-all-dependencies' => true, - '--dry-run' => $dryRun, - ]); + $output = $this->composer->run( + new ArrayInput([ + 'command' => 'update', + '--prefer-dist' => true, + '--no-plugins' => true, + '--no-dev' => true, + '-a' => true, + '--with-all-dependencies' => true, + '--dry-run' => $dryRun, + ]) + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerUpdateFailedException('*', $output); + if ($output->getExitCode() !== 0) { + throw new ComposerUpdateFailedException('*', $output->getContents()); } } } diff --git a/extensions/package-manager/src/Command/MinorFlarumUpdateHandler.php b/extensions/package-manager/src/Command/MinorFlarumUpdateHandler.php index af3c045f4..01e5a3bb7 100755 --- a/extensions/package-manager/src/Command/MinorFlarumUpdateHandler.php +++ b/extensions/package-manager/src/Command/MinorFlarumUpdateHandler.php @@ -9,19 +9,17 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Flarum\PackageManager\Event\FlarumUpdated; use Flarum\PackageManager\Exception\ComposerUpdateFailedException; use Flarum\PackageManager\LastUpdateCheck; -use Flarum\PackageManager\OutputLogger; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Input\StringInput; class MinorFlarumUpdateHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -35,17 +33,11 @@ class MinorFlarumUpdateHandler */ protected $events; - /** - * @var OutputLogger - */ - protected $logger; - - public function __construct(Application $composer, LastUpdateCheck $lastUpdateCheck, Dispatcher $events, OutputLogger $logger) + public function __construct(ComposerAdapter $composer, LastUpdateCheck $lastUpdateCheck, Dispatcher $events) { $this->composer = $composer; $this->lastUpdateCheck = $lastUpdateCheck; $this->events = $events; - $this->logger = $logger; } /** @@ -56,23 +48,12 @@ class MinorFlarumUpdateHandler { $command->actor->assertAdmin(); - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'update', - 'packages' => ["flarum/*"], - '--prefer-dist' => true, - '--no-dev' => true, - '-a' => true, - '--with-all-dependencies' => true, - ]); + $output = $this->composer->run( + new StringInput("update flarum/* --prefer-dist --no-dev -a --with-all-dependencies") + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerUpdateFailedException('flarum/*', $output); + if ($output->getExitCode() !== 0) { + throw new ComposerUpdateFailedException('flarum/*', $output->getContents()); } $this->lastUpdateCheck->forget('flarum/*', true); diff --git a/extensions/package-manager/src/Command/RemoveExtensionHandler.php b/extensions/package-manager/src/Command/RemoveExtensionHandler.php index 2b0db42fa..9b3fd229c 100755 --- a/extensions/package-manager/src/Command/RemoveExtensionHandler.php +++ b/extensions/package-manager/src/Command/RemoveExtensionHandler.php @@ -9,21 +9,18 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; use Flarum\Extension\ExtensionManager; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Flarum\PackageManager\Exception\ComposerCommandFailedException; -use Flarum\PackageManager\Exception\ComposerUpdateFailedException; use Flarum\PackageManager\Exception\ExtensionNotInstalledException; use Flarum\PackageManager\Extension\Event\Removed; -use Flarum\PackageManager\OutputLogger; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Input\StringInput; class RemoveExtensionHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -37,17 +34,11 @@ class RemoveExtensionHandler */ protected $events; - /** - * @var OutputLogger - */ - protected $logger; - - public function __construct(Application $composer, ExtensionManager $extensions, Dispatcher $events, OutputLogger $logger) + public function __construct(ComposerAdapter $composer, ExtensionManager $extensions, Dispatcher $events) { $this->composer = $composer; $this->extensions = $extensions; $this->events = $events; - $this->logger = $logger; } /** @@ -64,19 +55,12 @@ class RemoveExtensionHandler throw new ExtensionNotInstalledException($command->extensionId); } - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'remove', - 'packages' => [$extension->name], - ]); + $output = $this->composer->run( + new StringInput("remove $extension->name") + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerCommandFailedException($extension->name, $output); + if ($output->getExitCode() !== 0) { + throw new ComposerCommandFailedException($extension->name, $output->getContents()); } $this->events->dispatch( diff --git a/extensions/package-manager/src/Command/RequireExtensionHandler.php b/extensions/package-manager/src/Command/RequireExtensionHandler.php index 801a8f9ef..f900f3235 100755 --- a/extensions/package-manager/src/Command/RequireExtensionHandler.php +++ b/extensions/package-manager/src/Command/RequireExtensionHandler.php @@ -9,22 +9,20 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; use Flarum\Extension\ExtensionManager; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Flarum\PackageManager\Exception\ComposerRequireFailedException; use Flarum\PackageManager\Exception\ExtensionAlreadyInstalledException; use Flarum\PackageManager\Extension\Event\Installed; use Flarum\PackageManager\Extension\ExtensionUtils; -use Flarum\PackageManager\OutputLogger; use Flarum\PackageManager\RequirePackageValidator; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Input\StringInput; class RequireExtensionHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -43,18 +41,12 @@ class RequireExtensionHandler */ protected $events; - /** - * @var OutputLogger - */ - protected $logger; - - public function __construct(Application $composer, ExtensionManager $extensions, RequirePackageValidator $validator, Dispatcher $events, OutputLogger $logger) + public function __construct(ComposerAdapter $composer, ExtensionManager $extensions, RequirePackageValidator $validator, Dispatcher $events) { $this->composer = $composer; $this->extensions = $extensions; $this->validator = $validator; $this->events = $events; - $this->logger = $logger; } /** @@ -74,19 +66,12 @@ class RequireExtensionHandler throw new ExtensionAlreadyInstalledException($extension); } - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'require', - 'packages' => [$command->package], - ]); + $output = $this->composer->run( + new StringInput("require $command->package") + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerRequireFailedException($command->package, $output); + if ($output->getExitCode() !== 0) { + throw new ComposerRequireFailedException($command->package, $output->getContents()); } $this->events->dispatch( diff --git a/extensions/package-manager/src/Command/UpdateExtensionHandler.php b/extensions/package-manager/src/Command/UpdateExtensionHandler.php index 9f53d474e..c0802e404 100755 --- a/extensions/package-manager/src/Command/UpdateExtensionHandler.php +++ b/extensions/package-manager/src/Command/UpdateExtensionHandler.php @@ -9,23 +9,20 @@ namespace Flarum\PackageManager\Command; -use Composer\Console\Application; use Flarum\Extension\ExtensionManager; -use Flarum\Settings\SettingsRepositoryInterface; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Events\Dispatcher; use Flarum\PackageManager\Exception\ComposerUpdateFailedException; use Flarum\PackageManager\Exception\ExtensionNotInstalledException; use Flarum\PackageManager\Extension\Event\Updated; -use Flarum\PackageManager\OutputLogger; use Flarum\PackageManager\UpdateExtensionValidator; use Flarum\PackageManager\LastUpdateCheck; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Input\StringInput; class UpdateExtensionHandler { /** - * @var Application + * @var ComposerAdapter */ protected $composer; @@ -49,25 +46,18 @@ class UpdateExtensionHandler */ protected $events; - /** - * @var OutputLogger - */ - protected $logger; - public function __construct( - Application $composer, + ComposerAdapter $composer, ExtensionManager $extensions, UpdateExtensionValidator $validator, LastUpdateCheck $lastUpdateCheck, - Dispatcher $events, - OutputLogger $logger) + Dispatcher $events) { $this->composer = $composer; $this->extensions = $extensions; $this->validator = $validator; $this->lastUpdateCheck = $lastUpdateCheck; $this->events = $events; - $this->logger = $logger; } /** @@ -86,19 +76,12 @@ class UpdateExtensionHandler throw new ExtensionNotInstalledException($command->extensionId); } - $output = new BufferedOutput(); - $input = new ArrayInput([ - 'command' => 'require', - 'packages' => ["$extension->name:*"], - ]); + $output = $this->composer->run( + new StringInput("require $extension->name:*") + ); - $exitCode = $this->composer->run($input, $output); - $output = $output->fetch(); - - $this->logger->log($input->__toString(), $output, $exitCode); - - if ($exitCode !== 0) { - throw new ComposerUpdateFailedException($extension->name, $output); + if ($output->getExitCode() !== 0) { + throw new ComposerUpdateFailedException($extension->name, $output->getContents()); } $this->lastUpdateCheck->forget($extension->name); diff --git a/extensions/package-manager/src/Composer/ComposerAdapter.php b/extensions/package-manager/src/Composer/ComposerAdapter.php new file mode 100644 index 000000000..c94aaa0e1 --- /dev/null +++ b/extensions/package-manager/src/Composer/ComposerAdapter.php @@ -0,0 +1,47 @@ +application = $application; + $this->logger = $logger; + } + + public function run(InputInterface $input): ComposerOutput + { + $output = new BufferedOutput(); + + $exitCode = $this->application->run($input, $output); + + $outputContents = $output->fetch(); + + $this->logger->log($input->__toString(), $outputContents, $exitCode); + + return new ComposerOutput($exitCode, $outputContents); + } +} diff --git a/extensions/package-manager/src/Composer/ComposerOutput.php b/extensions/package-manager/src/Composer/ComposerOutput.php new file mode 100644 index 000000000..87719880a --- /dev/null +++ b/extensions/package-manager/src/Composer/ComposerOutput.php @@ -0,0 +1,39 @@ +exitCode = $exitCode; + $this->contents = $contents; + } + + public function getExitCode(): int + { + return $this->exitCode; + } + + public function getContents(): string + { + return $this->contents; + } +} diff --git a/extensions/package-manager/src/PackageManagerServiceProvider.php b/extensions/package-manager/src/PackageManagerServiceProvider.php index 2ab914c33..7c65a6e05 100755 --- a/extensions/package-manager/src/PackageManagerServiceProvider.php +++ b/extensions/package-manager/src/PackageManagerServiceProvider.php @@ -16,6 +16,7 @@ use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\Paths; use Flarum\Frontend\RecompileFrontendAssets; use Flarum\Locale\LocaleManager; +use Flarum\PackageManager\Composer\ComposerAdapter; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Events\Dispatcher; use Monolog\Formatter\LineFormatter; @@ -29,7 +30,7 @@ class PackageManagerServiceProvider extends AbstractServiceProvider { public function register() { - $this->container->singleton(Application::class, function (Container $container) { + $this->container->singleton(ComposerAdapter::class, function (Container $container) { // This should only ever be resolved when running composer commands, // because we modify other environment configurations. $composer = new Application(); @@ -48,10 +49,10 @@ class PackageManagerServiceProvider extends AbstractServiceProvider @ini_set('memory_limit', '1G'); @set_time_limit(5 * 60); - return $composer; + return new ComposerAdapter($composer, $container->make(OutputLogger::class)); }); - $this->container->alias(Application::class, 'flarum.composer'); + $this->container->alias(ComposerAdapter::class, 'flarum.composer'); $this->container->singleton(OutputLogger::class, function (Container $container) { $logPath = $container->make(Paths::class)->storage.'/logs/composer/output.log'; diff --git a/extensions/package-manager/src/RequirePackageValidator.php b/extensions/package-manager/src/RequirePackageValidator.php index ec5599d41..6667ce5d6 100755 --- a/extensions/package-manager/src/RequirePackageValidator.php +++ b/extensions/package-manager/src/RequirePackageValidator.php @@ -17,6 +17,6 @@ class RequirePackageValidator extends AbstractValidator * {@inheritdoc} */ protected $rules = [ - 'package' => 'required|string' + 'package' => ['required', 'string', 'regex:/^[A-z0-9-_]+\/[A-z-0-9]+(?::[A-z-0-9.->=<_]+){0,1}$/i'] ]; } diff --git a/extensions/package-manager/tests/integration/TestCase.php b/extensions/package-manager/tests/integration/TestCase.php index 92d1efc95..1adaa1de8 100644 --- a/extensions/package-manager/tests/integration/TestCase.php +++ b/extensions/package-manager/tests/integration/TestCase.php @@ -9,18 +9,13 @@ namespace Flarum\PackageManager\Tests\integration; -use Composer\Config; -use Composer\Console\Application; -use Flarum\Extension\ExtensionManager; use Flarum\Foundation\Paths; +use Flarum\PackageManager\Composer\ComposerAdapter; use Flarum\PackageManager\Extension\ExtensionUtils; use Flarum\Testing\integration\RetrievesAuthorizedUsers; -use Illuminate\Contracts\Container\Container; use Illuminate\Support\Arr; use Psr\Http\Message\ResponseInterface; -use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\StringInput; -use Symfony\Component\Console\Output\NullOutput; class TestCase extends \Flarum\Testing\integration\TestCase { @@ -81,10 +76,9 @@ class TestCase extends \Flarum\Testing\integration\TestCase protected function composer(string $command): void { - /** @var Application $composer */ - $composer = $this->app()->getContainer()->make(Application::class); - $output = new NullOutput(); - $composer->run(new StringInput($command), $output); + /** @var ComposerAdapter $composer */ + $composer = $this->app()->getContainer()->make(ComposerAdapter::class); + $composer->run(new StringInput($command)); } protected function guessedCause(ResponseInterface $response): ?string