diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php
index a85ee8cc20a..bd713cab201 100644
--- a/apps/settings/lib/Controller/AppSettingsController.php
+++ b/apps/settings/lib/Controller/AppSettingsController.php
@@ -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) {
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 61d68578781..fd9c1b31a31 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -3317,14 +3317,6 @@
-
-
-
-
-
-
-
-
@@ -4011,12 +4003,6 @@
-
-
-
-
-
-
getDN(X509::DN_OPENSSL)['CN']]]>
diff --git a/core/Command/Integrity/CheckApp.php b/core/Command/Integrity/CheckApp.php
index 0145a3f8070..df9e9973aa7 100644
--- a/core/Command/Integrity/CheckApp.php
+++ b/core/Command/Integrity/CheckApp.php
@@ -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')) {
diff --git a/core/ajax/update.php b/core/ajax/update.php
index 69665cf62df..22bbdcff3e0 100644
--- a/core/ajax/update.php
+++ b/core/ajax/update.php
@@ -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', []);
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index e975adac6ef..84f75545b25 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -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',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index b6bd20b84fa..d533a3bcf1c 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.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',
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 7778393b3b3..b9883d01dbd 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.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;
+ }
}
diff --git a/lib/private/App/DependencyAnalyzer.php b/lib/private/App/DependencyAnalyzer.php
index bde8719c41d..374fe4cd272 100644
--- a/lib/private/App/DependencyAnalyzer.php
+++ b/lib/private/App/DependencyAnalyzer.php
@@ -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;
}
diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php
index 40579c7a898..e1723ff09a9 100644
--- a/lib/private/DB/MigrationService.php
+++ b/lib/private/DB/MigrationService.php
@@ -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();
}
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index fd737d286ad..e40e77c8b50 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -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;
diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php
index 2bd6e426b79..e98f77acaa0 100644
--- a/lib/private/IntegrityCheck/Checker.php
+++ b/lib/private/IntegrityCheck/Checker.php
@@ -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;
}
diff --git a/lib/private/IntegrityCheck/Helpers/AppLocator.php b/lib/private/IntegrityCheck/Helpers/AppLocator.php
deleted file mode 100644
index 148a3aeda76..00000000000
--- a/lib/private/IntegrityCheck/Helpers/AppLocator.php
+++ /dev/null
@@ -1,33 +0,0 @@
-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));
});
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 4082cd5df50..15f0a4eb617 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -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
diff --git a/lib/private/Updater.php b/lib/private/Updater.php
index 9cd33863612..da7b52e5493 100644
--- a/lib/private/Updater.php
+++ b/lib/private/Updater.php
@@ -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) {
diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php
index 6dbef42594b..c97c4f3d81e 100644
--- a/lib/private/legacy/OC_App.php
+++ b/lib/private/legacy/OC_App.php
@@ -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);
diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php
index 20019ce1ffd..97acd9af7b1 100644
--- a/lib/public/App/IAppManager.php
+++ b/lib/public/App/IAppManager.php
@@ -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;
}
diff --git a/tests/data/app/expected-info.json b/tests/data/app/expected-info.json
index 40ba6104104..9c5ce230cad 100644
--- a/tests/data/app/expected-info.json
+++ b/tests/data/app/expected-info.json
@@ -16,7 +16,6 @@
"admin": "admin-encryption"
},
"types": ["filesystem"],
- "ocsid": "166047",
"dependencies": {
"php": {
"@attributes" : {
diff --git a/tests/data/app/invalid-info.xml b/tests/data/app/invalid-info.xml
index 1c39ae2d625..8a95669beb0 100644
--- a/tests/data/app/invalid-info.xml
+++ b/tests/data/app/invalid-info.xml
@@ -22,5 +22,4 @@
- 166047
diff --git a/tests/data/app/valid-info.xml b/tests/data/app/valid-info.xml
index d2569788399..811fa634264 100644
--- a/tests/data/app/valid-info.xml
+++ b/tests/data/app/valid-info.xml
@@ -22,7 +22,6 @@
- 166047
sqlite
diff --git a/tests/enable_all.php b/tests/enable_all.php
index 85e5f3b9247..e9aaf3299a5 100644
--- a/tests/enable_all.php
+++ b/tests/enable_all.php
@@ -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";
}
diff --git a/tests/lib/App/AppManagerTest.php b/tests/lib/App/AppManagerTest.php
index 9a4716aa8f1..dcaeef90ff5 100644
--- a/tests/lib/App/AppManagerTest.php
+++ b/tests/lib/App/AppManagerTest.php
@@ -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'),
);
}
-
}
diff --git a/tests/lib/App/DependencyAnalyzerTest.php b/tests/lib/App/DependencyAnalyzerTest.php
index 88cb6009cc0..9cdcb24b95f 100644
--- a/tests/lib/App/DependencyAnalyzerTest.php
+++ b/tests/lib/App/DependencyAnalyzerTest.php
@@ -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);
+ }
}
diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php
index c56e31aadf8..71186f5ffb0 100644
--- a/tests/lib/AppTest.php
+++ b/tests/lib/AppTest.php
@@ -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),
));
}
diff --git a/tests/lib/DB/MigrationsTest.php b/tests/lib/DB/MigrationsTest.php
index 2b39b26d852..2116678baa1 100644
--- a/tests/lib/DB/MigrationsTest.php
+++ b/tests/lib/DB/MigrationsTest.php
@@ -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);
}
diff --git a/tests/lib/InstallerTest.php b/tests/lib/InstallerTest.php
index 06163cdaedb..e763807be29 100644
--- a/tests/lib/InstallerTest.php
+++ b/tests/lib/InstallerTest.php
@@ -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'));
diff --git a/tests/lib/IntegrityCheck/CheckerTest.php b/tests/lib/IntegrityCheck/CheckerTest.php
index a8a2596a3d8..823258cab10 100644
--- a/tests/lib/IntegrityCheck/CheckerTest.php
+++ b/tests/lib/IntegrityCheck/CheckerTest.php
@@ -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([
diff --git a/tests/lib/IntegrityCheck/Helpers/AppLocatorTest.php b/tests/lib/IntegrityCheck/Helpers/AppLocatorTest.php
deleted file mode 100644
index 837b397ac1f..00000000000
--- a/tests/lib/IntegrityCheck/Helpers/AppLocatorTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-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');
- }
-}
diff --git a/tests/lib/Template/CSSResourceLocatorTest.php b/tests/lib/Template/CSSResourceLocatorTest.php
index 2ae37999b32..fc82c9c3e57 100644
--- a/tests/lib/Template/CSSResourceLocatorTest.php
+++ b/tests/lib/Template/CSSResourceLocatorTest.php
@@ -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,
diff --git a/tests/lib/UpdaterTest.php b/tests/lib/UpdaterTest.php
index 37a4a105628..23a4d5329c8 100644
--- a/tests/lib/UpdaterTest.php
+++ b/tests/lib/UpdaterTest.php
@@ -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,
);
}