chore: Get rid of AppLocator helper

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
pull/53895/head
Côme Chilliet 2025-07-31 15:14:48 +07:00
parent 3cea218750
commit b7c15949ce
No known key found for this signature in database
GPG Key ID: A3E2F658B28C760A
10 changed files with 41 additions and 106 deletions

@ -5,11 +5,11 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
namespace OC\Core\Command\Integrity; namespace OC\Core\Command\Integrity;
use OC\Core\Command\Base; use OC\Core\Command\Base;
use OC\IntegrityCheck\Checker; use OC\IntegrityCheck\Checker;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\FileAccessHelper; use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
@ -25,7 +25,6 @@ use Symfony\Component\Console\Output\OutputInterface;
class CheckApp extends Base { class CheckApp extends Base {
public function __construct( public function __construct(
private Checker $checker, private Checker $checker,
private AppLocator $appLocator,
private FileAccessHelper $fileAccessHelper, private FileAccessHelper $fileAccessHelper,
private IAppManager $appManager, private IAppManager $appManager,
) { ) {
@ -70,7 +69,7 @@ class CheckApp extends Base {
foreach ($appIds as $appId) { foreach ($appIds as $appId) {
$path = (string)$input->getOption('path'); $path = (string)$input->getOption('path');
if ($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')) { if ($this->appManager->isShipped($appId) || $this->fileAccessHelper->file_exists($path . '/appinfo/signature.json')) {

@ -252,9 +252,14 @@ class AppManager implements IAppManager {
foreach ($apps as $app) { foreach ($apps as $app) {
// If the app is already loaded then autoloading it makes no sense // If the app is already loaded then autoloading it makes no sense
if (!$this->isAppLoaded($app)) { if (!$this->isAppLoaded($app)) {
$path = \OC_App::getAppPath($app); try {
if ($path !== false) { $path = $this->getAppPath($app);
\OC_App::registerAutoloading($app, $path); \OC_App::registerAutoloading($app, $path);
} catch (AppPathNotFoundException $e) {
$this->logger->info('Error during app loading: ' . $e->getMessage(), [
'exception' => $e,
'app' => $app,
]);
} }
} }
} }
@ -450,8 +455,13 @@ class AppManager implements IAppManager {
return; return;
} }
$this->loadedApps[$app] = true; $this->loadedApps[$app] = true;
$appPath = \OC_App::getAppPath($app); try {
if ($appPath === false) { $appPath = $this->getAppPath($app);
} catch (AppPathNotFoundException $e) {
$this->logger->info('Error during app loading: ' . $e->getMessage(), [
'exception' => $e,
'app' => $app,
]);
return; return;
} }
$eventLogger = \OC::$server->get(IEventLogger::class); $eventLogger = \OC::$server->get(IEventLogger::class);

@ -13,8 +13,8 @@ use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Sequence; use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use OC\App\InfoParser; use OC\App\InfoParser;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\Migration\SimpleOutput; use OC\Migration\SimpleOutput;
use OCP\App\IAppManager;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\AppFramework\QueryException; use OCP\AppFramework\QueryException;
use OCP\DB\ISchemaWrapper; use OCP\DB\ISchemaWrapper;
@ -39,7 +39,12 @@ class MigrationService {
/** /**
* @throws \Exception * @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->appName = $appName;
$this->connection = $connection; $this->connection = $connection;
if ($logger === null) { if ($logger === null) {
@ -58,10 +63,8 @@ class MigrationService {
$this->migrationsNamespace = 'OC\\Core\\Migrations'; $this->migrationsNamespace = 'OC\\Core\\Migrations';
$this->checkOracle = true; $this->checkOracle = true;
} else { } else {
if ($appLocator === null) { $appManager = Server::get(IAppManager::class);
$appLocator = new AppLocator(); $appPath = $appManager->getAppPath($appName);
}
$appPath = $appLocator->getAppPath($appName);
$namespace = App::buildAppNamespace($appName); $namespace = App::buildAppNamespace($appName);
$this->migrationsPath = "$appPath/lib/Migration"; $this->migrationsPath = "$appPath/lib/Migration";
$this->migrationsNamespace = $namespace . '\\Migration'; $this->migrationsNamespace = $namespace . '\\Migration';
@ -728,7 +731,7 @@ class MigrationService {
} }
} }
private function ensureMigrationsAreLoaded() { private function ensureMigrationsAreLoaded(): void {
if (empty($this->migrations)) { if (empty($this->migrations)) {
$this->migrations = $this->findMigrations(); $this->migrations = $this->findMigrations();
} }

@ -18,7 +18,6 @@ use OC\Archive\TAR;
use OC\DB\Connection; use OC\DB\Connection;
use OC\DB\MigrationService; use OC\DB\MigrationService;
use OC\Files\FilenameValidator; use OC\Files\FilenameValidator;
use OC_App;
use OCP\App\AppPathNotFoundException; use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\IJobList;

@ -10,7 +10,6 @@ namespace OC\IntegrityCheck;
use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder; use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder;
use OC\IntegrityCheck\Exceptions\InvalidSignatureException; use OC\IntegrityCheck\Exceptions\InvalidSignatureException;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper; use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper; use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\IntegrityCheck\Iterator\ExcludeFileByNameFilterIterator; use OC\IntegrityCheck\Iterator\ExcludeFileByNameFilterIterator;
@ -44,7 +43,6 @@ class Checker {
private ServerVersion $serverVersion, private ServerVersion $serverVersion,
private EnvironmentHelper $environmentHelper, private EnvironmentHelper $environmentHelper,
private FileAccessHelper $fileAccessHelper, private FileAccessHelper $fileAccessHelper,
private AppLocator $appLocator,
private ?IConfig $config, private ?IConfig $config,
private ?IAppConfig $appConfig, private ?IAppConfig $appConfig,
ICacheFactory $cacheFactory, ICacheFactory $cacheFactory,
@ -460,7 +458,7 @@ class Checker {
public function verifyAppSignature(string $appId, string $path = '', bool $forceVerify = false): array { public function verifyAppSignature(string $appId, string $path = '', bool $forceVerify = false): array {
try { try {
if ($path === '') { if ($path === '') {
$path = $this->appLocator->getAppPath($appId); $path = $this->appManager->getAppPath($appId);
} }
$result = $this->verify( $result = $this->verify(
$path . '/appinfo/signature.json', $path . '/appinfo/signature.json',
@ -545,7 +543,7 @@ class Checker {
$appNeedsToBeChecked = false; $appNeedsToBeChecked = false;
if ($isShipped) { if ($isShipped) {
$appNeedsToBeChecked = true; $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 // Otherwise only if the application explicitly ships a signature.json file
$appNeedsToBeChecked = true; $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;
}
}

@ -65,7 +65,6 @@ use OC\FullTextSearch\FullTextSearchManager;
use OC\Http\Client\ClientService; use OC\Http\Client\ClientService;
use OC\Http\Client\NegativeDnsCache; use OC\Http\Client\NegativeDnsCache;
use OC\IntegrityCheck\Checker; use OC\IntegrityCheck\Checker;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper; use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper; use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\KnownUser\KnownUserService; use OC\KnownUser\KnownUserService;
@ -839,7 +838,6 @@ class Server extends ServerContainer implements IServerContainer {
$c->get(ServerVersion::class), $c->get(ServerVersion::class),
$c->get(EnvironmentHelper::class), $c->get(EnvironmentHelper::class),
new FileAccessHelper(), new FileAccessHelper(),
new AppLocator(),
$config, $config,
$appConfig, $appConfig,
$c->get(ICacheFactory::class), $c->get(ICacheFactory::class),

@ -20,6 +20,7 @@ use OC\DB\Connection;
use OC\DB\MigrationService; use OC\DB\MigrationService;
use OC\DB\SchemaWrapper; use OC\DB\SchemaWrapper;
use OC\Migration\MetadataManager; use OC\Migration\MetadataManager;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\Migration\Attributes\AddColumn; use OCP\Migration\Attributes\AddColumn;
@ -81,10 +82,10 @@ class MigrationsTest extends \Test\TestCase {
public function testUnknownApp(): void { public function testUnknownApp(): void {
$this->expectException(\Exception::class); $this->expectException(AppPathNotFoundException::class);
$this->expectExceptionMessage('App not found'); $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);
} }

@ -11,7 +11,6 @@ namespace Test\IntegrityCheck;
use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder; use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder;
use OC\Files\Type\Detection; use OC\Files\Type\Detection;
use OC\IntegrityCheck\Checker; use OC\IntegrityCheck\Checker;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper; use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper; use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\Memcache\NullCache; use OC\Memcache\NullCache;
@ -29,10 +28,6 @@ class CheckerTest extends TestCase {
private $serverVersion; private $serverVersion;
/** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */ /** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */
private $environmentHelper; private $environmentHelper;
/** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */
private $appLocator;
/** @var Checker */
private $checker;
/** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */ /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
private $fileAccessHelper; private $fileAccessHelper;
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
@ -46,12 +41,13 @@ class CheckerTest extends TestCase {
/** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */ /** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */
private $mimeTypeDetector; private $mimeTypeDetector;
private Checker $checker;
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
$this->serverVersion = $this->createMock(ServerVersion::class); $this->serverVersion = $this->createMock(ServerVersion::class);
$this->environmentHelper = $this->createMock(EnvironmentHelper::class); $this->environmentHelper = $this->createMock(EnvironmentHelper::class);
$this->fileAccessHelper = $this->createMock(FileAccessHelper::class); $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
$this->appLocator = $this->createMock(AppLocator::class);
$this->config = $this->createMock(IConfig::class); $this->config = $this->createMock(IConfig::class);
$this->appConfig = $this->createMock(IAppConfig::class); $this->appConfig = $this->createMock(IAppConfig::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class); $this->cacheFactory = $this->createMock(ICacheFactory::class);
@ -71,7 +67,6 @@ class CheckerTest extends TestCase {
$this->serverVersion, $this->serverVersion,
$this->environmentHelper, $this->environmentHelper,
$this->fileAccessHelper, $this->fileAccessHelper,
$this->appLocator,
$this->config, $this->config,
$this->appConfig, $this->appConfig,
$this->cacheFactory, $this->cacheFactory,
@ -186,7 +181,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->once()) ->expects($this->once())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp') ->with('SomeApp')
@ -221,7 +216,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->once()) ->expects($this->once())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp') ->with('SomeApp')
@ -262,7 +257,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->once()) ->expects($this->once())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp') ->with('SomeApp')
@ -319,7 +314,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->never()) ->expects($this->never())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp'); ->with('SomeApp');
@ -374,7 +369,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->once()) ->expects($this->once())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp') ->with('SomeApp')
@ -415,7 +410,7 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false) ->with('integrity.check.disabled', false)
->willReturn(false); ->willReturn(false);
$this->appLocator $this->appManager
->expects($this->once()) ->expects($this->once())
->method('getAppPath') ->method('getAppPath')
->with('SomeApp') ->with('SomeApp')
@ -984,7 +979,6 @@ class CheckerTest extends TestCase {
$this->serverVersion, $this->serverVersion,
$this->environmentHelper, $this->environmentHelper,
$this->fileAccessHelper, $this->fileAccessHelper,
$this->appLocator,
$this->config, $this->config,
$this->appConfig, $this->appConfig,
$this->cacheFactory, $this->cacheFactory,
@ -1032,7 +1026,7 @@ class CheckerTest extends TestCase {
$this->assertSame($expected, $app); $this->assertSame($expected, $app);
return []; return [];
}); });
$this->appLocator $this->appManager
->expects($this->exactly(2)) ->expects($this->exactly(2))
->method('getAppPath') ->method('getAppPath')
->willReturnMap([ ->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');
}
}