mirror of
https://github.com/nextcloud/server.git
synced 2026-02-18 18:28:50 -05:00
Merge pull request #53895 from nextcloud/fix/cleanup-updater-class
This commit is contained in:
commit
4edfef4dd5
30 changed files with 774 additions and 899 deletions
|
|
@ -14,7 +14,6 @@ use OC\App\AppStore\Fetcher\AppFetcher;
|
|||
use OC\App\AppStore\Fetcher\CategoryFetcher;
|
||||
use OC\App\AppStore\Version\VersionParser;
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\App\Platform;
|
||||
use OC\Installer;
|
||||
use OCA\AppAPI\Service\ExAppsPageService;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
|
|
@ -361,7 +360,7 @@ class AppSettingsController extends Controller {
|
|||
$this->fetchApps();
|
||||
$apps = $this->getAllApps();
|
||||
|
||||
$dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n);
|
||||
$dependencyAnalyzer = Server::get(DependencyAnalyzer::class);
|
||||
|
||||
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
|
||||
if (!is_array($ignoreMaxApps)) {
|
||||
|
|
@ -568,24 +567,18 @@ class AppSettingsController extends Controller {
|
|||
$appId = $this->appManager->cleanAppId($appId);
|
||||
|
||||
// Check if app is already downloaded
|
||||
/** @var Installer $installer */
|
||||
$installer = Server::get(Installer::class);
|
||||
$isDownloaded = $installer->isDownloaded($appId);
|
||||
|
||||
if (!$isDownloaded) {
|
||||
$installer->downloadApp($appId);
|
||||
if (!$this->installer->isDownloaded($appId)) {
|
||||
$this->installer->downloadApp($appId);
|
||||
}
|
||||
|
||||
$installer->installApp($appId);
|
||||
$this->installer->installApp($appId);
|
||||
|
||||
if (count($groups) > 0) {
|
||||
$this->appManager->enableAppForGroups($appId, $this->getGroupList($groups));
|
||||
} else {
|
||||
$this->appManager->enableApp($appId);
|
||||
}
|
||||
if (\OC_App::shouldUpgrade($appId)) {
|
||||
$updateRequired = true;
|
||||
}
|
||||
$updateRequired = $updateRequired || $this->appManager->isUpgradeRequired($appId);
|
||||
}
|
||||
return new JSONResponse(['data' => ['update_required' => $updateRequired]]);
|
||||
} catch (\Throwable $e) {
|
||||
|
|
|
|||
|
|
@ -3317,14 +3317,6 @@
|
|||
<code><![CDATA[ActivitySettings[]]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
</file>
|
||||
<file src="lib/private/App/DependencyAnalyzer.php">
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[bool]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[version_compare($first, $second, $operator)]]></code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="lib/private/AppFramework/Bootstrap/FunctionInjector.php">
|
||||
<UndefinedMethod>
|
||||
<code><![CDATA[getName]]></code>
|
||||
|
|
@ -4011,12 +4003,6 @@
|
|||
<code><![CDATA[query]]></code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/private/Installer.php">
|
||||
<InvalidArgument>
|
||||
<code><![CDATA[false]]></code>
|
||||
<code><![CDATA[false]]></code>
|
||||
</InvalidArgument>
|
||||
</file>
|
||||
<file src="lib/private/IntegrityCheck/Checker.php">
|
||||
<InvalidArrayAccess>
|
||||
<code><![CDATA[$x509->getDN(X509::DN_OPENSSL)['CN']]]></code>
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OC\Core\Command\Integrity;
|
||||
|
||||
use OC\Core\Command\Base;
|
||||
use OC\IntegrityCheck\Checker;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
||||
use OCP\App\IAppManager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
|
@ -25,7 +25,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
class CheckApp extends Base {
|
||||
public function __construct(
|
||||
private Checker $checker,
|
||||
private AppLocator $appLocator,
|
||||
private FileAccessHelper $fileAccessHelper,
|
||||
private IAppManager $appManager,
|
||||
) {
|
||||
|
|
@ -70,7 +69,7 @@ class CheckApp extends Base {
|
|||
foreach ($appIds as $appId) {
|
||||
$path = (string)$input->getOption('path');
|
||||
if ($path === '') {
|
||||
$path = $this->appLocator->getAppPath($appId);
|
||||
$path = $this->appManager->getAppPath($appId);
|
||||
}
|
||||
|
||||
if ($this->appManager->isShipped($appId) || $this->fileAccessHelper->file_exists($path . '/appinfo/signature.json')) {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
*/
|
||||
use OC\Core\Listener\FeedBackHandler;
|
||||
use OC\DB\MigratorExecuteSqlEvent;
|
||||
use OC\Installer;
|
||||
use OC\IntegrityCheck\Checker;
|
||||
use OC\Repair\Events\RepairAdvanceEvent;
|
||||
use OC\Repair\Events\RepairErrorEvent;
|
||||
use OC\Repair\Events\RepairFinishEvent;
|
||||
|
|
@ -20,13 +18,11 @@ use OC\SystemConfig;
|
|||
use OC\Updater;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\IEventSourceFactory;
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Server;
|
||||
use OCP\ServerVersion;
|
||||
use OCP\Util;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
|
@ -58,14 +54,7 @@ if (Util::needUpgrade()) {
|
|||
\OC_User::setIncognitoMode(true);
|
||||
|
||||
$config = Server::get(IConfig::class);
|
||||
$updater = new Updater(
|
||||
Server::get(ServerVersion::class),
|
||||
$config,
|
||||
Server::get(IAppConfig::class),
|
||||
Server::get(Checker::class),
|
||||
Server::get(LoggerInterface::class),
|
||||
Server::get(Installer::class)
|
||||
);
|
||||
$updater = Server::get(Updater::class);
|
||||
$incompatibleApps = [];
|
||||
$incompatibleOverwrites = $config->getSystemValue('app_install_overwrite', []);
|
||||
|
||||
|
|
|
|||
|
|
@ -1790,7 +1790,6 @@ return array(
|
|||
'OC\\Installer' => $baseDir . '/lib/private/Installer.php',
|
||||
'OC\\IntegrityCheck\\Checker' => $baseDir . '/lib/private/IntegrityCheck/Checker.php',
|
||||
'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException' => $baseDir . '/lib/private/IntegrityCheck/Exceptions/InvalidSignatureException.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\AppLocator' => $baseDir . '/lib/private/IntegrityCheck/Helpers/AppLocator.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\EnvironmentHelper' => $baseDir . '/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\FileAccessHelper' => $baseDir . '/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php',
|
||||
'OC\\IntegrityCheck\\Iterator\\ExcludeFileByNameFilterIterator' => $baseDir . '/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php',
|
||||
|
|
|
|||
|
|
@ -1831,7 +1831,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Installer' => __DIR__ . '/../../..' . '/lib/private/Installer.php',
|
||||
'OC\\IntegrityCheck\\Checker' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Checker.php',
|
||||
'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Exceptions/InvalidSignatureException.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\AppLocator' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Helpers/AppLocator.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\EnvironmentHelper' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php',
|
||||
'OC\\IntegrityCheck\\Helpers\\FileAccessHelper' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php',
|
||||
'OC\\IntegrityCheck\\Iterator\\ExcludeFileByNameFilterIterator' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php',
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@ namespace OC\App;
|
|||
use OC\AppConfig;
|
||||
use OC\AppFramework\Bootstrap\Coordinator;
|
||||
use OC\Config\ConfigManager;
|
||||
use OC\DB\MigrationService;
|
||||
use OCP\Activity\IManager as IActivityManager;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\Events\AppDisableEvent;
|
||||
use OCP\App\Events\AppEnableEvent;
|
||||
use OCP\App\Events\AppUpdateEvent;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\App\ManagerEvent;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Collaboration\AutoComplete\IManager as IAutoCompleteManager;
|
||||
use OCP\Collaboration\Collaborators\ISearch as ICollaboratorSearch;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
|
|
@ -86,6 +89,7 @@ class AppManager implements IAppManager {
|
|||
private LoggerInterface $logger,
|
||||
private ServerVersion $serverVersion,
|
||||
private ConfigManager $configManager,
|
||||
private DependencyAnalyzer $dependencyAnalyzer,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -249,9 +253,14 @@ class AppManager implements IAppManager {
|
|||
foreach ($apps as $app) {
|
||||
// If the app is already loaded then autoloading it makes no sense
|
||||
if (!$this->isAppLoaded($app)) {
|
||||
$path = \OC_App::getAppPath($app);
|
||||
if ($path !== false) {
|
||||
try {
|
||||
$path = $this->getAppPath($app);
|
||||
\OC_App::registerAutoloading($app, $path);
|
||||
} catch (AppPathNotFoundException $e) {
|
||||
$this->logger->info('Error during app loading: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'app' => $app,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -447,8 +456,13 @@ class AppManager implements IAppManager {
|
|||
return;
|
||||
}
|
||||
$this->loadedApps[$app] = true;
|
||||
$appPath = \OC_App::getAppPath($app);
|
||||
if ($appPath === false) {
|
||||
try {
|
||||
$appPath = $this->getAppPath($app);
|
||||
} catch (AppPathNotFoundException $e) {
|
||||
$this->logger->info('Error during app loading: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'app' => $app,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
$eventLogger = \OC::$server->get(IEventLogger::class);
|
||||
|
|
@ -675,29 +689,87 @@ class AppManager implements IAppManager {
|
|||
/**
|
||||
* Get the directory for the given app.
|
||||
*
|
||||
* @psalm-taint-specialize
|
||||
*
|
||||
* @throws AppPathNotFoundException if app folder can't be found
|
||||
*/
|
||||
public function getAppPath(string $appId): string {
|
||||
$appPath = \OC_App::getAppPath($appId);
|
||||
if ($appPath === false) {
|
||||
throw new AppPathNotFoundException('Could not find path for ' . $appId);
|
||||
public function getAppPath(string $appId, bool $ignoreCache = false): string {
|
||||
$appId = $this->cleanAppId($appId);
|
||||
if ($appId === '') {
|
||||
throw new AppPathNotFoundException('App id is empty');
|
||||
} elseif ($appId === 'core') {
|
||||
return __DIR__ . '/../../../core';
|
||||
}
|
||||
return $appPath;
|
||||
|
||||
if (($dir = $this->findAppInDirectories($appId, $ignoreCache)) != false) {
|
||||
return $dir['path'] . '/' . $appId;
|
||||
}
|
||||
throw new AppPathNotFoundException('Could not find path for ' . $appId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the web path for the given app.
|
||||
*
|
||||
* @param string $appId
|
||||
* @return string
|
||||
* @throws AppPathNotFoundException if app path can't be found
|
||||
*/
|
||||
public function getAppWebPath(string $appId): string {
|
||||
$appWebPath = \OC_App::getAppWebPath($appId);
|
||||
if ($appWebPath === false) {
|
||||
throw new AppPathNotFoundException('Could not find web path for ' . $appId);
|
||||
if (($dir = $this->findAppInDirectories($appId)) != false) {
|
||||
return \OC::$WEBROOT . $dir['url'] . '/' . $appId;
|
||||
}
|
||||
throw new AppPathNotFoundException('Could not find web path for ' . $appId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the apps root for an app id.
|
||||
*
|
||||
* If multiple copies are found, the apps root the latest version is returned.
|
||||
*
|
||||
* @param bool $ignoreCache ignore cache and rebuild it
|
||||
* @return false|array{path: string, url: string} the apps root shape
|
||||
*/
|
||||
public function findAppInDirectories(string $appId, bool $ignoreCache = false) {
|
||||
$sanitizedAppId = $this->cleanAppId($appId);
|
||||
if ($sanitizedAppId !== $appId) {
|
||||
return false;
|
||||
}
|
||||
// FIXME replace by a property or a cache
|
||||
static $app_dir = [];
|
||||
|
||||
if (isset($app_dir[$appId]) && !$ignoreCache) {
|
||||
return $app_dir[$appId];
|
||||
}
|
||||
|
||||
$possibleApps = [];
|
||||
foreach (\OC::$APPSROOTS as $dir) {
|
||||
if (file_exists($dir['path'] . '/' . $appId)) {
|
||||
$possibleApps[] = $dir;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($possibleApps)) {
|
||||
return false;
|
||||
} elseif (count($possibleApps) === 1) {
|
||||
$dir = array_shift($possibleApps);
|
||||
$app_dir[$appId] = $dir;
|
||||
return $dir;
|
||||
} else {
|
||||
$versionToLoad = [];
|
||||
foreach ($possibleApps as $possibleApp) {
|
||||
$appData = $this->getAppInfoByPath($possibleApp['path'] . '/' . $appId . '/appinfo/info.xml');
|
||||
$version = $appData['version'] ?? '';
|
||||
if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
|
||||
$versionToLoad = [
|
||||
'dir' => $possibleApp,
|
||||
'version' => $version,
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!isset($versionToLoad['dir'])) {
|
||||
return false;
|
||||
}
|
||||
$app_dir[$appId] = $versionToLoad['dir'];
|
||||
return $versionToLoad['dir'];
|
||||
}
|
||||
return $appWebPath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -724,7 +796,7 @@ class AppManager implements IAppManager {
|
|||
if ($appDbVersion
|
||||
&& isset($appInfo['version'])
|
||||
&& version_compare($appInfo['version'], $appDbVersion, '>')
|
||||
&& \OC_App::isAppCompatible($version, $appInfo)
|
||||
&& $this->isAppCompatible($version, $appInfo)
|
||||
) {
|
||||
$appsToUpgrade[] = $appInfo;
|
||||
}
|
||||
|
|
@ -814,7 +886,7 @@ class AppManager implements IAppManager {
|
|||
$info = $this->getAppInfo($appId);
|
||||
if ($info === null) {
|
||||
$incompatibleApps[] = ['id' => $appId, 'name' => $appId];
|
||||
} elseif (!\OC_App::isAppCompatible($version, $info)) {
|
||||
} elseif (!$this->isAppCompatible($version, $info)) {
|
||||
$incompatibleApps[] = $info;
|
||||
}
|
||||
}
|
||||
|
|
@ -949,4 +1021,94 @@ class AppManager implements IAppManager {
|
|||
/* Only lowercase alphanumeric is allowed */
|
||||
return preg_replace('/(^[0-9_]|[^a-z0-9_]+|_$)/', '', $app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run upgrade tasks for an app after the code has already been updated
|
||||
*
|
||||
* @throws AppPathNotFoundException if app folder can't be found
|
||||
*/
|
||||
public function upgradeApp(string $appId): bool {
|
||||
// for apps distributed with core, we refresh app path in case the downloaded version
|
||||
// have been installed in custom apps and not in the default path
|
||||
$appPath = $this->getAppPath($appId, true);
|
||||
|
||||
$this->clearAppsCache();
|
||||
$l = \OC::$server->getL10N('core');
|
||||
$appData = $this->getAppInfo($appId, false, $l->getLanguageCode());
|
||||
if ($appData === null) {
|
||||
throw new AppPathNotFoundException('Could not find ' . $appId);
|
||||
}
|
||||
|
||||
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
|
||||
$ignoreMax = in_array($appId, $ignoreMaxApps, true);
|
||||
\OC_App::checkAppDependencies(
|
||||
$this->config,
|
||||
$l,
|
||||
$appData,
|
||||
$ignoreMax
|
||||
);
|
||||
|
||||
\OC_App::registerAutoloading($appId, $appPath, true);
|
||||
\OC_App::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
|
||||
|
||||
$ms = new MigrationService($appId, Server::get(\OC\DB\Connection::class));
|
||||
$ms->migrate();
|
||||
|
||||
\OC_App::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
|
||||
$queue = Server::get(IJobList::class);
|
||||
foreach ($appData['repair-steps']['live-migration'] as $step) {
|
||||
$queue->add(\OC\Migration\BackgroundRepair::class, [
|
||||
'app' => $appId,
|
||||
'step' => $step]);
|
||||
}
|
||||
|
||||
// update appversion in app manager
|
||||
$this->clearAppsCache();
|
||||
$this->getAppVersion($appId, false);
|
||||
|
||||
// Setup background jobs
|
||||
foreach ($appData['background-jobs'] as $job) {
|
||||
$queue->add($job);
|
||||
}
|
||||
|
||||
//set remote/public handlers
|
||||
foreach ($appData['remote'] as $name => $path) {
|
||||
$this->config->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
|
||||
}
|
||||
foreach ($appData['public'] as $name => $path) {
|
||||
$this->config->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
|
||||
}
|
||||
|
||||
\OC_App::setAppTypes($appId);
|
||||
|
||||
$version = $this->getAppVersion($appId);
|
||||
$this->config->setAppValue($appId, 'installed_version', $version);
|
||||
|
||||
// migrate eventual new config keys in the process
|
||||
/** @psalm-suppress InternalMethod */
|
||||
$this->configManager->migrateConfigLexiconKeys($appId);
|
||||
|
||||
$this->dispatcher->dispatchTyped(new AppUpdateEvent($appId));
|
||||
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
|
||||
ManagerEvent::EVENT_APP_UPDATE, $appId
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isUpgradeRequired(string $appId): bool {
|
||||
$versions = $this->getAppInstalledVersions();
|
||||
$currentVersion = $this->getAppVersion($appId);
|
||||
if ($currentVersion && isset($versions[$appId])) {
|
||||
$installedVersion = $versions[$appId];
|
||||
if (!version_compare($currentVersion, $installedVersion, '=')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isAppCompatible(string $serverVersion, array $appInfo, bool $ignoreMax = false): bool {
|
||||
return count($this->dependencyAnalyzer->analyzeServerVersion($serverVersion, $appInfo, $ignoreMax)) === 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,20 +11,29 @@ declare(strict_types=1);
|
|||
namespace OC\App;
|
||||
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Server;
|
||||
|
||||
class DependencyAnalyzer {
|
||||
// Cannot be injected because when this class is built IAppManager is not available yet
|
||||
private ?IL10N $l = null;
|
||||
|
||||
public function __construct(
|
||||
private Platform $platform,
|
||||
private IL10N $l,
|
||||
) {
|
||||
}
|
||||
|
||||
private function getL(): IL10N {
|
||||
$this->l ??= Server::get(IFactory::class)->get('lib');
|
||||
return $this->l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of missing dependencies
|
||||
*/
|
||||
public function analyze(array $app, bool $ignoreMax = false): array {
|
||||
if (isset($app['dependencies'])) {
|
||||
$dependencies = $app['dependencies'];
|
||||
public function analyze(array $appInfo, bool $ignoreMax = false): array {
|
||||
if (isset($appInfo['dependencies'])) {
|
||||
$dependencies = $appInfo['dependencies'];
|
||||
} else {
|
||||
$dependencies = [];
|
||||
}
|
||||
|
|
@ -36,18 +45,12 @@ class DependencyAnalyzer {
|
|||
$this->analyzeCommands($dependencies),
|
||||
$this->analyzeLibraries($dependencies),
|
||||
$this->analyzeOS($dependencies),
|
||||
$this->analyzeOC($dependencies, $app, $ignoreMax)
|
||||
$this->analyzeServer($appInfo, $ignoreMax),
|
||||
);
|
||||
}
|
||||
|
||||
public function isMarkedCompatible(array $app): bool {
|
||||
if (isset($app['dependencies'])) {
|
||||
$dependencies = $app['dependencies'];
|
||||
} else {
|
||||
$dependencies = [];
|
||||
}
|
||||
|
||||
$maxVersion = $this->getMaxVersion($dependencies, $app);
|
||||
public function isMarkedCompatible(array $appInfo): bool {
|
||||
$maxVersion = $this->getMaxVersion($appInfo);
|
||||
if ($maxVersion === null) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -76,6 +79,7 @@ class DependencyAnalyzer {
|
|||
/**
|
||||
* Parameters will be normalized and then passed into version_compare
|
||||
* in the same order they are specified in the method header
|
||||
* @param '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
|
||||
* @return bool result similar to version_compare
|
||||
*/
|
||||
private function compare(string $first, string $second, string $operator): bool {
|
||||
|
|
@ -105,19 +109,19 @@ class DependencyAnalyzer {
|
|||
if (isset($dependencies['php']['@attributes']['min-version'])) {
|
||||
$minVersion = $dependencies['php']['@attributes']['min-version'];
|
||||
if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
|
||||
$missing[] = $this->l->t('PHP %s or higher is required.', [$minVersion]);
|
||||
$missing[] = $this->getL()->t('PHP %s or higher is required.', [$minVersion]);
|
||||
}
|
||||
}
|
||||
if (isset($dependencies['php']['@attributes']['max-version'])) {
|
||||
$maxVersion = $dependencies['php']['@attributes']['max-version'];
|
||||
if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
|
||||
$missing[] = $this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
|
||||
$missing[] = $this->getL()->t('PHP with a version lower than %s is required.', [$maxVersion]);
|
||||
}
|
||||
}
|
||||
if (isset($dependencies['php']['@attributes']['min-int-size'])) {
|
||||
$intSize = $dependencies['php']['@attributes']['min-int-size'];
|
||||
if ($intSize > $this->platform->getIntSize() * 8) {
|
||||
$missing[] = $this->l->t('%sbit or higher PHP required.', [$intSize]);
|
||||
$missing[] = $this->getL()->t('%sbit or higher PHP required.', [$intSize]);
|
||||
}
|
||||
}
|
||||
return $missing;
|
||||
|
|
@ -141,7 +145,7 @@ class DependencyAnalyzer {
|
|||
}, $supportedArchitectures);
|
||||
$currentArchitecture = $this->platform->getArchitecture();
|
||||
if (!in_array($currentArchitecture, $supportedArchitectures, true)) {
|
||||
$missing[] = $this->l->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
|
||||
$missing[] = $this->getL()->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
|
||||
}
|
||||
return $missing;
|
||||
}
|
||||
|
|
@ -167,7 +171,7 @@ class DependencyAnalyzer {
|
|||
}, $supportedDatabases);
|
||||
$currentDatabase = $this->platform->getDatabase();
|
||||
if (!in_array($currentDatabase, $supportedDatabases)) {
|
||||
$missing[] = $this->l->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
|
||||
$missing[] = $this->getL()->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
|
||||
}
|
||||
return $missing;
|
||||
}
|
||||
|
|
@ -192,7 +196,7 @@ class DependencyAnalyzer {
|
|||
}
|
||||
$commandName = $this->getValue($command);
|
||||
if (!$this->platform->isCommandKnown($commandName)) {
|
||||
$missing[] = $this->l->t('The command line tool %s could not be found', [$commandName]);
|
||||
$missing[] = $this->getL()->t('The command line tool %s could not be found', [$commandName]);
|
||||
}
|
||||
}
|
||||
return $missing;
|
||||
|
|
@ -215,7 +219,7 @@ class DependencyAnalyzer {
|
|||
$libName = $this->getValue($lib);
|
||||
$libVersion = $this->platform->getLibraryVersion($libName);
|
||||
if (is_null($libVersion)) {
|
||||
$missing[] = $this->l->t('The library %s is not available.', [$libName]);
|
||||
$missing[] = $this->getL()->t('The library %s is not available.', [$libName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -223,14 +227,14 @@ class DependencyAnalyzer {
|
|||
if (isset($lib['@attributes']['min-version'])) {
|
||||
$minVersion = $lib['@attributes']['min-version'];
|
||||
if ($this->compareSmaller($libVersion, $minVersion)) {
|
||||
$missing[] = $this->l->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
|
||||
$missing[] = $this->getL()->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
|
||||
[$libName, $minVersion, $libVersion]);
|
||||
}
|
||||
}
|
||||
if (isset($lib['@attributes']['max-version'])) {
|
||||
$maxVersion = $lib['@attributes']['max-version'];
|
||||
if ($this->compareBigger($libVersion, $maxVersion)) {
|
||||
$missing[] = $this->l->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
|
||||
$missing[] = $this->getL()->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
|
||||
[$libName, $maxVersion, $libVersion]);
|
||||
}
|
||||
}
|
||||
|
|
@ -258,44 +262,48 @@ class DependencyAnalyzer {
|
|||
}
|
||||
$currentOS = $this->platform->getOS();
|
||||
if (!in_array($currentOS, $oss)) {
|
||||
$missing[] = $this->l->t('The following platforms are supported: %s', [implode(', ', $oss)]);
|
||||
$missing[] = $this->getL()->t('The following platforms are supported: %s', [implode(', ', $oss)]);
|
||||
}
|
||||
return $missing;
|
||||
}
|
||||
|
||||
private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax): array {
|
||||
private function analyzeServer(array $appInfo, bool $ignoreMax): array {
|
||||
return $this->analyzeServerVersion($this->platform->getOcVersion(), $appInfo, $ignoreMax);
|
||||
}
|
||||
|
||||
public function analyzeServerVersion(string $serverVersion, array $appInfo, bool $ignoreMax): array {
|
||||
$missing = [];
|
||||
$minVersion = null;
|
||||
if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
|
||||
$minVersion = $dependencies['nextcloud']['@attributes']['min-version'];
|
||||
} elseif (isset($dependencies['owncloud']['@attributes']['min-version'])) {
|
||||
$minVersion = $dependencies['owncloud']['@attributes']['min-version'];
|
||||
if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
|
||||
$minVersion = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
|
||||
} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
|
||||
$minVersion = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
|
||||
} elseif (isset($appInfo['requiremin'])) {
|
||||
$minVersion = $appInfo['requiremin'];
|
||||
} elseif (isset($appInfo['require'])) {
|
||||
$minVersion = $appInfo['require'];
|
||||
}
|
||||
$maxVersion = $this->getMaxVersion($dependencies, $appInfo);
|
||||
$maxVersion = $this->getMaxVersion($appInfo);
|
||||
|
||||
if (!is_null($minVersion)) {
|
||||
if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
|
||||
$missing[] = $this->l->t('Server version %s or higher is required.', [$minVersion]);
|
||||
if ($this->compareSmaller($serverVersion, $minVersion)) {
|
||||
$missing[] = $this->getL()->t('Server version %s or higher is required.', [$minVersion]);
|
||||
}
|
||||
}
|
||||
if (!$ignoreMax && !is_null($maxVersion)) {
|
||||
if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
|
||||
$missing[] = $this->l->t('Server version %s or lower is required.', [$maxVersion]);
|
||||
if ($this->compareBigger($serverVersion, $maxVersion)) {
|
||||
$missing[] = $this->getL()->t('Server version %s or lower is required.', [$maxVersion]);
|
||||
}
|
||||
}
|
||||
return $missing;
|
||||
}
|
||||
|
||||
private function getMaxVersion(array $dependencies, array $appInfo): ?string {
|
||||
if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
|
||||
return $dependencies['nextcloud']['@attributes']['max-version'];
|
||||
private function getMaxVersion(array $appInfo): ?string {
|
||||
if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
|
||||
return $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
|
||||
}
|
||||
if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
|
||||
return $dependencies['owncloud']['@attributes']['max-version'];
|
||||
if (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
|
||||
return $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
|
||||
}
|
||||
if (isset($appInfo['requiremax'])) {
|
||||
return $appInfo['requiremax'];
|
||||
|
|
@ -304,13 +312,9 @@ class DependencyAnalyzer {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $element
|
||||
* @return mixed
|
||||
*/
|
||||
private function getValue($element) {
|
||||
private function getValue(mixed $element): string {
|
||||
if (isset($element['@value'])) {
|
||||
return $element['@value'];
|
||||
return (string)$element['@value'];
|
||||
}
|
||||
return (string)$element;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use Doctrine\DBAL\Schema\SchemaException;
|
|||
use Doctrine\DBAL\Schema\Sequence;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use OC\App\InfoParser;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\Migration\SimpleOutput;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
|
|
@ -39,7 +39,12 @@ class MigrationService {
|
|||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(string $appName, Connection $connection, ?IOutput $output = null, ?AppLocator $appLocator = null, ?LoggerInterface $logger = null) {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
Connection $connection,
|
||||
?IOutput $output = null,
|
||||
?LoggerInterface $logger = null,
|
||||
) {
|
||||
$this->appName = $appName;
|
||||
$this->connection = $connection;
|
||||
if ($logger === null) {
|
||||
|
|
@ -58,10 +63,8 @@ class MigrationService {
|
|||
$this->migrationsNamespace = 'OC\\Core\\Migrations';
|
||||
$this->checkOracle = true;
|
||||
} else {
|
||||
if ($appLocator === null) {
|
||||
$appLocator = new AppLocator();
|
||||
}
|
||||
$appPath = $appLocator->getAppPath($appName);
|
||||
$appManager = Server::get(IAppManager::class);
|
||||
$appPath = $appManager->getAppPath($appName);
|
||||
$namespace = App::buildAppNamespace($appName);
|
||||
$this->migrationsPath = "$appPath/lib/Migration";
|
||||
$this->migrationsNamespace = $namespace . '\\Migration';
|
||||
|
|
@ -728,7 +731,7 @@ class MigrationService {
|
|||
}
|
||||
}
|
||||
|
||||
private function ensureMigrationsAreLoaded() {
|
||||
private function ensureMigrationsAreLoaded(): void {
|
||||
if (empty($this->migrations)) {
|
||||
$this->migrations = $this->findMigrations();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,15 @@ use OC\Archive\TAR;
|
|||
use OC\DB\Connection;
|
||||
use OC\DB\MigrationService;
|
||||
use OC\Files\FilenameValidator;
|
||||
use OC_App;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Files;
|
||||
use OCP\HintException;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IConfig;
|
||||
use OCP\ITempManager;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Server;
|
||||
use phpseclib\File\X509;
|
||||
|
|
@ -43,6 +45,8 @@ class Installer {
|
|||
private ITempManager $tempManager,
|
||||
private LoggerInterface $logger,
|
||||
private IConfig $config,
|
||||
private IAppManager $appManager,
|
||||
private IFactory $l10nFactory,
|
||||
private bool $isCLI,
|
||||
) {
|
||||
}
|
||||
|
|
@ -56,21 +60,12 @@ class Installer {
|
|||
* @return string app ID
|
||||
*/
|
||||
public function installApp(string $appId, bool $forceEnable = false): string {
|
||||
$app = \OC_App::findAppInDirectories($appId);
|
||||
if ($app === false) {
|
||||
throw new \Exception('App not found in any app directory');
|
||||
}
|
||||
$appPath = $this->appManager->getAppPath($appId, true);
|
||||
|
||||
$basedir = $app['path'] . '/' . $appId;
|
||||
$l = $this->l10nFactory->get('core');
|
||||
$info = $this->appManager->getAppInfoByPath($appPath . '/appinfo/info.xml', $l->getLanguageCode());
|
||||
|
||||
if (is_file($basedir . '/appinfo/database.xml')) {
|
||||
throw new \Exception('The appinfo/database.xml file is not longer supported. Used in ' . $appId);
|
||||
}
|
||||
|
||||
$l = \OCP\Util::getL10N('core');
|
||||
$info = \OCP\Server::get(IAppManager::class)->getAppInfoByPath($basedir . '/appinfo/info.xml', $l->getLanguageCode());
|
||||
|
||||
if (!is_array($info)) {
|
||||
if (!is_array($info) || $info['id'] !== $appId) {
|
||||
throw new \Exception(
|
||||
$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
|
||||
[$appId]
|
||||
|
|
@ -82,9 +77,8 @@ class Installer {
|
|||
$ignoreMax = $forceEnable || in_array($appId, $ignoreMaxApps, true);
|
||||
|
||||
$version = implode('.', \OCP\Util::getVersion());
|
||||
if (!\OC_App::isAppCompatible($version, $info, $ignoreMax)) {
|
||||
if (!$this->appManager->isAppCompatible($version, $info, $ignoreMax)) {
|
||||
throw new \Exception(
|
||||
// TODO $l
|
||||
$l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
|
||||
[$info['name']]
|
||||
)
|
||||
|
|
@ -93,47 +87,10 @@ class Installer {
|
|||
|
||||
// check for required dependencies
|
||||
\OC_App::checkAppDependencies($this->config, $l, $info, $ignoreMax);
|
||||
/** @var Coordinator $coordinator */
|
||||
$coordinator = \OC::$server->get(Coordinator::class);
|
||||
$coordinator = Server::get(Coordinator::class);
|
||||
$coordinator->runLazyRegistration($appId);
|
||||
\OC_App::registerAutoloading($appId, $basedir);
|
||||
|
||||
$previousVersion = $this->config->getAppValue($info['id'], 'installed_version', false);
|
||||
if ($previousVersion) {
|
||||
OC_App::executeRepairSteps($appId, $info['repair-steps']['pre-migration']);
|
||||
}
|
||||
|
||||
//install the database
|
||||
$ms = new MigrationService($info['id'], \OCP\Server::get(Connection::class));
|
||||
$ms->migrate('latest', !$previousVersion);
|
||||
|
||||
if ($previousVersion) {
|
||||
OC_App::executeRepairSteps($appId, $info['repair-steps']['post-migration']);
|
||||
}
|
||||
|
||||
\OC_App::setupBackgroundJobs($info['background-jobs']);
|
||||
|
||||
//run appinfo/install.php
|
||||
self::includeAppScript($basedir . '/appinfo/install.php');
|
||||
|
||||
OC_App::executeRepairSteps($appId, $info['repair-steps']['install']);
|
||||
|
||||
$config = \OCP\Server::get(IConfig::class);
|
||||
//set the installed version
|
||||
$config->setAppValue($info['id'], 'installed_version', \OCP\Server::get(IAppManager::class)->getAppVersion($info['id'], false));
|
||||
$config->setAppValue($info['id'], 'enabled', 'no');
|
||||
|
||||
//set remote/public handlers
|
||||
foreach ($info['remote'] as $name => $path) {
|
||||
$config->setAppValue('core', 'remote_' . $name, $info['id'] . '/' . $path);
|
||||
}
|
||||
foreach ($info['public'] as $name => $path) {
|
||||
$config->setAppValue('core', 'public_' . $name, $info['id'] . '/' . $path);
|
||||
}
|
||||
|
||||
OC_App::setAppTypes($info['id']);
|
||||
|
||||
return $info['id'];
|
||||
return $this->installAppLastSteps($appPath, $info, null, 'no');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -142,7 +99,7 @@ class Installer {
|
|||
* @param bool $allowUnstable Allow unstable releases
|
||||
*/
|
||||
public function updateAppstoreApp(string $appId, bool $allowUnstable = false): bool {
|
||||
if ($this->isUpdateAvailable($appId, $allowUnstable)) {
|
||||
if ($this->isUpdateAvailable($appId, $allowUnstable) !== false) {
|
||||
try {
|
||||
$this->downloadApp($appId, $allowUnstable);
|
||||
} catch (\Exception $e) {
|
||||
|
|
@ -151,7 +108,7 @@ class Installer {
|
|||
]);
|
||||
return false;
|
||||
}
|
||||
return OC_App::updateApp($appId);
|
||||
return $this->appManager->upgradeApp($appId);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -347,7 +304,7 @@ class Installer {
|
|||
}
|
||||
|
||||
// Check if the version is lower than before
|
||||
$currentVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId, true);
|
||||
$currentVersion = $this->appManager->getAppVersion($appId, true);
|
||||
$newVersion = (string)$xml->version;
|
||||
if (version_compare($currentVersion, $newVersion) === 1) {
|
||||
throw new \Exception(
|
||||
|
|
@ -424,7 +381,7 @@ class Installer {
|
|||
|
||||
foreach ($this->apps as $app) {
|
||||
if ($app['id'] === $appId) {
|
||||
$currentVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId, true);
|
||||
$currentVersion = $this->appManager->getAppVersion($appId, true);
|
||||
|
||||
if (!isset($app['releases'][0]['version'])) {
|
||||
return false;
|
||||
|
|
@ -447,12 +404,12 @@ class Installer {
|
|||
* The function will check if the path contains a .git folder
|
||||
*/
|
||||
private function isInstalledFromGit(string $appId): bool {
|
||||
$app = \OC_App::findAppInDirectories($appId);
|
||||
if ($app === false) {
|
||||
try {
|
||||
$appPath = $this->appManager->getAppPath($appId);
|
||||
return file_exists($appPath . '/.git/');
|
||||
} catch (AppPathNotFoundException) {
|
||||
return false;
|
||||
}
|
||||
$basedir = $app['path'] . '/' . $appId;
|
||||
return file_exists($basedir . '/.git/');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -487,7 +444,7 @@ class Installer {
|
|||
*/
|
||||
public function removeApp(string $appId): bool {
|
||||
if ($this->isDownloaded($appId)) {
|
||||
if (\OCP\Server::get(IAppManager::class)->isShipped($appId)) {
|
||||
if ($this->appManager->isShipped($appId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -518,8 +475,7 @@ class Installer {
|
|||
$this->downloadApp($appId);
|
||||
}
|
||||
$this->installApp($appId);
|
||||
$app = new OC_App();
|
||||
$app->enable($appId);
|
||||
$this->appManager->enableApp($appId);
|
||||
}
|
||||
$bundles = json_decode($this->config->getAppValue('core', 'installed.bundles', json_encode([])), true);
|
||||
$bundles[] = $bundle->getIdentifier();
|
||||
|
|
@ -534,25 +490,23 @@ class Installer {
|
|||
* working ownCloud at the end instead of an aborted update.
|
||||
* @return array Array of error messages (appid => Exception)
|
||||
*/
|
||||
public static function installShippedApps(bool $softErrors = false, ?IOutput $output = null): array {
|
||||
public function installShippedApps(bool $softErrors = false, ?IOutput $output = null): array {
|
||||
if ($output instanceof IOutput) {
|
||||
$output->debug('Installing shipped apps');
|
||||
}
|
||||
$appManager = \OCP\Server::get(IAppManager::class);
|
||||
$config = \OCP\Server::get(IConfig::class);
|
||||
$errors = [];
|
||||
foreach (\OC::$APPSROOTS as $app_dir) {
|
||||
if ($dir = opendir($app_dir['path'])) {
|
||||
while (false !== ($filename = readdir($dir))) {
|
||||
if ($filename[0] !== '.' and is_dir($app_dir['path'] . "/$filename")) {
|
||||
if (file_exists($app_dir['path'] . "/$filename/appinfo/info.xml")) {
|
||||
if ($config->getAppValue($filename, 'installed_version') === '') {
|
||||
$enabled = $appManager->isDefaultEnabled($filename);
|
||||
if (($enabled || in_array($filename, $appManager->getAlwaysEnabledApps()))
|
||||
&& $config->getAppValue($filename, 'enabled') !== 'no') {
|
||||
if ($this->config->getAppValue($filename, 'installed_version') === '') {
|
||||
$enabled = $this->appManager->isDefaultEnabled($filename);
|
||||
if (($enabled || in_array($filename, $this->appManager->getAlwaysEnabledApps()))
|
||||
&& $this->config->getAppValue($filename, 'enabled') !== 'no') {
|
||||
if ($softErrors) {
|
||||
try {
|
||||
Installer::installShippedApp($filename, $output);
|
||||
$this->installShippedApp($filename, $output);
|
||||
} catch (HintException $e) {
|
||||
if ($e->getPrevious() instanceof TableExistsException) {
|
||||
$errors[$filename] = $e;
|
||||
|
|
@ -561,9 +515,9 @@ class Installer {
|
|||
throw $e;
|
||||
}
|
||||
} else {
|
||||
Installer::installShippedApp($filename, $output);
|
||||
$this->installShippedApp($filename, $output);
|
||||
}
|
||||
$config->setAppValue($filename, 'enabled', 'yes');
|
||||
$this->config->setAppValue($filename, 'enabled', 'yes');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -576,59 +530,79 @@ class Installer {
|
|||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* install an app already placed in the app folder
|
||||
*/
|
||||
public static function installShippedApp(string $app, ?IOutput $output = null): string|false {
|
||||
if ($output instanceof IOutput) {
|
||||
$output->debug('Installing ' . $app);
|
||||
}
|
||||
private function installAppLastSteps(string $appPath, array $info, ?IOutput $output = null, string $enabled = 'no'): string {
|
||||
\OC_App::registerAutoloading($info['id'], $appPath);
|
||||
|
||||
$appManager = \OCP\Server::get(IAppManager::class);
|
||||
$config = \OCP\Server::get(IConfig::class);
|
||||
|
||||
$appPath = $appManager->getAppPath($app);
|
||||
\OC_App::registerAutoloading($app, $appPath);
|
||||
|
||||
$ms = new MigrationService($app, \OCP\Server::get(Connection::class));
|
||||
$previousVersion = $this->config->getAppValue($info['id'], 'installed_version', '');
|
||||
$ms = new MigrationService($info['id'], Server::get(Connection::class));
|
||||
if ($output instanceof IOutput) {
|
||||
$ms->setOutput($output);
|
||||
}
|
||||
$previousVersion = $config->getAppValue($app, 'installed_version', false);
|
||||
$ms->migrate('latest', !$previousVersion);
|
||||
|
||||
//run appinfo/install.php
|
||||
self::includeAppScript("$appPath/appinfo/install.php");
|
||||
|
||||
$info = \OCP\Server::get(IAppManager::class)->getAppInfo($app);
|
||||
if (is_null($info)) {
|
||||
return false;
|
||||
if ($previousVersion !== '') {
|
||||
\OC_App::executeRepairSteps($info['id'], $info['repair-steps']['pre-migration']);
|
||||
}
|
||||
|
||||
$ms->migrate('latest', $previousVersion === '');
|
||||
|
||||
if ($previousVersion !== '') {
|
||||
\OC_App::executeRepairSteps($info['id'], $info['repair-steps']['post-migration']);
|
||||
}
|
||||
|
||||
if ($output instanceof IOutput) {
|
||||
$output->debug('Registering tasks of ' . $app);
|
||||
}
|
||||
\OC_App::setupBackgroundJobs($info['background-jobs']);
|
||||
|
||||
OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
|
||||
|
||||
$config->setAppValue($app, 'installed_version', \OCP\Server::get(IAppManager::class)->getAppVersion($app));
|
||||
if (array_key_exists('ocsid', $info)) {
|
||||
$config->setAppValue($app, 'ocsid', $info['ocsid']);
|
||||
$output->debug('Registering tasks of ' . $info['id']);
|
||||
}
|
||||
|
||||
//set remote/public handlers
|
||||
// Setup background jobs
|
||||
$queue = Server::get(IJobList::class);
|
||||
foreach ($info['background-jobs'] as $job) {
|
||||
$queue->add($job);
|
||||
}
|
||||
|
||||
// Run deprecated appinfo/install.php if any
|
||||
$appInstallScriptPath = $appPath . '/appinfo/install.php';
|
||||
if (file_exists($appInstallScriptPath)) {
|
||||
$this->logger->warning('Using an appinfo/install.php file is deprecated. Application "{app}" still uses one.', [
|
||||
'app' => $info['id'],
|
||||
]);
|
||||
self::includeAppScript($appInstallScriptPath);
|
||||
}
|
||||
|
||||
\OC_App::executeRepairSteps($info['id'], $info['repair-steps']['install']);
|
||||
|
||||
// Set the installed version
|
||||
$this->config->setAppValue($info['id'], 'installed_version', $this->appManager->getAppVersion($info['id'], false));
|
||||
$this->config->setAppValue($info['id'], 'enabled', $enabled);
|
||||
|
||||
// Set remote/public handlers
|
||||
foreach ($info['remote'] as $name => $path) {
|
||||
$config->setAppValue('core', 'remote_' . $name, $app . '/' . $path);
|
||||
$this->config->setAppValue('core', 'remote_' . $name, $info['id'] . '/' . $path);
|
||||
}
|
||||
foreach ($info['public'] as $name => $path) {
|
||||
$config->setAppValue('core', 'public_' . $name, $app . '/' . $path);
|
||||
$this->config->setAppValue('core', 'public_' . $name, $info['id'] . '/' . $path);
|
||||
}
|
||||
|
||||
OC_App::setAppTypes($info['id']);
|
||||
\OC_App::setAppTypes($info['id']);
|
||||
|
||||
return $info['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* install an app already placed in the app folder
|
||||
*/
|
||||
public function installShippedApp(string $app, ?IOutput $output = null): string|false {
|
||||
if ($output instanceof IOutput) {
|
||||
$output->debug('Installing ' . $app);
|
||||
}
|
||||
$info = $this->appManager->getAppInfo($app);
|
||||
if (is_null($info) || $info['id'] !== $app) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$appPath = $this->appManager->getAppPath($app);
|
||||
|
||||
return $this->installAppLastSteps($appPath, $info, $output, 'yes');
|
||||
}
|
||||
|
||||
private static function includeAppScript(string $script): void {
|
||||
if (file_exists($script)) {
|
||||
include $script;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ namespace OC\IntegrityCheck;
|
|||
|
||||
use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder;
|
||||
use OC\IntegrityCheck\Exceptions\InvalidSignatureException;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
||||
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
||||
use OC\IntegrityCheck\Iterator\ExcludeFileByNameFilterIterator;
|
||||
|
|
@ -44,7 +43,6 @@ class Checker {
|
|||
private ServerVersion $serverVersion,
|
||||
private EnvironmentHelper $environmentHelper,
|
||||
private FileAccessHelper $fileAccessHelper,
|
||||
private AppLocator $appLocator,
|
||||
private ?IConfig $config,
|
||||
private ?IAppConfig $appConfig,
|
||||
ICacheFactory $cacheFactory,
|
||||
|
|
@ -460,7 +458,7 @@ class Checker {
|
|||
public function verifyAppSignature(string $appId, string $path = '', bool $forceVerify = false): array {
|
||||
try {
|
||||
if ($path === '') {
|
||||
$path = $this->appLocator->getAppPath($appId);
|
||||
$path = $this->appManager->getAppPath($appId);
|
||||
}
|
||||
$result = $this->verify(
|
||||
$path . '/appinfo/signature.json',
|
||||
|
|
@ -545,7 +543,7 @@ class Checker {
|
|||
$appNeedsToBeChecked = false;
|
||||
if ($isShipped) {
|
||||
$appNeedsToBeChecked = true;
|
||||
} elseif ($this->fileAccessHelper->file_exists($this->appLocator->getAppPath($appId) . '/appinfo/signature.json')) {
|
||||
} elseif ($this->fileAccessHelper->file_exists($this->appManager->getAppPath($appId) . '/appinfo/signature.json')) {
|
||||
// Otherwise only if the application explicitly ships a signature.json file
|
||||
$appNeedsToBeChecked = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OC\IntegrityCheck\Helpers;
|
||||
|
||||
/**
|
||||
* Class AppLocator provides a non-static helper for OC_App::getPath($appId)
|
||||
* it is not possible to use IAppManager at this point as IAppManager has a
|
||||
* dependency on a running Nextcloud.
|
||||
*
|
||||
* @package OC\IntegrityCheck\Helpers
|
||||
*/
|
||||
class AppLocator {
|
||||
/**
|
||||
* Provides \OC_App::getAppPath($appId)
|
||||
*
|
||||
* @param string $appId
|
||||
* @return string
|
||||
* @throws \Exception If the app cannot be found
|
||||
*/
|
||||
public function getAppPath(string $appId): string {
|
||||
$path = \OC_App::getAppPath($appId);
|
||||
if ($path === false) {
|
||||
throw new \Exception('App not found');
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ use NCU\Security\Signature\ISignatureManager;
|
|||
use OC\Accounts\AccountManager;
|
||||
use OC\App\AppManager;
|
||||
use OC\App\AppStore\Bundles\BundleFetcher;
|
||||
use OC\App\AppStore\Fetcher\AppFetcher;
|
||||
use OC\AppFramework\Bootstrap\Coordinator;
|
||||
use OC\AppFramework\Http\Request;
|
||||
use OC\AppFramework\Http\RequestId;
|
||||
|
|
@ -66,7 +65,6 @@ use OC\FullTextSearch\FullTextSearchManager;
|
|||
use OC\Http\Client\ClientService;
|
||||
use OC\Http\Client\NegativeDnsCache;
|
||||
use OC\IntegrityCheck\Checker;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
||||
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
||||
use OC\KnownUser\KnownUserService;
|
||||
|
|
@ -842,7 +840,6 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
$c->get(ServerVersion::class),
|
||||
$c->get(EnvironmentHelper::class),
|
||||
new FileAccessHelper(),
|
||||
new AppLocator(),
|
||||
$config,
|
||||
$appConfig,
|
||||
$c->get(ICacheFactory::class),
|
||||
|
|
@ -1177,17 +1174,6 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
);
|
||||
});
|
||||
|
||||
$this->registerService(Installer::class, function (ContainerInterface $c) {
|
||||
return new Installer(
|
||||
$c->get(AppFetcher::class),
|
||||
$c->get(IClientService::class),
|
||||
$c->get(ITempManager::class),
|
||||
$c->get(LoggerInterface::class),
|
||||
$c->get(\OCP\IConfig::class),
|
||||
\OC::$CLI
|
||||
);
|
||||
});
|
||||
|
||||
$this->registerService(IApiFactory::class, function (ContainerInterface $c) {
|
||||
return new ApiFactory($c->get(IClientService::class));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -443,7 +443,8 @@ class Setup {
|
|||
|
||||
// Install shipped apps and specified app bundles
|
||||
$this->outputDebug($output, 'Install default apps');
|
||||
Installer::installShippedApps(false, $output);
|
||||
$installer = Server::get(Installer::class);
|
||||
$installer->installShippedApps(false, $output);
|
||||
|
||||
// create empty file in data dir, so we can later find
|
||||
// out that this is indeed a Nextcloud data directory
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ use OC\Repair\Events\RepairInfoEvent;
|
|||
use OC\Repair\Events\RepairStartEvent;
|
||||
use OC\Repair\Events\RepairStepEvent;
|
||||
use OC\Repair\Events\RepairWarningEvent;
|
||||
use OC_App;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
|
@ -60,6 +59,7 @@ class Updater extends BasicEmitter {
|
|||
private Checker $checker,
|
||||
private ?LoggerInterface $log,
|
||||
private Installer $installer,
|
||||
private IAppManager $appManager,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -238,18 +238,16 @@ class Updater extends BasicEmitter {
|
|||
// Update the appfetchers version so it downloads the correct list from the appstore
|
||||
\OC::$server->get(AppFetcher::class)->setVersion($currentVersion);
|
||||
|
||||
/** @var AppManager $appManager */
|
||||
$appManager = \OC::$server->getAppManager();
|
||||
|
||||
// upgrade appstore apps
|
||||
$this->upgradeAppStoreApps($appManager->getEnabledApps());
|
||||
$autoDisabledApps = $appManager->getAutoDisabledApps();
|
||||
$this->upgradeAppStoreApps($this->appManager->getEnabledApps());
|
||||
/** @var AppManager $this->appManager */
|
||||
$autoDisabledApps = $this->appManager->getAutoDisabledApps();
|
||||
if (!empty($autoDisabledApps)) {
|
||||
$this->upgradeAppStoreApps(array_keys($autoDisabledApps), $autoDisabledApps);
|
||||
}
|
||||
|
||||
// install new shipped apps on upgrade
|
||||
$errors = Installer::installShippedApps(true);
|
||||
$errors = $this->installer->installShippedApps(true);
|
||||
foreach ($errors as $appId => $exception) {
|
||||
/** @var \Exception $exception */
|
||||
$this->log->error($exception->getMessage(), [
|
||||
|
|
@ -296,7 +294,7 @@ class Updater extends BasicEmitter {
|
|||
* @throws NeedsUpdateException
|
||||
*/
|
||||
protected function doAppUpgrade(): void {
|
||||
$apps = \OC_App::getEnabledApps();
|
||||
$apps = $this->appManager->getEnabledApps();
|
||||
$priorityTypes = ['authentication', 'extended_authentication', 'filesystem', 'logging'];
|
||||
$pseudoOtherType = 'other';
|
||||
$stacks = [$pseudoOtherType => []];
|
||||
|
|
@ -307,7 +305,7 @@ class Updater extends BasicEmitter {
|
|||
if (!isset($stacks[$type])) {
|
||||
$stacks[$type] = [];
|
||||
}
|
||||
if (\OC_App::isType($appId, [$type])) {
|
||||
if ($this->appManager->isType($appId, [$type])) {
|
||||
$stacks[$type][] = $appId;
|
||||
$priorityType = true;
|
||||
break;
|
||||
|
|
@ -320,16 +318,16 @@ class Updater extends BasicEmitter {
|
|||
foreach (array_merge($priorityTypes, [$pseudoOtherType]) as $type) {
|
||||
$stack = $stacks[$type];
|
||||
foreach ($stack as $appId) {
|
||||
if (\OC_App::shouldUpgrade($appId)) {
|
||||
$this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OCP\Server::get(IAppManager::class)->getAppVersion($appId)]);
|
||||
\OC_App::updateApp($appId);
|
||||
$this->emit('\OC\Updater', 'appUpgrade', [$appId, \OCP\Server::get(IAppManager::class)->getAppVersion($appId)]);
|
||||
if ($this->appManager->isUpgradeRequired($appId)) {
|
||||
$this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, $this->appManager->getAppVersion($appId)]);
|
||||
$this->appManager->upgradeApp($appId);
|
||||
$this->emit('\OC\Updater', 'appUpgrade', [$appId, $this->appManager->getAppVersion($appId)]);
|
||||
}
|
||||
if ($type !== $pseudoOtherType) {
|
||||
// load authentication, filesystem and logging apps after
|
||||
// upgrading them. Other apps my need to rely on modifying
|
||||
// user and/or filesystem aspects.
|
||||
\OC_App::loadApp($appId);
|
||||
$this->appManager->loadApp($appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -345,25 +343,21 @@ class Updater extends BasicEmitter {
|
|||
*/
|
||||
private function checkAppsRequirements(): void {
|
||||
$isCoreUpgrade = $this->isCodeUpgrade();
|
||||
$apps = OC_App::getEnabledApps();
|
||||
$apps = $this->appManager->getEnabledApps();
|
||||
$version = implode('.', Util::getVersion());
|
||||
$appManager = \OC::$server->getAppManager();
|
||||
foreach ($apps as $app) {
|
||||
// check if the app is compatible with this version of Nextcloud
|
||||
$info = $appManager->getAppInfo($app);
|
||||
if ($info === null || !OC_App::isAppCompatible($version, $info)) {
|
||||
if ($appManager->isShipped($app)) {
|
||||
$info = $this->appManager->getAppInfo($app);
|
||||
if ($info === null || !$this->appManager->isAppCompatible($version, $info)) {
|
||||
if ($this->appManager->isShipped($app)) {
|
||||
throw new \UnexpectedValueException('The files of the app "' . $app . '" were not correctly replaced before running the update');
|
||||
}
|
||||
$appManager->disableApp($app, true);
|
||||
$this->appManager->disableApp($app, true);
|
||||
$this->emit('\OC\Updater', 'incompatibleAppDisabled', [$app]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isCodeUpgrade(): bool {
|
||||
$installedVersion = $this->config->getSystemValueString('version', '0.0.0');
|
||||
$currentVersion = implode('.', Util::getVersion());
|
||||
|
|
@ -395,12 +389,11 @@ class Updater extends BasicEmitter {
|
|||
}
|
||||
$this->emit('\OC\Updater', 'checkAppStoreApp', [$app]);
|
||||
|
||||
if (!empty($previousEnableStates)) {
|
||||
$ocApp = new \OC_App();
|
||||
if (isset($previousEnableStates[$app])) {
|
||||
if (!empty($previousEnableStates[$app]) && is_array($previousEnableStates[$app])) {
|
||||
$ocApp->enable($app, $previousEnableStates[$app]);
|
||||
} else {
|
||||
$ocApp->enable($app);
|
||||
$this->appManager->enableAppForGroups($app, $previousEnableStates[$app]);
|
||||
} elseif ($previousEnableStates[$app] === 'yes') {
|
||||
$this->appManager->enableApp($app);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
|
|
|
|||
|
|
@ -6,17 +6,14 @@ declare(strict_types=1);
|
|||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
use OC\App\AppManager;
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\App\Platform;
|
||||
use OC\AppFramework\Bootstrap\Coordinator;
|
||||
use OC\Config\ConfigManager;
|
||||
use OC\DB\MigrationService;
|
||||
use OC\Installer;
|
||||
use OC\Repair;
|
||||
use OC\Repair\Events\RepairErrorEvent;
|
||||
use OCP\App\Events\AppUpdateEvent;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\App\ManagerEvent;
|
||||
use OCP\Authentication\IAlternativeLogin;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IAppConfig;
|
||||
|
|
@ -205,6 +202,7 @@ class OC_App {
|
|||
* @param array $groups (optional) when set, only these groups will have access to the app
|
||||
* @throws \Exception
|
||||
* @return void
|
||||
* @deprecated 32.0.0 Use the installer and the app manager instead
|
||||
*
|
||||
* This function set an app as enabled in appconfig.
|
||||
*/
|
||||
|
|
@ -242,49 +240,12 @@ class OC_App {
|
|||
*
|
||||
* If multiple copies are found, the apps root the latest version is returned.
|
||||
*
|
||||
* @param string $appId
|
||||
* @param bool $ignoreCache ignore cache and rebuild it
|
||||
* @return false|array{path: string, url: string} the apps root shape
|
||||
* @deprecated 32.0.0 internal, use getAppPath or getAppWebPath
|
||||
*/
|
||||
public static function findAppInDirectories(string $appId, bool $ignoreCache = false) {
|
||||
$sanitizedAppId = self::cleanAppId($appId);
|
||||
if ($sanitizedAppId !== $appId) {
|
||||
return false;
|
||||
}
|
||||
static $app_dir = [];
|
||||
|
||||
if (isset($app_dir[$appId]) && !$ignoreCache) {
|
||||
return $app_dir[$appId];
|
||||
}
|
||||
|
||||
$possibleApps = [];
|
||||
foreach (OC::$APPSROOTS as $dir) {
|
||||
if (file_exists($dir['path'] . '/' . $appId)) {
|
||||
$possibleApps[] = $dir;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($possibleApps)) {
|
||||
return false;
|
||||
} elseif (count($possibleApps) === 1) {
|
||||
$dir = array_shift($possibleApps);
|
||||
$app_dir[$appId] = $dir;
|
||||
return $dir;
|
||||
} else {
|
||||
$versionToLoad = [];
|
||||
foreach ($possibleApps as $possibleApp) {
|
||||
$version = self::getAppVersionByPath($possibleApp['path'] . '/' . $appId);
|
||||
if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
|
||||
$versionToLoad = [
|
||||
'dir' => $possibleApp,
|
||||
'version' => $version,
|
||||
];
|
||||
}
|
||||
}
|
||||
$app_dir[$appId] = $versionToLoad['dir'];
|
||||
return $versionToLoad['dir'];
|
||||
//TODO - write test
|
||||
}
|
||||
return Server::get(AppManager::class)->findAppInDirectories($appId, $ignoreCache);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -299,17 +260,11 @@ class OC_App {
|
|||
* @deprecated 11.0.0 use Server::get(IAppManager)->getAppPath()
|
||||
*/
|
||||
public static function getAppPath(string $appId, bool $refreshAppPath = false) {
|
||||
$appId = self::cleanAppId($appId);
|
||||
if ($appId === '') {
|
||||
try {
|
||||
return Server::get(IAppManager::class)->getAppPath($appId, $refreshAppPath);
|
||||
} catch (AppPathNotFoundException) {
|
||||
return false;
|
||||
} elseif ($appId === 'core') {
|
||||
return __DIR__ . '/../../../core';
|
||||
}
|
||||
|
||||
if (($dir = self::findAppInDirectories($appId, $refreshAppPath)) != false) {
|
||||
return $dir['path'] . '/' . $appId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -318,20 +273,20 @@ class OC_App {
|
|||
*
|
||||
* @param string $appId
|
||||
* @return string|false
|
||||
* @deprecated 18.0.0 use \OC::$server->getAppManager()->getAppWebPath()
|
||||
* @deprecated 18.0.0 use Server::get(IAppManager)->getAppWebPath()
|
||||
*/
|
||||
public static function getAppWebPath(string $appId) {
|
||||
if (($dir = self::findAppInDirectories($appId)) != false) {
|
||||
return OC::$WEBROOT . $dir['url'] . '/' . $appId;
|
||||
try {
|
||||
return Server::get(IAppManager::class)->getAppWebPath($appId);
|
||||
} catch (AppPathNotFoundException) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get app's version based on it's path
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @deprecated 32.0.0 use Server::get(IAppManager)->getAppInfoByPath() with the path to info.xml directly
|
||||
*/
|
||||
public static function getAppVersionByPath(string $path): string {
|
||||
$infoFile = $path . '/appinfo/info.xml';
|
||||
|
|
@ -542,38 +497,11 @@ class OC_App {
|
|||
return $appList;
|
||||
}
|
||||
|
||||
public static function shouldUpgrade(string $app): bool {
|
||||
$versions = self::getAppVersions();
|
||||
$currentVersion = Server::get(\OCP\App\IAppManager::class)->getAppVersion($app);
|
||||
if ($currentVersion && isset($versions[$app])) {
|
||||
$installedVersion = $versions[$app];
|
||||
if (!version_compare($currentVersion, $installedVersion, '=')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the number of version parts of $version1 to match
|
||||
* the number of version parts of $version2.
|
||||
*
|
||||
* @param string $version1 version to adjust
|
||||
* @param string $version2 version to take the number of parts from
|
||||
* @return string shortened $version1
|
||||
* @deprecated 32.0.0 Use IAppManager::isUpgradeRequired instead
|
||||
*/
|
||||
private static function adjustVersionParts(string $version1, string $version2): string {
|
||||
$version1 = explode('.', $version1);
|
||||
$version2 = explode('.', $version2);
|
||||
// reduce $version1 to match the number of parts in $version2
|
||||
while (count($version1) > count($version2)) {
|
||||
array_pop($version1);
|
||||
}
|
||||
// if $version1 does not have enough parts, add some
|
||||
while (count($version1) < count($version2)) {
|
||||
$version1[] = '0';
|
||||
}
|
||||
return implode('.', $version1);
|
||||
public static function shouldUpgrade(string $app): bool {
|
||||
return Server::get(\OCP\App\IAppManager::class)->isUpgradeRequired($app);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -590,42 +518,11 @@ class OC_App {
|
|||
* @param string $ocVersion Nextcloud version to check against
|
||||
* @param array $appInfo app info (from xml)
|
||||
*
|
||||
* @return boolean true if compatible, otherwise false
|
||||
* @return bool true if compatible, otherwise false
|
||||
* @deprecated 32.0.0 Use IAppManager::isAppCompatible instead
|
||||
*/
|
||||
public static function isAppCompatible(string $ocVersion, array $appInfo, bool $ignoreMax = false): bool {
|
||||
$requireMin = '';
|
||||
$requireMax = '';
|
||||
if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
|
||||
$requireMin = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
|
||||
} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
|
||||
$requireMin = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
|
||||
} elseif (isset($appInfo['requiremin'])) {
|
||||
$requireMin = $appInfo['requiremin'];
|
||||
} elseif (isset($appInfo['require'])) {
|
||||
$requireMin = $appInfo['require'];
|
||||
}
|
||||
|
||||
if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
|
||||
$requireMax = $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
|
||||
} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
|
||||
$requireMax = $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
|
||||
} elseif (isset($appInfo['requiremax'])) {
|
||||
$requireMax = $appInfo['requiremax'];
|
||||
}
|
||||
|
||||
if (!empty($requireMin)
|
||||
&& version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$ignoreMax && !empty($requireMax)
|
||||
&& version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Server::get(\OCP\App\IAppManager::class)->isAppCompatible($ocVersion, $appInfo, $ignoreMax);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -639,77 +536,14 @@ class OC_App {
|
|||
/**
|
||||
* update the database for the app and call the update script
|
||||
*
|
||||
* @param string $appId
|
||||
* @return bool
|
||||
* @deprecated 32.0.0 Use IAppManager::upgradeApp instead
|
||||
*/
|
||||
public static function updateApp(string $appId): bool {
|
||||
// for apps distributed with core, we refresh app path in case the downloaded version
|
||||
// have been installed in custom apps and not in the default path
|
||||
$appPath = self::getAppPath($appId, true);
|
||||
if ($appPath === false) {
|
||||
try {
|
||||
return Server::get(\OC\App\AppManager::class)->upgradeApp($appId);
|
||||
} catch (\OCP\App\AppPathNotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_file($appPath . '/appinfo/database.xml')) {
|
||||
Server::get(LoggerInterface::class)->error('The appinfo/database.xml file is not longer supported. Used in ' . $appId);
|
||||
return false;
|
||||
}
|
||||
|
||||
\OC::$server->getAppManager()->clearAppsCache();
|
||||
$l = \OC::$server->getL10N('core');
|
||||
$appData = Server::get(\OCP\App\IAppManager::class)->getAppInfo($appId, false, $l->getLanguageCode());
|
||||
|
||||
$ignoreMaxApps = \OC::$server->getConfig()->getSystemValue('app_install_overwrite', []);
|
||||
$ignoreMax = in_array($appId, $ignoreMaxApps, true);
|
||||
\OC_App::checkAppDependencies(
|
||||
\OC::$server->getConfig(),
|
||||
$l,
|
||||
$appData,
|
||||
$ignoreMax
|
||||
);
|
||||
|
||||
self::registerAutoloading($appId, $appPath, true);
|
||||
self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
|
||||
|
||||
$ms = new MigrationService($appId, \OC::$server->get(\OC\DB\Connection::class));
|
||||
$ms->migrate();
|
||||
|
||||
self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
|
||||
self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']);
|
||||
// update appversion in app manager
|
||||
\OC::$server->getAppManager()->clearAppsCache();
|
||||
\OC::$server->getAppManager()->getAppVersion($appId, false);
|
||||
|
||||
self::setupBackgroundJobs($appData['background-jobs']);
|
||||
|
||||
//set remote/public handlers
|
||||
if (array_key_exists('ocsid', $appData)) {
|
||||
\OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
|
||||
} elseif (\OC::$server->getConfig()->getAppValue($appId, 'ocsid') !== '') {
|
||||
\OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
|
||||
}
|
||||
foreach ($appData['remote'] as $name => $path) {
|
||||
\OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
|
||||
}
|
||||
foreach ($appData['public'] as $name => $path) {
|
||||
\OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
|
||||
}
|
||||
|
||||
self::setAppTypes($appId);
|
||||
|
||||
$version = Server::get(\OCP\App\IAppManager::class)->getAppVersion($appId);
|
||||
\OC::$server->getConfig()->setAppValue($appId, 'installed_version', $version);
|
||||
|
||||
// migrate eventual new config keys in the process
|
||||
/** @psalm-suppress InternalMethod */
|
||||
Server::get(ConfigManager::class)->migrateConfigLexiconKeys($appId);
|
||||
|
||||
\OC::$server->get(IEventDispatcher::class)->dispatchTyped(new AppUpdateEvent($appId));
|
||||
\OC::$server->get(IEventDispatcher::class)->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
|
||||
ManagerEvent::EVENT_APP_UPDATE, $appId
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -740,6 +574,9 @@ class OC_App {
|
|||
$r->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 32.0.0 Use the IJobList directly instead
|
||||
*/
|
||||
public static function setupBackgroundJobs(array $jobs) {
|
||||
$queue = \OC::$server->getJobList();
|
||||
foreach ($jobs as $job) {
|
||||
|
|
@ -747,19 +584,6 @@ class OC_App {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $appId
|
||||
* @param string[] $steps
|
||||
*/
|
||||
private static function setupLiveMigrations(string $appId, array $steps) {
|
||||
$queue = \OC::$server->getJobList();
|
||||
foreach ($steps as $step) {
|
||||
$queue->add('OC\Migration\BackgroundRepair', [
|
||||
'app' => $appId,
|
||||
'step' => $step]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OCP\IConfig $config
|
||||
* @param \OCP\IL10N $l
|
||||
|
|
@ -767,7 +591,7 @@ class OC_App {
|
|||
* @throws \Exception
|
||||
*/
|
||||
public static function checkAppDependencies(\OCP\IConfig $config, \OCP\IL10N $l, array $info, bool $ignoreMax) {
|
||||
$dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
|
||||
$dependencyAnalyzer = Server::get(DependencyAnalyzer::class);
|
||||
$missing = $dependencyAnalyzer->analyze($info, $ignoreMax);
|
||||
if (!empty($missing)) {
|
||||
$missingMsg = implode(PHP_EOL, $missing);
|
||||
|
|
|
|||
|
|
@ -166,9 +166,10 @@ interface IAppManager {
|
|||
* Get the directory for the given app.
|
||||
*
|
||||
* @since 11.0.0
|
||||
* @since 32.0.0 Added param $ignoreCache to ignore cache
|
||||
* @throws AppPathNotFoundException
|
||||
*/
|
||||
public function getAppPath(string $appId): string;
|
||||
public function getAppPath(string $appId, bool $ignoreCache = false): string;
|
||||
|
||||
/**
|
||||
* Get the web path for the given app.
|
||||
|
|
@ -340,4 +341,36 @@ interface IAppManager {
|
|||
* @since 31.0.0
|
||||
*/
|
||||
public function getAllAppsInAppsFolders(): array;
|
||||
|
||||
/**
|
||||
* Run upgrade tasks for an app after the code has already been updated
|
||||
*
|
||||
* @throws AppPathNotFoundException if app folder can't be found
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function upgradeApp(string $appId): bool;
|
||||
|
||||
/**
|
||||
* Check whether the installed version is the same as the version from info.xml
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function isUpgradeRequired(string $appId): bool;
|
||||
|
||||
/**
|
||||
* Check whether the current Nextcloud version matches the given
|
||||
* application's version requirements.
|
||||
*
|
||||
* The comparison is made based on the number of parts that the
|
||||
* app info version has. For example for Nextcloud 26.0.3 if the
|
||||
* app info version is expecting version 26.0, the comparison is
|
||||
* made on the first two parts of the Nextcloud version.
|
||||
* This means that it's possible to specify "requiremin" => 26
|
||||
* and "requiremax" => 26 and it will still match Nextcloud 26.0.3.
|
||||
*
|
||||
* @param string $serverVersion Nextcloud version to check against
|
||||
* @param array $appInfo app info (from xml)
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function isAppCompatible(string $serverVersion, array $appInfo, bool $ignoreMax = false): bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
"admin": "admin-encryption"
|
||||
},
|
||||
"types": ["filesystem"],
|
||||
"ocsid": "166047",
|
||||
"dependencies": {
|
||||
"php": {
|
||||
"@attributes" : {
|
||||
|
|
|
|||
|
|
@ -22,5 +22,4 @@
|
|||
<types>
|
||||
<filesystem/>
|
||||
</types>
|
||||
<ocsid>166047</ocsid>
|
||||
</info>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
<types>
|
||||
<filesystem/>
|
||||
</types>
|
||||
<ocsid>166047</ocsid>
|
||||
<dependencies>
|
||||
<php min-version="5.4" max-version="5.5"/>
|
||||
<database min-version="3.0">sqlite</database>
|
||||
|
|
|
|||
|
|
@ -6,10 +6,18 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
use OC\Installer;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Server;
|
||||
|
||||
require_once __DIR__ . '/../lib/base.php';
|
||||
|
||||
function enableApp($app) {
|
||||
(new \OC_App())->enable($app);
|
||||
$installer = Server::get(Installer::class);
|
||||
$appManager = Server::get(IAppManager::class);
|
||||
|
||||
$installer->installApp($app);
|
||||
$appManager->enableApp($app);
|
||||
echo "Enabled application {$app}\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ declare(strict_types=1);
|
|||
namespace Test\App;
|
||||
|
||||
use OC\App\AppManager;
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\App\Platform;
|
||||
use OC\AppConfig;
|
||||
use OC\Config\ConfigManager;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\Events\AppDisableEvent;
|
||||
use OCP\App\Events\AppEnableEvent;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
|
|
@ -96,8 +97,9 @@ class AppManagerTest extends TestCase {
|
|||
protected ServerVersion&MockObject $serverVersion;
|
||||
protected ConfigManager&MockObject $configManager;
|
||||
|
||||
/** @var IAppManager */
|
||||
protected $manager;
|
||||
protected DependencyAnalyzer $dependencyAnalyzer;
|
||||
|
||||
protected AppManager $manager;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -113,6 +115,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||
$this->serverVersion = $this->createMock(ServerVersion::class);
|
||||
$this->configManager = $this->createMock(ConfigManager::class);
|
||||
$this->dependencyAnalyzer = new DependencyAnalyzer($this->createMock(Platform::class));
|
||||
|
||||
$this->overwriteService(AppConfig::class, $this->appConfig);
|
||||
$this->overwriteService(IURLGenerator::class, $this->urlGenerator);
|
||||
|
|
@ -136,6 +139,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -275,6 +279,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppPath',
|
||||
|
|
@ -331,6 +336,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppPath',
|
||||
|
|
@ -394,6 +400,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppPath',
|
||||
|
|
@ -474,16 +481,16 @@ class AppManagerTest extends TestCase {
|
|||
'writable' => false,
|
||||
];
|
||||
|
||||
$fakeTestAppPath = $fakeAppPath . '/' . 'test-test-app';
|
||||
$fakeTestAppPath = $fakeAppPath . '/' . 'test_test_app';
|
||||
mkdir($fakeTestAppPath);
|
||||
|
||||
$generatedAppPath = $this->manager->getAppPath('test-test-app');
|
||||
$generatedAppPath = $this->manager->getAppPath('test_test_app');
|
||||
|
||||
rmdir($fakeTestAppPath);
|
||||
unlink($fakeAppLink);
|
||||
rmdir($fakeAppPath);
|
||||
|
||||
$this->assertEquals($fakeAppLink . '/test-test-app', $generatedAppPath);
|
||||
$this->assertEquals($fakeAppLink . '/test_test_app', $generatedAppPath);
|
||||
}
|
||||
|
||||
public function testGetAppPathFail(): void {
|
||||
|
|
@ -589,7 +596,7 @@ class AppManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetAppsNeedingUpgrade(): void {
|
||||
/** @var AppManager|MockObject $manager */
|
||||
/** @var AppManager&MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([
|
||||
$this->userSession,
|
||||
|
|
@ -600,6 +607,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods(['getAppInfo'])
|
||||
->getMock();
|
||||
|
|
@ -661,6 +669,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods(['getAppInfo'])
|
||||
->getMock();
|
||||
|
|
@ -801,6 +810,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppInfo',
|
||||
|
|
@ -833,6 +843,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppInfo',
|
||||
|
|
@ -864,6 +875,7 @@ class AppManagerTest extends TestCase {
|
|||
$this->logger,
|
||||
$this->serverVersion,
|
||||
$this->configManager,
|
||||
$this->dependencyAnalyzer,
|
||||
])
|
||||
->onlyMethods([
|
||||
'getAppInfo',
|
||||
|
|
@ -884,5 +896,4 @@ class AppManagerTest extends TestCase {
|
|||
$manager->getAppVersion('unknown'),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,13 @@ namespace Test\App;
|
|||
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\App\Platform;
|
||||
use OCP\IL10N;
|
||||
use Test\TestCase;
|
||||
|
||||
class DependencyAnalyzerTest extends TestCase {
|
||||
/** @var Platform|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $platformMock;
|
||||
|
||||
/** @var IL10N */
|
||||
private $l10nMock;
|
||||
|
||||
/** @var DependencyAnalyzer */
|
||||
private $analyser;
|
||||
private DependencyAnalyzer $analyser;
|
||||
|
||||
protected function setUp(): void {
|
||||
$this->platformMock = $this->getMockBuilder(Platform::class)
|
||||
|
|
@ -55,16 +50,7 @@ class DependencyAnalyzerTest extends TestCase {
|
|||
->method('getOcVersion')
|
||||
->willReturn('8.0.2');
|
||||
|
||||
$this->l10nMock = $this->getMockBuilder(IL10N::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->l10nMock->expects($this->any())
|
||||
->method('t')
|
||||
->willReturnCallback(function ($text, $parameters = []) {
|
||||
return vsprintf($text, $parameters);
|
||||
});
|
||||
|
||||
$this->analyser = new DependencyAnalyzer($this->platformMock, $this->l10nMock);
|
||||
$this->analyser = new DependencyAnalyzer($this->platformMock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -485,4 +471,286 @@ class DependencyAnalyzerTest extends TestCase {
|
|||
[[], '5.4', '5.4', null],
|
||||
];
|
||||
}
|
||||
|
||||
public static function appVersionsProvider(): array {
|
||||
return [
|
||||
// exact match
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// in-between match
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// app too old
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '5.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// app too new
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only min specified
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only min specified fail
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only min specified legacy
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'require' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only min specified legacy fail
|
||||
[
|
||||
'4.0.0.0',
|
||||
[
|
||||
'require' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only max specified
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only max specified fail
|
||||
[
|
||||
'7.0.0.0',
|
||||
[
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// variations of versions
|
||||
// single OC number
|
||||
[
|
||||
'4',
|
||||
[
|
||||
'require' => '4.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// multiple OC number
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.3',
|
||||
],
|
||||
true
|
||||
],
|
||||
// single app number
|
||||
[
|
||||
'4',
|
||||
[
|
||||
'require' => '4',
|
||||
],
|
||||
true
|
||||
],
|
||||
// single app number fail
|
||||
[
|
||||
'4.3',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
false
|
||||
],
|
||||
// complex
|
||||
[
|
||||
'5.0.0',
|
||||
[
|
||||
'require' => '4.5.1',
|
||||
],
|
||||
true
|
||||
],
|
||||
// complex fail
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.3.2',
|
||||
],
|
||||
false
|
||||
],
|
||||
// two numbers
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.4',
|
||||
],
|
||||
false
|
||||
],
|
||||
// one number fail
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
false
|
||||
],
|
||||
// pre-alpha app
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'require' => '4.93',
|
||||
],
|
||||
true
|
||||
],
|
||||
// pre-alpha OC
|
||||
[
|
||||
'6.90.0.2',
|
||||
[
|
||||
'require' => '6.90',
|
||||
],
|
||||
true
|
||||
],
|
||||
// pre-alpha OC max
|
||||
[
|
||||
'6.90.0.2',
|
||||
[
|
||||
'requiremax' => '7',
|
||||
],
|
||||
true
|
||||
],
|
||||
// expect same major number match
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
true
|
||||
],
|
||||
// expect same major number match
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'requiremax' => '5',
|
||||
],
|
||||
true
|
||||
],
|
||||
// dependencies versions before require*
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '7.0',
|
||||
'max-version' => '7.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
false
|
||||
],
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '5.0',
|
||||
'max-version' => '5.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
false
|
||||
],
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '5.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '5.0',
|
||||
'max-version' => '7.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
[
|
||||
'9.2.0.0',
|
||||
[
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.0',
|
||||
'max-version' => '9.1',
|
||||
],
|
||||
],
|
||||
'nextcloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.1',
|
||||
'max-version' => '9.2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
[
|
||||
'9.2.0.0',
|
||||
[
|
||||
'dependencies' => [
|
||||
'nextcloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.1',
|
||||
'max-version' => '9.2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('appVersionsProvider')]
|
||||
public function testServerVersion($ncVersion, $appInfo, $expectedResult): void {
|
||||
$this->assertEquals($expectedResult, count($this->analyser->analyzeServerVersion($ncVersion, $appInfo, false)) === 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
namespace Test;
|
||||
|
||||
use OC\App\AppManager;
|
||||
use OC\App\DependencyAnalyzer;
|
||||
use OC\AppConfig;
|
||||
use OC\Config\ConfigManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
|
@ -36,288 +37,6 @@ class AppTest extends \Test\TestCase {
|
|||
public const TEST_GROUP1 = 'group1';
|
||||
public const TEST_GROUP2 = 'group2';
|
||||
|
||||
public static function appVersionsProvider(): array {
|
||||
return [
|
||||
// exact match
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// in-between match
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// app too old
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '5.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// app too new
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only min specified
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only min specified fail
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremin' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only min specified legacy
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'require' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only min specified legacy fail
|
||||
[
|
||||
'4.0.0.0',
|
||||
[
|
||||
'require' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// only max specified
|
||||
[
|
||||
'5.0.0.0',
|
||||
[
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// only max specified fail
|
||||
[
|
||||
'7.0.0.0',
|
||||
[
|
||||
'requiremax' => '6.0',
|
||||
],
|
||||
false
|
||||
],
|
||||
// variations of versions
|
||||
// single OC number
|
||||
[
|
||||
'4',
|
||||
[
|
||||
'require' => '4.0',
|
||||
],
|
||||
true
|
||||
],
|
||||
// multiple OC number
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.3',
|
||||
],
|
||||
true
|
||||
],
|
||||
// single app number
|
||||
[
|
||||
'4',
|
||||
[
|
||||
'require' => '4',
|
||||
],
|
||||
true
|
||||
],
|
||||
// single app number fail
|
||||
[
|
||||
'4.3',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
false
|
||||
],
|
||||
// complex
|
||||
[
|
||||
'5.0.0',
|
||||
[
|
||||
'require' => '4.5.1',
|
||||
],
|
||||
true
|
||||
],
|
||||
// complex fail
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.3.2',
|
||||
],
|
||||
false
|
||||
],
|
||||
// two numbers
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '4.4',
|
||||
],
|
||||
false
|
||||
],
|
||||
// one number fail
|
||||
[
|
||||
'4.3.1',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
false
|
||||
],
|
||||
// pre-alpha app
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'require' => '4.93',
|
||||
],
|
||||
true
|
||||
],
|
||||
// pre-alpha OC
|
||||
[
|
||||
'6.90.0.2',
|
||||
[
|
||||
'require' => '6.90',
|
||||
],
|
||||
true
|
||||
],
|
||||
// pre-alpha OC max
|
||||
[
|
||||
'6.90.0.2',
|
||||
[
|
||||
'requiremax' => '7',
|
||||
],
|
||||
true
|
||||
],
|
||||
// expect same major number match
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'require' => '5',
|
||||
],
|
||||
true
|
||||
],
|
||||
// expect same major number match
|
||||
[
|
||||
'5.0.3',
|
||||
[
|
||||
'requiremax' => '5',
|
||||
],
|
||||
true
|
||||
],
|
||||
// dependencies versions before require*
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '7.0',
|
||||
'max-version' => '7.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
false
|
||||
],
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '7.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '5.0',
|
||||
'max-version' => '5.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
false
|
||||
],
|
||||
[
|
||||
'6.0.0.0',
|
||||
[
|
||||
'requiremin' => '5.0',
|
||||
'requiremax' => '5.0',
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '5.0',
|
||||
'max-version' => '7.0',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
[
|
||||
'9.2.0.0',
|
||||
[
|
||||
'dependencies' => [
|
||||
'owncloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.0',
|
||||
'max-version' => '9.1',
|
||||
],
|
||||
],
|
||||
'nextcloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.1',
|
||||
'max-version' => '9.2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
[
|
||||
'9.2.0.0',
|
||||
[
|
||||
'dependencies' => [
|
||||
'nextcloud' => [
|
||||
'@attributes' => [
|
||||
'min-version' => '9.1',
|
||||
'max-version' => '9.2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
true
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('appVersionsProvider')]
|
||||
public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult): void {
|
||||
$this->assertEquals($expectedResult, \OC_App::isAppCompatible($ocVersion, $appInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the app order is correct
|
||||
*/
|
||||
|
|
@ -572,6 +291,7 @@ class AppTest extends \Test\TestCase {
|
|||
Server::get(LoggerInterface::class),
|
||||
Server::get(ServerVersion::class),
|
||||
Server::get(ConfigManager::class),
|
||||
Server::get(DependencyAnalyzer::class),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use OC\DB\Connection;
|
|||
use OC\DB\MigrationService;
|
||||
use OC\DB\SchemaWrapper;
|
||||
use OC\Migration\MetadataManager;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\Attributes\AddColumn;
|
||||
|
|
@ -81,10 +82,10 @@ class MigrationsTest extends \Test\TestCase {
|
|||
|
||||
|
||||
public function testUnknownApp(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('App not found');
|
||||
$this->expectException(AppPathNotFoundException::class);
|
||||
$this->expectExceptionMessage('Could not find path for unknown_bloody_app');
|
||||
|
||||
$migrationService = new MigrationService('unknown-bloody-app', $this->db);
|
||||
$migrationService = new MigrationService('unknown_bloody_app', $this->db);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ use OCP\Http\Client\IClient;
|
|||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IConfig;
|
||||
use OCP\ITempManager;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Server;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -38,6 +40,8 @@ class InstallerTest extends TestCase {
|
|||
private $logger;
|
||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $config;
|
||||
private IAppManager&MockObject $appManager;
|
||||
private IFactory&MockObject $l10nFactory;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -47,18 +51,13 @@ class InstallerTest extends TestCase {
|
|||
$this->tempManager = $this->createMock(ITempManager::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
$this->l10nFactory = $this->createMock(IFactory::class);
|
||||
|
||||
$config = Server::get(IConfig::class);
|
||||
$this->appstore = $config->setSystemValue('appstoreenabled', true);
|
||||
$config->setSystemValue('appstoreenabled', true);
|
||||
$installer = new Installer(
|
||||
Server::get(AppFetcher::class),
|
||||
Server::get(IClientService::class),
|
||||
Server::get(ITempManager::class),
|
||||
Server::get(LoggerInterface::class),
|
||||
$config,
|
||||
false
|
||||
);
|
||||
$installer = Server::get(Installer::class);
|
||||
$installer->removeApp(self::$appid);
|
||||
}
|
||||
|
||||
|
|
@ -69,19 +68,14 @@ class InstallerTest extends TestCase {
|
|||
$this->tempManager,
|
||||
$this->logger,
|
||||
$this->config,
|
||||
$this->appManager,
|
||||
$this->l10nFactory,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
$installer = new Installer(
|
||||
Server::get(AppFetcher::class),
|
||||
Server::get(IClientService::class),
|
||||
Server::get(ITempManager::class),
|
||||
Server::get(LoggerInterface::class),
|
||||
Server::get(IConfig::class),
|
||||
false
|
||||
);
|
||||
$installer = Server::get(Installer::class);
|
||||
$installer->removeApp(self::$appid);
|
||||
Server::get(IConfig::class)->setSystemValue('appstoreenabled', $this->appstore);
|
||||
|
||||
|
|
@ -93,14 +87,7 @@ class InstallerTest extends TestCase {
|
|||
Server::get(IAppManager::class)->getAppVersion('testapp', true);
|
||||
|
||||
// Build installer
|
||||
$installer = new Installer(
|
||||
Server::get(AppFetcher::class),
|
||||
Server::get(IClientService::class),
|
||||
Server::get(ITempManager::class),
|
||||
Server::get(LoggerInterface::class),
|
||||
Server::get(IConfig::class),
|
||||
false
|
||||
);
|
||||
$installer = Server::get(Installer::class);
|
||||
|
||||
// Extract app
|
||||
$pathOfTestApp = __DIR__ . '/../data/testapp.zip';
|
||||
|
|
@ -158,6 +145,10 @@ class InstallerTest extends TestCase {
|
|||
->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn($appArray);
|
||||
$this->appManager
|
||||
->expects($this->exactly(2))
|
||||
->method('getAppVersion')
|
||||
->willReturn('1.0');
|
||||
|
||||
$installer = $this->getInstaller();
|
||||
$this->assertSame($updateAvailable, $installer->isUpdateAvailable('files'));
|
||||
|
|
@ -700,6 +691,11 @@ JXhrdaWDZ8fzpUjugrtC3qslsqL0dzgU37anS3HwrT8=',
|
|||
$this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml'));
|
||||
$this->assertEquals('0.9', \OC_App::getAppVersionByPath(__DIR__ . '/../../apps/testapp/'));
|
||||
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppVersion')
|
||||
->willReturn('0.9');
|
||||
|
||||
$installer = $this->getInstaller();
|
||||
$installer->downloadApp('testapp');
|
||||
$this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml'));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ namespace Test\IntegrityCheck;
|
|||
use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder;
|
||||
use OC\Files\Type\Detection;
|
||||
use OC\IntegrityCheck\Checker;
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
||||
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
||||
use OC\Memcache\NullCache;
|
||||
|
|
@ -29,10 +28,6 @@ class CheckerTest extends TestCase {
|
|||
private $serverVersion;
|
||||
/** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $environmentHelper;
|
||||
/** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $appLocator;
|
||||
/** @var Checker */
|
||||
private $checker;
|
||||
/** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $fileAccessHelper;
|
||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
|
||||
|
|
@ -46,12 +41,13 @@ class CheckerTest extends TestCase {
|
|||
/** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $mimeTypeDetector;
|
||||
|
||||
private Checker $checker;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->serverVersion = $this->createMock(ServerVersion::class);
|
||||
$this->environmentHelper = $this->createMock(EnvironmentHelper::class);
|
||||
$this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
|
||||
$this->appLocator = $this->createMock(AppLocator::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
||||
|
|
@ -71,7 +67,6 @@ class CheckerTest extends TestCase {
|
|||
$this->serverVersion,
|
||||
$this->environmentHelper,
|
||||
$this->fileAccessHelper,
|
||||
$this->appLocator,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->cacheFactory,
|
||||
|
|
@ -186,7 +181,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp')
|
||||
|
|
@ -221,7 +216,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp')
|
||||
|
|
@ -262,7 +257,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp')
|
||||
|
|
@ -319,7 +314,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->never())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp');
|
||||
|
|
@ -374,7 +369,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp')
|
||||
|
|
@ -415,7 +410,7 @@ class CheckerTest extends TestCase {
|
|||
->with('integrity.check.disabled', false)
|
||||
->willReturn(false);
|
||||
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->once())
|
||||
->method('getAppPath')
|
||||
->with('SomeApp')
|
||||
|
|
@ -984,7 +979,6 @@ class CheckerTest extends TestCase {
|
|||
$this->serverVersion,
|
||||
$this->environmentHelper,
|
||||
$this->fileAccessHelper,
|
||||
$this->appLocator,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->cacheFactory,
|
||||
|
|
@ -1032,7 +1026,7 @@ class CheckerTest extends TestCase {
|
|||
$this->assertSame($expected, $app);
|
||||
return [];
|
||||
});
|
||||
$this->appLocator
|
||||
$this->appManager
|
||||
->expects($this->exactly(2))
|
||||
->method('getAppPath')
|
||||
->willReturnMap([
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace Test\IntegrityCheck\Helpers;
|
||||
|
||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||
use Test\TestCase;
|
||||
|
||||
class AppLocatorTest extends TestCase {
|
||||
/** @var AppLocator */
|
||||
private $locator;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->locator = new AppLocator();
|
||||
}
|
||||
|
||||
public function testGetAppPath(): void {
|
||||
$this->assertSame(\OC_App::getAppPath('files'), $this->locator->getAppPath('files'));
|
||||
}
|
||||
|
||||
|
||||
public function testGetAppPathNotExistentApp(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('App not found');
|
||||
|
||||
$this->locator->getAppPath('aTotallyNotExistingApp');
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ class CSSResourceLocatorTest extends \Test\TestCase {
|
|||
symlink($apps_dirname, $new_apps_path_symlink);
|
||||
|
||||
// Create an app within that path
|
||||
mkdir($new_apps_path . '/' . 'test-css-app');
|
||||
mkdir($new_apps_path . '/' . 'test_css_app');
|
||||
|
||||
// Use the symlink as the app path
|
||||
\OC::$APPSROOTS[] = [
|
||||
|
|
@ -97,7 +97,7 @@ class CSSResourceLocatorTest extends \Test\TestCase {
|
|||
];
|
||||
|
||||
$locator = $this->cssResourceLocator();
|
||||
$locator->find(['test-css-app/test-file']);
|
||||
$locator->find(['test_css_app/test-file']);
|
||||
|
||||
$resources = $locator->getResources();
|
||||
$this->assertCount(1, $resources);
|
||||
|
|
@ -107,8 +107,8 @@ class CSSResourceLocatorTest extends \Test\TestCase {
|
|||
$webRoot = $resource[1];
|
||||
$file = $resource[2];
|
||||
|
||||
$expectedRoot = $new_apps_path . '/test-css-app';
|
||||
$expectedWebRoot = \OC::$WEBROOT . '/css-apps-test/test-css-app';
|
||||
$expectedRoot = $new_apps_path . '/test_css_app';
|
||||
$expectedWebRoot = \OC::$WEBROOT . '/css-apps-test/test_css_app';
|
||||
$expectedFile = 'test-file.css';
|
||||
|
||||
$this->assertEquals($expectedRoot, $root,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Test;
|
|||
use OC\Installer;
|
||||
use OC\IntegrityCheck\Checker;
|
||||
use OC\Updater;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\ServerVersion;
|
||||
|
|
@ -32,6 +33,7 @@ class UpdaterTest extends TestCase {
|
|||
private $checker;
|
||||
/** @var Installer|MockObject */
|
||||
private $installer;
|
||||
private IAppManager&MockObject $appManager;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -41,6 +43,7 @@ class UpdaterTest extends TestCase {
|
|||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->checker = $this->createMock(Checker::class);
|
||||
$this->installer = $this->createMock(Installer::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
|
||||
$this->updater = new Updater(
|
||||
$this->serverVersion,
|
||||
|
|
@ -48,7 +51,8 @@ class UpdaterTest extends TestCase {
|
|||
$this->appConfig,
|
||||
$this->checker,
|
||||
$this->logger,
|
||||
$this->installer
|
||||
$this->installer,
|
||||
$this->appManager,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue