Skip to content

refactor(appstore): split appstore from settings app#59997

Open
susnux wants to merge 5 commits intomasterfrom
chore/split-appstore
Open

refactor(appstore): split appstore from settings app#59997
susnux wants to merge 5 commits intomasterfrom
chore/split-appstore

Conversation

@susnux
Copy link
Copy Markdown
Contributor

@susnux susnux commented Apr 29, 2026

Summary

See #57290 for details.
This only contains the app split and the needed changes to make it work in a separate app.
Moreover this also applies strict rector rules, for this I needed to fix a bug where rector (and also for psalm strict) did not have access to OCP (lib/public) and thus did not knew about those classes / interfaces and produced wrong output.

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@susnux susnux added this to the Nextcloud 34 milestone Apr 29, 2026
@susnux susnux requested review from a team and provokateurin as code owners April 29, 2026 19:57
@susnux susnux added the 3. to review Waiting for reviews label Apr 29, 2026
@susnux susnux requested a review from a team as a code owner April 29, 2026 19:57
@susnux susnux added technical debt 🧱 🤔🚀 ♻️ refactor Refactor code (not a bug fix, not a feature just refactoring) labels Apr 29, 2026
@susnux susnux requested review from CarlSchwan, leftybournes, nfebe, salmart-dev, sorbaugh and szaimen and removed request for a team April 29, 2026 19:57
@susnux susnux force-pushed the chore/split-appstore branch from 40c4086 to 9749a51 Compare April 29, 2026 19:58
@susnux susnux requested review from artonge and skjnldsv and removed request for a team and sorbaugh April 29, 2026 19:58
susnux added 5 commits April 29, 2026 22:04
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
@susnux susnux force-pushed the chore/split-appstore branch from 9749a51 to 4be9862 Compare April 29, 2026 20:05
/**
* Get all available apps
*
* @return DataResponse<Http::STATUS_OK, list<array{id: string, name: string, description: string, ...}>, array{}>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if this could contain all fields (and would use a type alias).

Comment on lines +273 to +274
#[ApiRoute(verb: 'POST', url: '/api/v1/apps/force')]
public function force(string $appId): DataResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[ApiRoute(verb: 'POST', url: '/api/v1/apps/force')]
public function force(string $appId): DataResponse {
#[ApiRoute(verb: 'POST', url: '/api/v1/apps/enable/force')]
public function forceEnable(string $appId): DataResponse {

Or just merge it with the normal enable endpoint and add a boolean parameter.

Comment on lines +34 to +35
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
class DiscoverController extends Controller {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be an OCSController and not be ignored. Maybe clients want to use this API in the future too?

*/
#[NoCSRFRequired]
#[FrontpageRoute(verb: 'GET', url: '/api/v1/discover/media')]
public function getAppDiscoverMedia(string $fileName, ILimiter $limiter, IUserSession $session): FileDisplayResponse|NotFoundResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function getAppDiscoverMedia(string $fileName, ILimiter $limiter, IUserSession $session): FileDisplayResponse|NotFoundResponse {
public function getAppDiscoverMedia(string $fileName, ILimiter $limiter): FileDisplayResponse|NotFoundResponse {

Does this even work? It should be injected through the constructor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does you can inject things in controller methods (its a thing we advertise to do)¹.

The use case is that controllers are always constructed, so e.g. userId must be string | null but if you inject in the methods then you can also inject $userId as string if the method was not flagged as PublicPage.
And also you do not need to inject things you only need in one method.

¹ See also https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#controller-injection

Comment thread apps/appstore/lib/Controller/PageController.php
Comment on lines 87 to +88
$apps = $appClass->listAllApps();
/** @var array{id: string, ...} $app */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type of listAllApps should be fixed instead.


private function getBundles() {
/**
* @return array{name: mixed, id: mixed, appIdentifiers: mixed}[]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type should be more concrete than mixed.

Comment thread psalm-strict.xml
Comment thread psalm-strict.xml
@@ -32,17 +32,26 @@
<file name="lib/public/DB/QueryBuilder/ITypedQueryBuilder.php"/>
<file name="lib/private/Share20/ShareHelper.php"/>
<file name="lib/public/Share/IShareHelper.php"/>
<directory name="apps/appstore/lib" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<directory name="apps/appstore/lib" />
<directory name="apps/appstore" />

Comment thread psalm-strict.xml
Comment on lines +37 to +47
<!-- Missing types of the AppFetcher and the OC_Apps class for return types -->
<file name="apps/appstore/lib/Controller/ApiController.php" />
<!-- ... -->
<directory name="apps/**/composer"/>
<directory name="apps/**/tests"/>
<directory name="lib/private"/>
<directory name="lib/public"/>
<directory name="lib/composer"/>
<directory name="lib/l10n"/>
<directory name="3rdparty"/>
<directory name="build"/>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this should not be necessary 🤔

For Unified Sharing I have a whole new app and parts of lib/public and lib/private in this config and there is no issue with that.

@susnux susnux mentioned this pull request Apr 30, 2026
7 tasks
Copy link
Copy Markdown
Collaborator

@artonge artonge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much more manageable, thanks for splitting :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews ♻️ refactor Refactor code (not a bug fix, not a feature just refactoring) technical debt 🧱 🤔🚀

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants