Skip to content

Commit

Permalink
Pass an additional parameter on the core update
Browse files Browse the repository at this point in the history
  • Loading branch information
VicDeo committed Nov 19, 2018
1 parent 8c55523 commit 9715514
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 17 deletions.
13 changes: 11 additions & 2 deletions core/Command/Upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@ protected function configure() {
null,
InputOption::VALUE_NONE,
'Skip disabling of third party apps.'
);
)
->addOption(
'--major',
null,
InputOption::VALUE_NONE,
'Automatically update apps to new major versions during minor updates of ownCloud Server'
);
}

/**
Expand All @@ -96,13 +102,16 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$output->setFormatter($timestampFormatter);
}

$self = $this;
$updater = new Updater(
$this->config,
\OC::$server->getIntegrityCodeChecker(),
$this->logger
);

if ($input->getOption('major')) {
$updater->setForceMajorUpgrade(true);
}

$dispatcher = \OC::$server->getEventDispatcher();
$progress = new ProgressBar($output);
$progress->setFormat(" %message%\n %current%/%max% [%bar%] %percent:3s%%");
Expand Down
13 changes: 12 additions & 1 deletion lib/private/Helper/EnvironmentHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
* This class provides non-static wrappers for the static OC class members
*/
class EnvironmentHelper {
/**
* Check if ownCloud runs in cli mode
*
* @return bool
*/
public function isCli() {
return \OC::$CLI;
}

/**
* Get the ownCloud root path for http requests (e.g. owncloud/)
*
Expand Down Expand Up @@ -58,7 +67,9 @@ public function getAppsRoots() {

/**
* Get the environment variable
* @param $envVar
*
* @param string $envVar
*
* @return array|false|string
*/
public function getEnvVar($envVar) {
Expand Down
2 changes: 1 addition & 1 deletion lib/private/Repair.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace OC;

use OC\Helper\EnvironmentHelper;
use OC\Repair\Apps;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
Expand Down Expand Up @@ -195,7 +196,6 @@ public static function getBeforeUpgradeRepairSteps() {
new SqliteAutoincrement($connection),
new RepairOrphanedSubshare($connection),
new SearchLuceneTables(),
new Apps(\OC::$server->getAppManager(), \OC::$server->getEventDispatcher(), \OC::$server->getConfig(), new \OC_Defaults()),
];

//There is no need to delete all previews on every single update
Expand Down
53 changes: 46 additions & 7 deletions lib/private/Repair/Apps.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
use OC\App\Platform;
use OC\Helper\EnvironmentHelper;
use OC\RepairException;
use OC_App;
use OCP\App\AppAlreadyInstalledException;
Expand All @@ -32,12 +33,12 @@
use OCP\App\AppNotInstalledException;
use OCP\App\AppUpdateNotFoundException;
use OCP\App\IAppManager;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use OCP\Util;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use OCP\IConfig;

class Apps implements IRepairStep {
const KEY_COMPATIBLE = 'compatible';
Expand All @@ -47,7 +48,7 @@ class Apps implements IRepairStep {
/** @var IAppManager */
private $appManager;

/** @var EventDispatcher */
/** @var EventDispatcherInterface */
private $eventDispatcher;

/** @var IConfig */
Expand All @@ -56,19 +57,27 @@ class Apps implements IRepairStep {
/** @var \OC_Defaults */
private $defaults;

/** @var EnvironmentHelper */
private $environmentHelper;

/** @var bool */
private $forceMajorUpgrade;

/**
* Apps constructor.
*
* @param IAppManager $appManager
* @param EventDispatcher $eventDispatcher
* @param EventDispatcherInterface $eventDispatcher
* @param IConfig $config
* @param \OC_Defaults $defaults
*/
public function __construct(IAppManager $appManager, EventDispatcher $eventDispatcher, IConfig $config, \OC_Defaults $defaults) {
public function __construct(IAppManager $appManager, EventDispatcherInterface $eventDispatcher, IConfig $config, \OC_Defaults $defaults, EnvironmentHelper $environmentHelper, $forceMajorUpgrade = false) {
$this->appManager = $appManager;
$this->eventDispatcher = $eventDispatcher;
$this->config = $config;
$this->defaults = $defaults;
$this->environmentHelper = $environmentHelper;
$this->forceMajorUpgrade = $forceMajorUpgrade;
}

/**
Expand All @@ -84,14 +93,34 @@ public function getName() {
*/
private function isCoreUpdate() {
$installedVersion = $this->config->getSystemValue('version', '0.0.0');
$currentVersion = \implode('.', Util::getVersion());
$currentVersion = \implode('.', $this->getSourcesVersion());
$versionDiff = \version_compare($currentVersion, $installedVersion);
if ($versionDiff > 0) {
return true;
}
return false;
}

/**
* Is it a major core update
*
* @return bool
*/
private function isMajorCoreUpdate() {
if ($this->forceMajorUpgrade === true) {
return true;
}

$installedVersion = $this->config->getSystemValue('version', '0.0.0');
$installedVersionArray = \explode('.', $installedVersion);
$installedVersionMajor = (int) $installedVersionArray[0];
$targetVersionArray = $this->getSourcesVersion();
$targetVersionMajor = (int) $targetVersionArray[0];
$majorUpgrade = $targetVersionMajor !== $installedVersionMajor;

return $majorUpgrade;
}

/**
* If we are updating from <= 10.0.0 we need to enable the marketplace before running the update
* @return bool
Expand Down Expand Up @@ -219,7 +248,10 @@ protected function getAppsFromMarket(IOutput $output, $appList, $event) {
try {
$this->eventDispatcher->dispatch(
\sprintf('%s::%s', IRepairStep::class, $event),
new GenericEvent($app)
new GenericEvent(
$app,
['isMajorUpdate' => $this->isMajorCoreUpdate()]
)
);
} catch (AppAlreadyInstalledException $e) {
$output->info($e->getMessage());
Expand Down Expand Up @@ -387,4 +419,11 @@ private function changeSchema(Schema $schema, array $options) {
}
}
}

/**
* @return array
*/
protected function getSourcesVersion() {
return Util::getVersion();
}
}
33 changes: 33 additions & 0 deletions lib/private/Updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class Updater extends BasicEmitter {
/** @var Checker */
private $checker;

/** @var bool */
private $forceMajorUpgrade = false;

private $logLevelNames = [
0 => 'Debug',
1 => 'Info',
Expand Down Expand Up @@ -105,6 +108,7 @@ public function upgrade() {

$success = true;
try {
$this->checkAppsCompatibility();
$this->doUpgrade($currentVersion, $installedVersion);
} catch (\Exception $exception) {
$this->log->logException($exception, ['app' => 'core']);
Expand Down Expand Up @@ -187,6 +191,35 @@ public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVers
return false;
}

/**
* @param $forceMajorUpgrade
*/
public function setForceMajorUpgrade($forceMajorUpgrade) {
$this->forceMajorUpgrade = $forceMajorUpgrade;
}

/**
* Check if we have empty app folders or incompatible apps enabled
*/
private function checkAppsCompatibility() {
$dispatcher = \OC::$server->getEventDispatcher();
// App compatibility check
$repair = new Repair(
[
new Repair\Apps(
\OC::$server->getAppManager(),
$dispatcher,
$this->config,
new \OC_Defaults(),
new Helper\EnvironmentHelper(),
$this->forceMajorUpgrade
),
],
$dispatcher
);
$repair->run();
}

/**
* runs the update actions in maintenance mode, does not upgrade the source files
* except the main .htaccess file
Expand Down
83 changes: 77 additions & 6 deletions tests/lib/Repair/AppsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
*
*/
namespace Test\Repair;
use OC\Helper\EnvironmentHelper;
use OC\Repair\Apps;
use OCP\App\IAppManager;
use OCP\IConfig;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;

/**
Expand All @@ -32,25 +34,33 @@
*/
class AppsTest extends TestCase {

/** @var Apps */
/** @var Apps | \PHPUnit_Framework_MockObject_MockObject */
protected $repair;
/** @var IAppManager | \PHPUnit_Framework_MockObject_MockObject */
protected $appManager;
/** @var EventDispatcher | \PHPUnit_Framework_MockObject_MockObject */
/** @var EventDispatcherInterface | \PHPUnit_Framework_MockObject_MockObject */
protected $eventDispatcher;
/** @var IConfig | \PHPUnit_Framework_MockObject_MockObject*/
protected $config;
/** @var \OC_Defaults | \PHPUnit_Framework_MockObject_MockObject */
private $defaults;
/** @var EnvironmentHelper | \PHPUnit_Framework_MockObject_MockObject */
private $environmentHelper;

protected function setUp() {
parent::setUp();

$this->appManager = $this->createMock(IAppManager::class);
$this->defaults = $this->createMock(\OC_Defaults::class);
$this->eventDispatcher = $this->createMock(EventDispatcher::class);
$this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$this->config = $this->createMock(IConfig::class);
$this->repair = new Apps($this->appManager, $this->eventDispatcher, $this->config, $this->defaults);
$this->environmentHelper = $this->createMock(EnvironmentHelper::class);
$this->repair = new Apps(
$this->appManager,
$this->eventDispatcher,
$this->config,
$this->defaults,
$this->environmentHelper
);
}

public function testMarketEnableVersionCompare10() {
Expand All @@ -72,4 +82,65 @@ public function testMarketEnableVersionCompareCurrent() {
$this->config->expects($this->once())->method('getSystemValue')->with('version', '0.0.0')->willReturn('10.0.1');
$this->assertFalse($this->invokePrivate($this->repair, 'requiresMarketEnable'));
}

public function dataTestUpdateEvent() {
return [
['10.1.0.0', [10, 1, 3, 7], false, false], // same major version
['10.1.0.0', [10, 1, 3, 7], true, true], // same major version, but major forced
['10.1.0.0', [11, 0, 2, 0], false, true], // different major version
['10.1.0.0', [10, 0, 2, 0], true, true], // different major version, major forced
];
}

/**
* @dataProvider dataTestUpdateEvent
* @param string $installedVersion
* @param int[] $sourcesVersion
* @param bool $forceMajorUpdate
* @param bool $expectedIsMajorUpdate
*/
public function testUpdateAppEvent($installedVersion, $sourcesVersion, $forceMajorUpdate, $expectedIsMajorUpdate) {
$appName = 'fakeapp';

$this->config->method('getSystemValue')
->with('version', '0.0.0')
->willReturn($installedVersion);
$this->configureRepair(['getSourcesVersion'], $forceMajorUpdate);

$this->repair->method('getSourcesVersion')
->willReturn($sourcesVersion);

$this->eventDispatcher->expects($this->once())->method('dispatch')
->willReturnCallback(
function ($eventName, $event) use ($appName) {
$this->assertEquals($appName, $event->getSubject());
$this->assertEquals(true, $event->getArgument('isMajorUpdate'));
}
);
$this->invokePrivate(
$this->repair,
'getAppsFromMarket',
[
new \OC\Migration\ConsoleOutput(new NullOutput()),
[ $appName ],
'john'
]
);
}

private function configureRepair($mockedMethods, $forceMajorUpgrade = false) {
$this->repair = $this->getMockBuilder(Apps::class)
->setConstructorArgs(
[
$this->appManager,
$this->eventDispatcher,
$this->config,
$this->defaults,
$this->environmentHelper,
$forceMajorUpgrade
]
)
->setMethods($mockedMethods)
->getMock();
}
}

0 comments on commit 9715514

Please sign in to comment.