mirror of
https://github.com/flarum/core.git
synced 2025-08-13 20:04:24 +02:00
Improve the logic behind the different features
This commit is contained in:
@@ -33,7 +33,7 @@ class MajorUpdateController implements RequestHandlerInterface
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$actor = RequestUtil::getActor($request);
|
||||
$dryRun = (bool) (int) Arr::get($request->getParsedBody(), 'data.dryRun');
|
||||
$dryRun = (bool) (int) Arr::get($request->getParsedBody(), 'data.dryRun', 0);
|
||||
|
||||
$this->bus->dispatch(
|
||||
new MajorUpdate($actor, $dryRun)
|
||||
|
@@ -15,9 +15,9 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Flarum\PackageManager\Command\MinorFlarumUpdate;
|
||||
use Flarum\PackageManager\Command\MinorUpdate;
|
||||
|
||||
class MinorFlarumUpdateController implements RequestHandlerInterface
|
||||
class MinorUpdateController implements RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var Dispatcher
|
||||
@@ -37,7 +37,7 @@ class MinorFlarumUpdateController implements RequestHandlerInterface
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
$this->bus->dispatch(
|
||||
new MinorFlarumUpdate($actor)
|
||||
new MinorUpdate($actor)
|
||||
);
|
||||
|
||||
return new EmptyResponse();
|
@@ -71,7 +71,9 @@ class CheckForUpdatesHandler
|
||||
if ($majorUpdates) {
|
||||
$secondOutput = $this->runComposerCommand(true);
|
||||
$secondOutput = json_decode($secondOutput, true);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (! isset($secondOutput)) {
|
||||
$secondOutput = ['installed' => []];
|
||||
}
|
||||
|
||||
@@ -101,14 +103,17 @@ class CheckForUpdatesHandler
|
||||
*/
|
||||
protected function runComposerCommand(bool $minorOnly): string
|
||||
{
|
||||
$output = $this->composer->run(
|
||||
new ArrayInput([
|
||||
'command' => 'outdated',
|
||||
'-D' => true,
|
||||
'--minor-only' => $minorOnly,
|
||||
'--format' => 'json',
|
||||
])
|
||||
);
|
||||
$input = [
|
||||
'command' => 'outdated',
|
||||
'-D' => true,
|
||||
'--format' => 'json',
|
||||
];
|
||||
|
||||
if ($minorOnly) {
|
||||
$input['--minor-only'] = true;
|
||||
}
|
||||
|
||||
$output = $this->composer->run(new ArrayInput($input));
|
||||
|
||||
if ($output->getExitCode() !== 0) {
|
||||
throw new ComposerCommandFailedException('', $output->getContents());
|
||||
|
@@ -11,9 +11,10 @@ namespace Flarum\PackageManager\Command;
|
||||
|
||||
use Flarum\PackageManager\Composer\ComposerAdapter;
|
||||
use Flarum\PackageManager\Composer\ComposerJson;
|
||||
use Flarum\PackageManager\Exception\MajorUpdateFailedException;
|
||||
use Flarum\PackageManager\Exception\NoNewMajorVersionException;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Flarum\PackageManager\Event\FlarumUpdated;
|
||||
use Flarum\PackageManager\Exception\ComposerUpdateFailedException;
|
||||
use Flarum\PackageManager\LastUpdateCheck;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
|
||||
@@ -61,7 +62,7 @@ class MajorUpdateHandler
|
||||
* Run migrations.
|
||||
*
|
||||
* @throws \Flarum\User\Exception\PermissionDeniedException
|
||||
* @throws ComposerUpdateFailedException
|
||||
* @throws NoNewMajorVersionException|MajorUpdateFailedException
|
||||
*/
|
||||
public function handle(MajorUpdate $command)
|
||||
{
|
||||
@@ -70,12 +71,12 @@ class MajorUpdateHandler
|
||||
$majorVersion = $this->lastUpdateCheck->getNewMajorVersion();
|
||||
|
||||
if (! $majorVersion) {
|
||||
return false;
|
||||
throw new NoNewMajorVersionException();
|
||||
}
|
||||
|
||||
$this->updateComposerJson($majorVersion);
|
||||
|
||||
$this->runCommand($command->dryRun);
|
||||
$this->runCommand($command->dryRun, $majorVersion);
|
||||
|
||||
if ($command->dryRun) {
|
||||
$this->composerJson->revert();
|
||||
@@ -94,29 +95,34 @@ class MajorUpdateHandler
|
||||
|
||||
protected function updateComposerJson(string $majorVersion): void
|
||||
{
|
||||
$versionNumber = str_replace('v', '', $majorVersion);
|
||||
|
||||
$this->composerJson->require('*', '*');
|
||||
$this->composerJson->require('flarum/core', '^'.str_replace('v', '', $majorVersion));
|
||||
$this->composerJson->require('flarum/core', '^'.$versionNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ComposerUpdateFailedException
|
||||
* @throws MajorUpdateFailedException
|
||||
*/
|
||||
protected function runCommand(bool $dryRun): void
|
||||
protected function runCommand(bool $dryRun, string $majorVersion): void
|
||||
{
|
||||
$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,
|
||||
])
|
||||
);
|
||||
$input = [
|
||||
'command' => 'update',
|
||||
'--prefer-dist' => true,
|
||||
'--no-plugins' => true,
|
||||
'--no-dev' => true,
|
||||
'-a' => true,
|
||||
'--with-all-dependencies' => true,
|
||||
];
|
||||
|
||||
if ($dryRun) {
|
||||
$input['--dry-run'] = true;
|
||||
}
|
||||
|
||||
$output = $this->composer->run(new ArrayInput($input));
|
||||
|
||||
if ($output->getExitCode() !== 0) {
|
||||
throw new ComposerUpdateFailedException('*', $output->getContents());
|
||||
throw new MajorUpdateFailedException('*', $output->getContents(), $majorVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ namespace Flarum\PackageManager\Command;
|
||||
|
||||
use Flarum\User\User;
|
||||
|
||||
class MinorFlarumUpdate
|
||||
class MinorUpdate
|
||||
{
|
||||
/**
|
||||
* @var \Flarum\User\User
|
@@ -17,7 +17,7 @@ use Flarum\PackageManager\Exception\ComposerUpdateFailedException;
|
||||
use Flarum\PackageManager\LastUpdateCheck;
|
||||
use Symfony\Component\Console\Input\StringInput;
|
||||
|
||||
class MinorFlarumUpdateHandler
|
||||
class MinorUpdateHandler
|
||||
{
|
||||
/**
|
||||
* @var ComposerAdapter
|
||||
@@ -51,7 +51,7 @@ class MinorFlarumUpdateHandler
|
||||
* @throws \Flarum\User\Exception\PermissionDeniedException
|
||||
* @throws ComposerUpdateFailedException
|
||||
*/
|
||||
public function handle(MinorFlarumUpdate $command)
|
||||
public function handle(MinorUpdate $command)
|
||||
{
|
||||
$command->actor->assertAdmin();
|
||||
|
@@ -14,6 +14,9 @@ use Flarum\PackageManager\OutputLogger;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ComposerAdapter
|
||||
{
|
||||
/**
|
||||
@@ -26,19 +29,23 @@ class ComposerAdapter
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var BufferedOutput
|
||||
*/
|
||||
private $output;
|
||||
|
||||
public function __construct(Application $application, OutputLogger $logger)
|
||||
{
|
||||
$this->application = $application;
|
||||
$this->logger = $logger;
|
||||
$this->output = new BufferedOutput();
|
||||
}
|
||||
|
||||
public function run(InputInterface $input): ComposerOutput
|
||||
{
|
||||
$output = new BufferedOutput();
|
||||
$exitCode = $this->application->run($input, $this->output);
|
||||
|
||||
$exitCode = $this->application->run($input, $output);
|
||||
|
||||
$outputContents = $output->fetch();
|
||||
$outputContents = $this->output->fetch();
|
||||
|
||||
$this->logger->log($input->__toString(), $outputContents, $exitCode);
|
||||
|
||||
|
@@ -44,6 +44,10 @@ class ComposerJson
|
||||
$composerJson['require'][$packageName] = $version;
|
||||
} else {
|
||||
foreach ($composerJson['require'] as $p => $v) {
|
||||
if ($version === '*@dev') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wildcardPackageName = str_replace('\*', '.*', preg_quote($packageName, '/'));
|
||||
|
||||
if (Str::of($p)->test("/($wildcardPackageName)/")) {
|
||||
@@ -81,6 +85,6 @@ class ComposerJson
|
||||
|
||||
protected function set(array $json): void
|
||||
{
|
||||
$this->filesystem->put($this->getComposerJsonPath(), json_encode($json, JSON_PRETTY_PRINT));
|
||||
$this->filesystem->put($this->getComposerJsonPath(), json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,11 @@ class ComposerCommandFailedException extends Exception
|
||||
*/
|
||||
public $packageName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $details = [];
|
||||
|
||||
public function __construct(string $packageName, string $output)
|
||||
{
|
||||
$this->packageName = $packageName;
|
||||
|
@@ -11,7 +11,7 @@ namespace Flarum\PackageManager\Exception;
|
||||
|
||||
use Flarum\Foundation\ErrorHandling\HandledError;
|
||||
|
||||
class ComposerCommandFailedExceptionHandler
|
||||
class ExceptionHandler
|
||||
{
|
||||
public function handle(ComposerCommandFailedException $e): HandledError
|
||||
{
|
||||
@@ -32,6 +32,10 @@ class ComposerCommandFailedExceptionHandler
|
||||
$details['guessed_cause'] = $guessedCause;
|
||||
}
|
||||
|
||||
if (! empty($e->details)) {
|
||||
$details = array_merge($details, $e->details);
|
||||
}
|
||||
|
||||
return [$details];
|
||||
}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Flarum\PackageManager\Exception;
|
||||
|
||||
use Composer\Semver\Semver;
|
||||
|
||||
class MajorUpdateFailedException extends ComposerCommandFailedException
|
||||
{
|
||||
private const INCOMPATIBLE_REGEX = '/^ +- (?<ext>[A-z0-9\/-]+) [A-z0-9.-_\/]+ requires flarum\/core (?<coreReq>(?:[A-z0-9.><=_ -](?!->))+)/m';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $majorVersion;
|
||||
|
||||
public function __construct(string $packageName, string $output, string $majorVersion)
|
||||
{
|
||||
$this->majorVersion = $majorVersion;
|
||||
|
||||
parent::__construct($packageName, $output);
|
||||
}
|
||||
|
||||
public function guessCause(): ?string
|
||||
{
|
||||
if (preg_match_all(self::INCOMPATIBLE_REGEX, $this->getMessage(), $matches) !== false) {
|
||||
$this->details['incompatible_extensions'] = [];
|
||||
|
||||
foreach ($matches['ext'] as $k => $name) {
|
||||
if (! Semver::satisfies($this->majorVersion, $matches['coreReq'][$k])) {
|
||||
$this->details['incompatible_extensions'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return 'extensions_incompatible_with_new_major';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
26
extensions/package-manager/src/Exception/NoNewMajorVersionException.php
Executable file
26
extensions/package-manager/src/Exception/NoNewMajorVersionException.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\PackageManager\Exception;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Foundation\KnownError;
|
||||
|
||||
class NoNewMajorVersionException extends Exception implements KnownError
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct("No new major version known of. Try checking for updates first.");
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return 'no_new_major_version';
|
||||
}
|
||||
}
|
@@ -42,12 +42,12 @@ class LastUpdateCheck
|
||||
|
||||
public function get(): array
|
||||
{
|
||||
return json_decode($this->settings->get(self::KEY, '{}'), true);
|
||||
return json_decode($this->settings->get(self::KEY), true);
|
||||
}
|
||||
|
||||
public function getNewMajorVersion(): ?string
|
||||
{
|
||||
$core = Arr::first($this->get()['updates']['installed'], function ($package) {
|
||||
$core = Arr::first(Arr::get($this->get(), 'updates.installed', []), function ($package) {
|
||||
return $package['name'] === 'flarum/core';
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user