1
0
mirror of https://github.com/flarum/core.git synced 2025-08-13 11:54:32 +02:00

Improve update checking and add UI for major flarum update

This commit is contained in:
SychO9
2021-10-01 17:52:15 +01:00
parent 0aed124911
commit 2ce28f8e5c
9 changed files with 255 additions and 24 deletions

View File

@@ -6,9 +6,7 @@
namespace SychO\PackageManager\Command;
use Carbon\Carbon;
use Composer\Console\Application;
use Flarum\Settings\SettingsRepositoryInterface;
use SychO\PackageManager\Exception\ComposerCommandFailedException;
use SychO\PackageManager\LastUpdateCheck;
use SychO\PackageManager\OutputLogger;
@@ -40,8 +38,22 @@ class CheckForUpdatesHandler
}
/**
* @throws \Flarum\User\Exception\PermissionDeniedException
* @throws ComposerCommandFailedException
* We run two commands here
*
* `composer outdated -D --format json`
* This queries latest versions for all direct packages, so it can include major updates,
* that are not necessarily compatible with the current flarum version.
* That includes flarum/core itself, so for example if we are on flarum/core v1.8.0
* and there are v1.8.1 and v2.0.0 available, the command would only let us know of v2.0.0.
*
* `composer outdated -D --minor-only --format json`
* This only lists latest minor updates, we need to run this as well not only to be able to know
* of these minor versions in addition to major ones, but especially for the flarum/core, as explained above
* we need to know of minor core updates, even if there is a major version available.
*
* The results from both commands are properly processed and merged to have new key values `latest-minor` and `latest-major`.
*
* @throws \Flarum\User\Exception\PermissionDeniedException|ComposerCommandFailedException
*/
public function handle(CheckForUpdates $command)
{
@@ -49,10 +61,56 @@ class CheckForUpdatesHandler
$actor->assertAdmin();
$firstOutput = $this->runComposerCommand(false);
$firstOutput = json_decode($firstOutput, true);
$majorUpdates = false;
foreach ($firstOutput['installed'] as $package) {
if ($package['latest-status'] === 'update-possible') {
$majorUpdates = true;
break;
}
}
if ($majorUpdates) {
$secondOutput = $this->runComposerCommand(true);
$secondOutput = json_decode($secondOutput, true);
} else {
$secondOutput = ['installed' => []];
}
foreach ($firstOutput['installed'] as &$mainPackageUpdate) {
$mainPackageUpdate['latest-minor'] = $mainPackageUpdate['latest-major'] = null;
if ($mainPackageUpdate['latest-status'] === 'update-possible') {
$mainPackageUpdate['latest-major'] = $mainPackageUpdate['latest'];
$minorPackageUpdate = array_filter($secondOutput['installed'], function ($package) use ($mainPackageUpdate) {
return $package['name'] === $mainPackageUpdate['name'];
})[0] ?? null;
if ($minorPackageUpdate) {
$mainPackageUpdate['latest-minor'] = $minorPackageUpdate['latest'];
}
} else {
$mainPackageUpdate['latest-minor'] = $mainPackageUpdate['latest'];
}
}
return $this->lastUpdateCheck->save($firstOutput);
}
/**
* @throws ComposerCommandFailedException
*/
protected function runComposerCommand(bool $minorOnly): string
{
$output = new BufferedOutput();
$input = new ArrayInput([
'command' => 'outdated',
'-D' => true,
'--minor-only' => $minorOnly,
'--format' => 'json',
]);
@@ -65,6 +123,6 @@ class CheckForUpdatesHandler
throw new ComposerCommandFailedException('', $output);
}
return $this->lastUpdateCheck->save(json_decode($output, true));
return $output;
}
}

View File

@@ -47,7 +47,7 @@ class LastUpdateCheck
if (isset($lastUpdateCheck['updates']) && ! empty($lastUpdateCheck['updates']['installed'])) {
$updatesListChanged = false;
$pattern = str_replace('*', '.*', preg_quote($name));
$pattern = preg_quote(str_replace('*', '.*', $name));
foreach ($lastUpdateCheck['updates']['installed'] as $k => $package) {
if (($wildcard && Str::of($package['name'])->test("/($pattern)/")) || $package['name'] === $name) {