Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions core/Command/Upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$self = $this;
$updater = Server::get(Updater::class);
$incompatibleOverwrites = $this->config->getSystemValue('app_install_overwrite', []);

/** @var IEventDispatcher $dispatcher */
$dispatcher = Server::get(IEventDispatcher::class);
Expand Down Expand Up @@ -161,7 +160,9 @@ function ($success) use ($output, $self): void {
$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($output): void {
$output->writeln('<info>Updated database</info>');
});
$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($output, &$incompatibleOverwrites): void {
$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($output): void {
// Read per event, the overwrites are cleared during a major upgrade
$incompatibleOverwrites = $this->config->getSystemValue('app_install_overwrite', []);
if (!in_array($app, $incompatibleOverwrites)) {
$output->writeln('<comment>Disabled incompatible app: ' . $app . '</comment>');
}
Expand Down
5 changes: 3 additions & 2 deletions core/Controller/UpdateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public function update(): DataResponse {
\OC_User::setIncognitoMode(true);

$incompatibleApps = [];
$incompatibleOverwrites = $this->config->getSystemValue('app_install_overwrite', []);

$this->dispatcher->addListener(
MigratorExecuteSqlEvent::class,
Expand Down Expand Up @@ -127,7 +126,9 @@ function (MigratorExecuteSqlEvent $event) use ($eventSource): void {
$this->updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($eventSource): void {
$eventSource->send('success', $this->l->t('Updated "%1$s" to %2$s', [$app, $version]));
});
$this->updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use (&$incompatibleApps, &$incompatibleOverwrites): void {
$this->updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use (&$incompatibleApps): void {
// Read per event, the overwrites are cleared during a major upgrade
$incompatibleOverwrites = $this->config->getSystemValue('app_install_overwrite', []);
if (!in_array($app, $incompatibleOverwrites)) {
$incompatibleApps[] = $app;
}
Expand Down
15 changes: 15 additions & 0 deletions lib/private/Updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,16 @@ public function isUpgradePossible(string $oldVersion, string $newVersion, array
|| isset($allowedPreviousVersions[$currentVendor][$oldVersion]);
}

/**
* Whether the upgrade crosses a major version boundary
*/
private function isMajorUpgrade(string $installedVersion, string $currentVersion): bool {
$installedMajor = (int)explode('.', $installedVersion)[0];
$currentMajor = (int)explode('.', $currentVersion)[0];

return $currentMajor > $installedMajor;
}

/**
* runs the update actions in maintenance mode, does not upgrade the source files
* except the main .htaccess file
Expand All @@ -204,6 +214,11 @@ private function doUpgrade(string $currentVersion, string $installedVersion): vo
throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
}

// A force-enable applies to the major version it was granted on
if ($this->isMajorUpgrade($installedVersion, $currentVersion)) {
$this->config->deleteSystemValue('app_install_overwrite');
}

// Update .htaccess files
try {
Setup::updateHtaccess();
Expand Down
19 changes: 19 additions & 0 deletions tests/lib/UpdaterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,25 @@ public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersions
$this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersions));
}

/**
* @return array
*/
public static function majorUpgradeTestData(): array {
return [
// Same major version
['33.0.0.10', '33.1.2.3', false],
// Major upgrade
['33.0.5.1', '34.0.0.10', true],
// Downgrade, only reachable with debug enabled
['34.0.0.10', '33.0.5.1', false],
];
}

#[\PHPUnit\Framework\Attributes\DataProvider('majorUpgradeTestData')]
public function testIsMajorUpgrade(string $installedVersion, string $currentVersion, bool $result): void {
$this->assertSame($result, self::invokePrivate($this->updater, 'isMajorUpgrade', [$installedVersion, $currentVersion]));
}

public function testUpgradeAppStoreAppsRestoresMissingAutoDisabledAppBeforeEnabling(): void {
$this->installer->expects($this->once())
->method('isUpdateAvailable')
Expand Down
Loading