summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/admin_audit/appinfo/info.xml16
-rw-r--r--apps/comments/appinfo/info.xml17
-rw-r--r--apps/dav/appinfo/info.xml37
-rw-r--r--apps/encryption/appinfo/info.xml40
-rw-r--r--apps/federatedfilesharing/appinfo/info.xml14
-rw-r--r--apps/federation/appinfo/info.xml27
-rw-r--r--apps/files/appinfo/info.xml50
-rw-r--r--apps/files_external/appinfo/info.xml35
-rw-r--r--apps/files_sharing/appinfo/info.xml52
-rw-r--r--apps/files_trashbin/appinfo/info.xml18
-rw-r--r--apps/files_versions/appinfo/info.xml26
-rw-r--r--apps/lookup_server_connector/appinfo/info.xml18
-rw-r--r--apps/oauth2/appinfo/info.xml9
-rw-r--r--apps/provisioning_api/appinfo/info.xml20
-rw-r--r--apps/sharebymail/appinfo/info.xml51
-rw-r--r--apps/systemtags/appinfo/info.xml19
-rw-r--r--apps/testing/appinfo/info.xml18
-rw-r--r--apps/theming/appinfo/info.xml20
-rw-r--r--apps/twofactor_backupcodes/appinfo/info.xml23
-rw-r--r--apps/updatenotification/appinfo/info.xml10
-rw-r--r--apps/user_ldap/appinfo/info.xml23
-rw-r--r--apps/workflowengine/appinfo/info.xml20
-rw-r--r--core/Command/App/CheckCode.php53
-rw-r--r--core/register_command.php3
-rw-r--r--lib/private/App/AppManager.php5
-rw-r--r--lib/private/App/CodeChecker/InfoChecker.php149
-rw-r--r--resources/app-info-shipped.xsd671
-rw-r--r--resources/app-info.xsd652
-rw-r--r--tests/apps/testapp-dependency-missing/appinfo/info.xml9
-rw-r--r--tests/apps/testapp-infoxml/appinfo/info.xml12
-rw-r--r--tests/apps/testapp-name-missing/appinfo/info.xml11
-rw-r--r--tests/apps/testapp-version/appinfo/info.xml11
-rw-r--r--tests/apps/testapp-version/appinfo/version1
-rw-r--r--tests/apps/testapp_dependency_missing/appinfo/info.xml13
-rw-r--r--tests/apps/testapp_infoxml/appinfo/info.xml16
-rw-r--r--tests/apps/testapp_name_missing/appinfo/info.xml15
-rw-r--r--tests/apps/testapp_version/appinfo/info.xml15
-rw-r--r--tests/lib/App/CodeChecker/InfoCheckerTest.php19
38 files changed, 1790 insertions, 428 deletions
diff --git a/apps/admin_audit/appinfo/info.xml b/apps/admin_audit/appinfo/info.xml
index 44abc85f105..054ed9580f2 100644
--- a/apps/admin_audit/appinfo/info.xml
+++ b/apps/admin_audit/appinfo/info.xml
@@ -1,16 +1,20 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>admin_audit</id>
<name>Auditing / Logging</name>
+ <summary>Provides logging abilities for Nextcloud such as logging file accesses or otherwise sensitive actions.</summary>
<description>Provides logging abilities for Nextcloud such as logging file accesses or otherwise sensitive actions.</description>
- <licence>AGPL</licence>
- <author>Nextcloud</author>
<version>1.4.0</version>
+ <licence>agpl</licence>
+ <author>Nextcloud</author>
<namespace>AdminAudit</namespace>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<types>
<logging/>
</types>
+ <category>monitoring</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
</info>
diff --git a/apps/comments/appinfo/info.xml b/apps/comments/appinfo/info.xml
index 61a23cf65f8..bc2cfe03054 100644
--- a/apps/comments/appinfo/info.xml
+++ b/apps/comments/appinfo/info.xml
@@ -1,19 +1,24 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>comments</id>
<name>Comments</name>
+ <summary>Files app plugin to add comments to files</summary>
<description>Files app plugin to add comments to files</description>
- <licence>AGPL</licence>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
<author>Arthur Schiwon</author>
<author>Vincent Petry</author>
<default_enable/>
- <version>1.4.0</version>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<types>
<logging/>
</types>
+ <category>office</category>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<activity>
<settings>
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index 7115cacfef2..3afef530e7a 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -1,22 +1,24 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>dav</id>
<name>WebDAV</name>
+ <summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
- <licence>AGPL</licence>
- <author>owncloud.org</author>
<version>1.5.0</version>
+ <licence>agpl</licence>
+ <author>owncloud.org</author>
+ <namespace>DAV</namespace>
<default_enable/>
<types>
<filesystem/>
</types>
- <namespace>DAV</namespace>
- <public>
- <webdav>appinfo/v1/publicwebdav.php</webdav>
- </public>
+ <category>integration</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
+
<repair-steps>
<post-migration>
<step>OCA\DAV\Migration\FixBirthdayCalendarComponent</step>
@@ -24,6 +26,7 @@
<step>OCA\DAV\Migration\BuildCalendarSearchIndex</step>
</post-migration>
</repair-steps>
+
<commands>
<command>OCA\DAV\Command\CreateAddressBook</command>
<command>OCA\DAV\Command\CreateCalendar</command>
@@ -31,18 +34,22 @@
<command>OCA\DAV\Command\SyncSystemAddressBook</command>
</commands>
- <activity>
- <filters>
- <filter>OCA\DAV\CalDAV\Activity\Filter\Calendar</filter>
- <filter>OCA\DAV\CalDAV\Activity\Filter\Todo</filter>
- </filters>
+ <settings>
+ <admin>OCA\DAV\Settings\CalDAVSettings</admin>
+ </settings>
+ <activity>
<settings>
<setting>OCA\DAV\CalDAV\Activity\Setting\Calendar</setting>
<setting>OCA\DAV\CalDAV\Activity\Setting\Event</setting>
<setting>OCA\DAV\CalDAV\Activity\Setting\Todo</setting>
</settings>
+ <filters>
+ <filter>OCA\DAV\CalDAV\Activity\Filter\Calendar</filter>
+ <filter>OCA\DAV\CalDAV\Activity\Filter\Todo</filter>
+ </filters>
+
<providers>
<provider>OCA\DAV\CalDAV\Activity\Provider\Calendar</provider>
<provider>OCA\DAV\CalDAV\Activity\Provider\Event</provider>
@@ -50,7 +57,7 @@
</providers>
</activity>
- <settings>
- <admin>OCA\DAV\Settings\CalDAVSettings</admin>
- </settings>
+ <public>
+ <webdav>appinfo/v1/publicwebdav.php</webdav>
+ </public>
</info>
diff --git a/apps/encryption/appinfo/info.xml b/apps/encryption/appinfo/info.xml
index 5744e5d2d66..2859043e72b 100644
--- a/apps/encryption/appinfo/info.xml
+++ b/apps/encryption/appinfo/info.xml
@@ -1,6 +1,9 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>encryption</id>
+ <name>Default encryption module</name>
+ <summary>Default encryption module for server-side encryption</summary>
<description>
In order to use this encryption module you need to enable server-side
encryption in the admin settings. Once enabled this module will encrypt
@@ -11,35 +14,40 @@
Please read the documentation to know all implications before you decide
to enable server-side encryption.
</description>
- <name>Default encryption module</name>
- <licence>AGPL</licence>
+ <version>2.1.0</version>
+ <licence>agpl</licence>
<author>Bjoern Schiessle</author>
<author>Clark Tomlinson</author>
+ <types>
+ <filesystem/>
+ </types>
<documentation>
<user>user-encryption</user>
<admin>admin-encryption</admin>
</documentation>
- <version>2.1.0</version>
- <types>
- <filesystem/>
- </types>
+ <category>files</category>
+ <category>security</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+
<dependencies>
<lib>openssl</lib>
<nextcloud min-version="14" max-version="14" />
</dependencies>
- <settings>
- <admin>OCA\Encryption\Settings\Admin</admin>
- <personal>OCA\Encryption\Settings\Personal</personal>
- </settings>
- <commands>
- <command>OCA\Encryption\Command\EnableMasterKey</command>
- <command>OCA\Encryption\Command\DisableMasterKey</command>
- <command>OCA\Encryption\Command\MigrateKeys</command>
- </commands>
<repair-steps>
<post-migration>
<step>OCA\Encryption\Migration\SetMasterKeyStatus</step>
</post-migration>
</repair-steps>
+
+ <commands>
+ <command>OCA\Encryption\Command\EnableMasterKey</command>
+ <command>OCA\Encryption\Command\DisableMasterKey</command>
+ <command>OCA\Encryption\Command\MigrateKeys</command>
+ </commands>
+
+ <settings>
+ <admin>OCA\Encryption\Settings\Admin</admin>
+ <personal>OCA\Encryption\Settings\Personal</personal>
+ </settings>
</info>
diff --git a/apps/federatedfilesharing/appinfo/info.xml b/apps/federatedfilesharing/appinfo/info.xml
index ac5e3f45e95..027e62ed183 100644
--- a/apps/federatedfilesharing/appinfo/info.xml
+++ b/apps/federatedfilesharing/appinfo/info.xml
@@ -1,17 +1,23 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>federatedfilesharing</id>
<name>Federated file sharing</name>
+ <summary>Provide federated file sharing across servers</summary>
<description>Provide federated file sharing across servers</description>
- <licence>AGPL</licence>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
<author>Bjoern Schiessle</author>
<author>Roeland Jago Douma</author>
- <version>1.4.0</version>
<namespace>FederatedFileSharing</namespace>
- <category>other</category>
+ <category>files</category>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
+
<settings>
<admin>OCA\FederatedFileSharing\Settings\Admin</admin>
<personal>OCA\FederatedFileSharing\Settings\Personal</personal>
diff --git a/apps/federation/appinfo/info.xml b/apps/federation/appinfo/info.xml
index c7fc2f2431a..e96c50479ae 100644
--- a/apps/federation/appinfo/info.xml
+++ b/apps/federation/appinfo/info.xml
@@ -1,30 +1,35 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>federation</id>
<name>Federation</name>
+ <summary>Federation allows you to connect with other trusted servers to exchange the user directory.</summary>
<description>Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing.</description>
- <licence>AGPL</licence>
- <author>Bjoern Schiessle</author>
<version>1.4.0</version>
+ <licence>agpl</licence>
+ <author>Bjoern Schiessle</author>
<namespace>Federation</namespace>
- <category>other</category>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<default_enable/>
+
<types>
<authentication/>
</types>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<background-jobs>
<job>OCA\Federation\SyncJob</job>
</background-jobs>
- <settings>
- <admin>OCA\Federation\Settings\Admin</admin>
- </settings>
-
<commands>
<command>OCA\Federation\Command\SyncFederationAddressBooks</command>
</commands>
+
+ <settings>
+ <admin>OCA\Federation\Settings\Admin</admin>
+ </settings>
</info>
diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml
index 1faf2c80adc..f5b43070cee 100644
--- a/apps/files/appinfo/info.xml
+++ b/apps/files/appinfo/info.xml
@@ -1,22 +1,43 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>files</id>
<name>Files</name>
+ <summary>File Management</summary>
<description>File Management</description>
- <licence>AGPL</licence>
+ <version>1.9.0</version>
+ <licence>agpl</licence>
<author>Robin Appelman</author>
<author>Vincent Petry</author>
<default_enable/>
- <version>1.9.0</version>
<types>
<filesystem/>
</types>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<documentation>
<user>user-files</user>
</documentation>
+ <category>files</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
+
+ <background-jobs>
+ <job>OCA\Files\BackgroundJob\ScanFiles</job>
+ <job>OCA\Files\BackgroundJob\DeleteOrphanedItems</job>
+ <job>OCA\Files\BackgroundJob\CleanupFileLocks</job>
+ </background-jobs>
+
+ <commands>
+ <command>OCA\Files\Command\Scan</command>
+ <command>OCA\Files\Command\DeleteOrphanedFiles</command>
+ <command>OCA\Files\Command\TransferOwnership</command>
+ <command>OCA\Files\Command\ScanAppData</command>
+ </commands>
+
+ <settings>
+ <admin>OCA\Files\Settings\Admin</admin>
+ </settings>
<activity>
<settings>
@@ -39,23 +60,6 @@
</providers>
</activity>
- <background-jobs>
- <job>OCA\Files\BackgroundJob\ScanFiles</job>
- <job>OCA\Files\BackgroundJob\DeleteOrphanedItems</job>
- <job>OCA\Files\BackgroundJob\CleanupFileLocks</job>
- </background-jobs>
-
- <settings>
- <admin>OCA\Files\Settings\Admin</admin>
- </settings>
-
- <commands>
- <command>OCA\Files\Command\Scan</command>
- <command>OCA\Files\Command\DeleteOrphanedFiles</command>
- <command>OCA\Files\Command\TransferOwnership</command>
- <command>OCA\Files\Command\ScanAppData</command>
- </commands>
-
<navigations>
<navigation>
<name>Files</name>
diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml
index a924c32ba25..795c63a60f0 100644
--- a/apps/files_external/appinfo/info.xml
+++ b/apps/files_external/appinfo/info.xml
@@ -1,38 +1,36 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>files_external</id>
<name>External storage support</name>
+ <summary>Adds basic external storage support</summary>
<description>
This application enables administrators to configure connections to external storage providers, such as FTP servers, S3 or SWIFT object stores, other Nextcloud servers, WebDAV servers, and more. Administrators can choose which types of storage to enable and can mount these storage locations for a user, a group, or the entire system. Users will see a new folder appear in their root Nextcloud directory, which they can access and use like any other Nextcloud folder. External storage also allows users to share files stored in these external locations. In these cases, the credentials for the owner of the file are used when the recipient requests the file from external storage, thereby ensuring that the recipient can access the shared file.
External storage can be configured using the GUI or at the command line. This second option provides the advanced user with more flexibility for configuring bulk external storage mounts and setting mount priorities. More information is available in the external storage GUI documentation and the external storage Configuration File documentation.
</description>
- <licence>AGPL</licence>
+ <version>1.5.0</version>
+ <licence>agpl</licence>
<author>Robin Appelman</author>
<author>Michael Gapczynski</author>
<author>Vincent Petry</author>
- <documentation>
- <admin>admin-external-storage</admin>
- </documentation>
- <version>1.5.0</version>
+ <namespace>Files_External</namespace>
+
<types>
<filesystem/>
</types>
- <ocsid>166048</ocsid>
- <namespace>Files_External</namespace>
+ <documentation>
+ <admin>admin-external-storage</admin>
+ </documentation>
+ <category>files</category>
+ <category>integration</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
- <settings>
- <admin>OCA\Files_External\Settings\Admin</admin>
- <admin-section>OCA\Files_External\Settings\Section</admin-section>
- <personal>OCA\Files_External\Settings\Personal</personal>
- <personal-section>OCA\Files_External\Settings\PersonalSection</personal-section>
- </settings>
-
<commands>
<command>OCA\Files_External\Command\ListCommand</command>
<command>OCA\Files_External\Command\Config</command>
@@ -46,4 +44,11 @@ External storage can be configured using the GUI or at the command line. This se
<command>OCA\Files_External\Command\Verify</command>
<command>OCA\Files_External\Command\Notify</command>
</commands>
+
+ <settings>
+ <admin>OCA\Files_External\Settings\Admin</admin>
+ <admin-section>OCA\Files_External\Settings\Section</admin-section>
+ <personal>OCA\Files_External\Settings\Personal</personal>
+ <personal-section>OCA\Files_External\Settings\PersonalSection</personal-section>
+ </settings>
</info>
diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml
index 326bd49e9bc..b4c54247267 100644
--- a/apps/files_sharing/appinfo/info.xml
+++ b/apps/files_sharing/appinfo/info.xml
@@ -1,28 +1,46 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>files_sharing</id>
<name>File sharing</name>
+ <summary>File sharing</summary>
<description>
This application enables users to share files within Nextcloud. If enabled, the admin can choose which groups can share files. The applicable users can then share files and folders with other users and groups within Nextcloud. In addition, if the admin enables the share link feature, an external link can be used to share files with other users outside of Nextcloud. Admins can also enforce passwords, expirations dates, and enable server to server sharing via share links, as well as sharing from mobile devices.
Turning the feature off removes shared files and folders on the server for all share recipients, and also on the sync clients and mobile apps. More information is available in the Nextcloud Documentation.
</description>
- <licence>AGPL</licence>
+ <version>1.6.0</version>
+ <licence>agpl</licence>
<author>Michael Gapczynski</author>
<author>Bjoern Schiessle</author>
+ <namespace>Files_Sharing</namespace>
<default_enable/>
- <version>1.6.0</version>
<types>
<filesystem/>
</types>
+
+ <category>files</category>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
- <public>
- <files>public.php</files>
- </public>
- <namespace>Files_Sharing</namespace>
+ <background-jobs>
+ <job>OCA\Files_Sharing\DeleteOrphanedSharesJob</job>
+ <job>OCA\Files_Sharing\ExpireSharesJob</job>
+ </background-jobs>
+
+ <repair-steps>
+ <post-migration>
+ <step>OCA\Files_Sharing\Migration\OwncloudGuestShareType</step>
+ <step>OCA\Files_Sharing\Migration\SetPasswordColumn</step>
+ </post-migration>
+ </repair-steps>
+
+ <commands>
+ <command>OCA\Files_Sharing\Command\CleanupRemoteStorages</command>
+ </commands>
<activity>
<settings>
@@ -44,25 +62,13 @@ Turning the feature off removes shared files and folders on the server for all s
</providers>
</activity>
- <background-jobs>
- <job>OCA\Files_Sharing\DeleteOrphanedSharesJob</job>
- <job>OCA\Files_Sharing\ExpireSharesJob</job>
- </background-jobs>
-
- <commands>
- <command>OCA\Files_Sharing\Command\CleanupRemoteStorages</command>
- </commands>
-
- <repair-steps>
- <post-migration>
- <step>OCA\Files_Sharing\Migration\OwncloudGuestShareType</step>
- <step>OCA\Files_Sharing\Migration\SetPasswordColumn</step>
- </post-migration>
- </repair-steps>
-
<collaboration>
<plugins>
<plugin type="autocomplete-sort">OCA\Files_Sharing\Collaboration\ShareRecipientSorter</plugin>
</plugins>
</collaboration>
+
+ <public>
+ <files>public.php</files>
+ </public>
</info>
diff --git a/apps/files_trashbin/appinfo/info.xml b/apps/files_trashbin/appinfo/info.xml
index 305906a5446..585e61fe1e8 100644
--- a/apps/files_trashbin/appinfo/info.xml
+++ b/apps/files_trashbin/appinfo/info.xml
@@ -1,26 +1,30 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>files_trashbin</id>
<name>Deleted files</name>
+ <summary>This application enables users to restore files that were deleted from the system.</summary>
<description>
This application enables users to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the users file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.
To prevent a user from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation.
</description>
- <licence>AGPL</licence>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
<author>Bjoern Schiessle</author>
+ <namespace>Files_Trashbin</namespace>
<default_enable/>
- <version>1.4.0</version>
<types>
<filesystem/>
</types>
- <namespace>Files_Trashbin</namespace>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<documentation>
<user>user-trashbin</user>
</documentation>
+ <category>files</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<background-jobs>
<job>OCA\Files_Trashbin\BackgroundJob\ExpireTrash</job>
diff --git a/apps/files_versions/appinfo/info.xml b/apps/files_versions/appinfo/info.xml
index 511b1713cb1..8f7e4d7b716 100644
--- a/apps/files_versions/appinfo/info.xml
+++ b/apps/files_versions/appinfo/info.xml
@@ -1,26 +1,30 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>files_versions</id>
<name>Versions</name>
- <licence>AGPL</licence>
- <author>Frank Karlitschek</author>
- <author>Bjoern Schiessle</author>
+ <summary>This application automatically maintains older versions of files that are changed.</summary>
<description>
- This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.
-In addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation.
+ This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.
+ In addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation.
</description>
<version>1.7.0</version>
+ <licence>agpl</licence>
+ <author>Frank Karlitschek</author>
+ <author>Bjoern Schiessle</author>
+ <namespace>Files_Versions</namespace>
+ <default_enable/>
<types>
<filesystem/>
</types>
- <namespace>Files_Versions</namespace>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<documentation>
<user>user-versions</user>
</documentation>
- <default_enable/>
+ <category>files</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<background-jobs>
<job>OCA\Files_Versions\BackgroundJob\ExpireVersions</job>
diff --git a/apps/lookup_server_connector/appinfo/info.xml b/apps/lookup_server_connector/appinfo/info.xml
index 31fc4fe8e5f..19ffeb4de1c 100644
--- a/apps/lookup_server_connector/appinfo/info.xml
+++ b/apps/lookup_server_connector/appinfo/info.xml
@@ -1,18 +1,22 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>lookup_server_connector</id>
<name>Lookup Server Connector</name>
+ <summary>Sync public user information with the lookup server</summary>
<description>Sync public user information with the lookup server</description>
- <licence>AGPL</licence>
+ <version>1.2.0</version>
+ <licence>agpl</licence>
<author>Bjoern Schiessle</author>
<namespace>LookupServerConnector</namespace>
- <version>1.2.0</version>
- <category>other</category>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<default_enable/>
<types>
<authentication/>
</types>
+ <category>integration</category>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
</info>
diff --git a/apps/oauth2/appinfo/info.xml b/apps/oauth2/appinfo/info.xml
index 0bbad31dab3..ac18b5cdb94 100644
--- a/apps/oauth2/appinfo/info.xml
+++ b/apps/oauth2/appinfo/info.xml
@@ -1,16 +1,21 @@
<?xml version="1.0"?>
-<info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>oauth2</id>
<name>OAuth 2.0</name>
+ <summary>Allows OAuth2 compatible authentication from other web applications.</summary>
<description>The OAuth2 app allows administrators to configure the built-in authentication workflow to also allow OAuth2 compatible authentication from other web applications.</description>
+ <version>1.2.0</version>
<licence>agpl</licence>
<author>Lukas Reschke</author>
<namespace>OAuth2</namespace>
- <version>1.2.0</version>
<default_enable/>
<types>
<authentication/>
</types>
+
+ <category>integration</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
diff --git a/apps/provisioning_api/appinfo/info.xml b/apps/provisioning_api/appinfo/info.xml
index 849e74432f0..05e805c1170 100644
--- a/apps/provisioning_api/appinfo/info.xml
+++ b/apps/provisioning_api/appinfo/info.xml
@@ -1,7 +1,9 @@
-<?xml version="1.0"?>
-<info>
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>provisioning_api</id>
<name>Provisioning API</name>
+ <summary>This application enables a set of APIs that external systems can use to manage users, groups and apps.</summary>
<description>
This application enables a set of APIs that external systems can use to create, edit, delete and query user
attributes, query, set and remove groups, set quota and query total storage used in Nextcloud. Group admin users
@@ -11,17 +13,19 @@
listed above. More information is available in the Provisioning API documentation, including example calls
and server responses.
</description>
- <licence>AGPL</licence>
- <author>Tom Needham</author>
- <default_enable/>
- <documentation>
- <admin>admin-provisioning-api</admin>
- </documentation>
<version>1.4.0</version>
+ <licence>agpl</licence>
+ <author>Tom Needham</author>
<namespace>Provisioning_API</namespace>
+ <default_enable/>
<types>
<prevent_group_restriction/>
</types>
+ <documentation>
+ <admin>admin-provisioning-api</admin>
+ </documentation>
+ <category>integration</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
diff --git a/apps/sharebymail/appinfo/info.xml b/apps/sharebymail/appinfo/info.xml
index f1cd70a66b3..6bec13e819b 100644
--- a/apps/sharebymail/appinfo/info.xml
+++ b/apps/sharebymail/appinfo/info.xml
@@ -1,29 +1,32 @@
<?xml version="1.0"?>
-<info>
- <id>sharebymail</id>
- <name>Share by mail</name>
- <description>Share provider which allows you to share files by mail</description>
- <licence>AGPL</licence>
- <author>Bjoern Schiessle</author>
- <version>1.4.0</version>
- <namespace>ShareByMail</namespace>
- <category>other</category>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
- <default_enable/>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>sharebymail</id>
+ <name>Share by mail</name>
+ <summary>Share provider which allows you to share files by mail</summary>
+ <description>Share provider which allows you to share files by mail</description>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
+ <author>Bjoern Schiessle</author>
+ <namespace>ShareByMail</namespace>
+ <default_enable/>
- <types>
- <filesystem/>
- </types>
+ <types>
+ <filesystem/>
+ </types>
+ <category>social</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
- <settings>
- <admin>OCA\ShareByMail\Settings\Admin</admin>
- </settings>
+ <settings>
+ <admin>OCA\ShareByMail\Settings\Admin</admin>
+ </settings>
- <activity>
- <providers>
- <provider>OCA\ShareByMail\Activity</provider>
- </providers>
- </activity>
+ <activity>
+ <providers>
+ <provider>OCA\ShareByMail\Activity</provider>
+ </providers>
+ </activity>
</info>
diff --git a/apps/systemtags/appinfo/info.xml b/apps/systemtags/appinfo/info.xml
index e46daf4b042..6484cd450ca 100644
--- a/apps/systemtags/appinfo/info.xml
+++ b/apps/systemtags/appinfo/info.xml
@@ -1,21 +1,26 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>systemtags</id>
<name>Collaborative tags</name>
+ <summary>Collaborative tagging functionality which shares tags among users.</summary>
<description>Collaborative tagging functionality which shares tags among users. Great for teams.
(If you are a provider with a multi-tenancy installation, it is advised to deactivate this app as tags are shared.)</description>
- <licence>AGPL</licence>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
<author>Vincent Petry</author>
<author>Joas Schilling</author>
- <default_enable/>
- <version>1.4.0</version>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
<namespace>SystemTags</namespace>
+ <default_enable/>
<types>
<logging/>
</types>
+ <category>files</category>
+ <category>organization</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<settings>
<admin>OCA\SystemTags\Settings\Admin</admin>
</settings>
diff --git a/apps/testing/appinfo/info.xml b/apps/testing/appinfo/info.xml
index d0d350a0364..81be7649d8e 100644
--- a/apps/testing/appinfo/info.xml
+++ b/apps/testing/appinfo/info.xml
@@ -1,15 +1,19 @@
-<?xml version="1.0"?>
-<info>
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>testing</id>
<name>QA testing</name>
+ <summary>This app is only for testing! It is dangerous to have it enabled in a live instance</summary>
<description>This app is only for testing! It is dangerous to have it enabled in a live instance</description>
- <licence>AGPL</licence>
- <author>Joas Schilling</author>
<version>1.4.0</version>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
+ <licence>agpl</licence>
+ <author>Joas Schilling</author>
<types>
<authentication/>
</types>
+ <category>monitoring</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
</info>
diff --git a/apps/theming/appinfo/info.xml b/apps/theming/appinfo/info.xml
index d2eacea77b3..63ae7d196c1 100644
--- a/apps/theming/appinfo/info.xml
+++ b/apps/theming/appinfo/info.xml
@@ -1,23 +1,25 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>theming</id>
<name>Theming</name>
+ <summary>Adjust the Nextcloud theme</summary>
<description>Adjust the Nextcloud theme</description>
- <licence>AGPL</licence>
- <author>Nextcloud</author>
<version>1.5.0</version>
+ <licence>agpl</licence>
+ <author>Nextcloud</author>
<namespace>Theming</namespace>
- <category>other</category>
-
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
+ <default_enable/>
<types>
<logging/>
</types>
- <default_enable/>
+ <category>customization</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<settings>
<admin>OCA\Theming\Settings\Admin</admin>
diff --git a/apps/twofactor_backupcodes/appinfo/info.xml b/apps/twofactor_backupcodes/appinfo/info.xml
index f2581de63e0..9fe0071a442 100644
--- a/apps/twofactor_backupcodes/appinfo/info.xml
+++ b/apps/twofactor_backupcodes/appinfo/info.xml
@@ -1,29 +1,32 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>twofactor_backupcodes</id>
<name>Two factor backup codes</name>
+ <summary>A two-factor auth backup codes provider</summary>
<description>A two-factor auth backup codes provider</description>
+ <version>1.3.0</version>
<licence>agpl</licence>
<author>Christoph Wurst</author>
- <version>1.3.0</version>
<namespace>TwoFactorBackupCodes</namespace>
- <category>other</category>
+ <category>integration</category>
+ <category>security</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="14" max-version="14" />
+ </dependencies>
<two-factor-providers>
<provider>OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider</provider>
</two-factor-providers>
- <dependencies>
- <nextcloud min-version="14" max-version="14" />
- </dependencies>
+ <settings>
+ <personal>OCA\TwoFactorBackupCodes\Settings\Personal</personal>
+ </settings>
<activity>
<providers>
<provider>OCA\TwoFactorBackupCodes\Activity\Provider</provider>
</providers>
</activity>
-
- <settings>
- <personal>OCA\TwoFactorBackupCodes\Settings\Personal</personal>
- </settings>
</info>
diff --git a/apps/updatenotification/appinfo/info.xml b/apps/updatenotification/appinfo/info.xml
index 14ec98916ab..a227ccd6557 100644
--- a/apps/updatenotification/appinfo/info.xml
+++ b/apps/updatenotification/appinfo/info.xml
@@ -1,13 +1,17 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>updatenotification</id>
<name>Update notification</name>
+ <summary>Displays update notifications for Nextcloud and provides the SSO for the updater.</summary>
<description>Displays update notifications for Nextcloud and provides the SSO for the updater.</description>
- <licence>AGPL</licence>
- <author>Lukas Reschke</author>
<version>1.4.1</version>
+ <licence>agpl</licence>
+ <author>Lukas Reschke</author>
<namespace>UpdateNotification</namespace>
<default_enable/>
+ <category>monitoring</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml
index dbf9a736899..bb5ebce4fc5 100644
--- a/apps/user_ldap/appinfo/info.xml
+++ b/apps/user_ldap/appinfo/info.xml
@@ -1,43 +1,46 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>user_ldap</id>
<name>LDAP user and group backend</name>
+ <summary>This application enables administrators to connect Nextcloud to an LDAP-based user directory.</summary>
<description>This application enables administrators to connect Nextcloud to an LDAP-based user directory for authentication and provisioning users, groups and user attributes. Admins can configure this application to connect to one or more LDAP directories or Active Directories via an LDAP interface. Attributes such as user quota, email, avatar pictures, group memberships and more can be pulled into Nextcloud from a directory with the appropriate queries and filters.
A user logs into Nextcloud with their LDAP or AD credentials, and is granted access based on an authentication request handled by the LDAP or AD server. Nextcloud does not store LDAP or AD passwords, rather these credentials are used to authenticate a user and then Nextcloud uses a session for the user ID. More information is available in the LDAP User and Group Backend documentation.
</description>
- <licence>AGPL</licence>
+ <version>1.4.0</version>
+ <licence>agpl</licence>
<author>Dominik Schmidt</author>
<author>Arthur Schiwon</author>
- <version>1.4.0</version>
+ <namespace>User_LDAP</namespace>
<types>
<authentication/>
</types>
<documentation>
<admin>admin-ldap</admin>
</documentation>
+ <category>integration</category>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
<lib>ldap</lib>
<nextcloud min-version="14" max-version="14" />
</dependencies>
- <namespace>User_LDAP</namespace>
-
<background-jobs>
<job>OCA\User_LDAP\Jobs\UpdateGroups</job>
<job>OCA\User_LDAP\Jobs\CleanUp</job>
<job>OCA\User_LDAP\Jobs\Sync</job>
</background-jobs>
- <settings>
- <admin>OCA\User_LDAP\Settings\Admin</admin>
- <admin-section>OCA\User_LDAP\Settings\Section</admin-section>
- </settings>
-
<repair-steps>
<post-migration>
<step>OCA\User_LDAP\Migration\UUIDFixInsert</step>
</post-migration>
</repair-steps>
+
+ <settings>
+ <admin>OCA\User_LDAP\Settings\Admin</admin>
+ <admin-section>OCA\User_LDAP\Settings\Section</admin-section>
+ </settings>
</info>
diff --git a/apps/workflowengine/appinfo/info.xml b/apps/workflowengine/appinfo/info.xml
index 5d51333f750..1c069ca5432 100644
--- a/apps/workflowengine/appinfo/info.xml
+++ b/apps/workflowengine/appinfo/info.xml
@@ -1,22 +1,24 @@
<?xml version="1.0"?>
-<info>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>workflowengine</id>
<name>Files workflow engine</name>
- <description></description>
- <licence>AGPL</licence>
- <author>Morris Jobke</author>
+ <summary>Files workflow engine</summary>
+ <description>Files workflow engine</description>
<version>1.4.0</version>
+ <licence>agpl</licence>
+ <author>Morris Jobke</author>
<namespace>WorkflowEngine</namespace>
- <category>other</category>
- <website>https://github.com/nextcloud/server</website>
- <bugs>https://github.com/nextcloud/server/issues</bugs>
- <repository type="git">https://github.com/nextcloud/server.git</repository>
-
<types>
<filesystem/>
</types>
+ <category>files</category>
+ <website>https://github.com/nextcloud/server</website>
+ <bugs>https://github.com/nextcloud/server/issues</bugs>
+ <repository>https://github.com/nextcloud/server.git</repository>
+
<dependencies>
<nextcloud min-version="14" max-version="14" />
</dependencies>
diff --git a/core/Command/App/CheckCode.php b/core/Command/App/CheckCode.php
index 82a137e58e1..530c1d30ec0 100644
--- a/core/Command/App/CheckCode.php
+++ b/core/Command/App/CheckCode.php
@@ -44,20 +44,12 @@ use OC\App\CodeChecker\PrivateCheck;
class CheckCode extends Command implements CompletionAwareInterface {
- /** @var InfoParser */
- private $infoParser;
-
protected $checkers = [
'private' => PrivateCheck::class,
'deprecation' => DeprecationCheck::class,
'strong-comparison' => StrongComparisonCheck::class,
];
- public function __construct(InfoParser $infoParser) {
- parent::__construct();
- $this->infoParser = $infoParser;
- }
-
protected function configure() {
$this
->setName('app:check-code')
@@ -134,50 +126,11 @@ class CheckCode extends Command implements CompletionAwareInterface {
}
if(!$input->getOption('skip-validate-info')) {
- $infoChecker = new InfoChecker($this->infoParser);
-
- $infoChecker->listen('InfoChecker', 'mandatoryFieldMissing', function($key) use ($output) {
- $output->writeln("<error>Mandatory field missing: $key</error>");
- });
-
- $infoChecker->listen('InfoChecker', 'deprecatedFieldFound', function($key, $value) use ($output) {
- if($value === [] || is_null($value) || $value === '') {
- $output->writeln("<info>Deprecated field available: $key</info>");
- } else {
- $output->writeln("<info>Deprecated field available: $key => $value</info>");
- }
- });
-
- $infoChecker->listen('InfoChecker', 'missingRequirement', function($minMax) use ($output) {
- $output->writeln("<error>Nextcloud $minMax version requirement missing</error>");
- });
-
- $infoChecker->listen('InfoChecker', 'differentVersions', function($versionFile, $infoXML) use ($output) {
- $output->writeln("<error>Different versions provided (appinfo/version: $versionFile - appinfo/info.xml: $infoXML)</error>");
+ $infoChecker = new InfoChecker();
+ $infoChecker->listen('InfoChecker', 'parseError', function($error) use ($output) {
+ $output->writeln("<error>Invalid appinfo.xml file found: $error</error>");
});
- $infoChecker->listen('InfoChecker', 'sameVersions', function($path) use ($output) {
- $output->writeln("<info>Version file isn't needed anymore and can be safely removed ($path)</info>");
- });
-
- $infoChecker->listen('InfoChecker', 'migrateVersion', function($version) use ($output) {
- $output->writeln("<error>Migrate the app version to appinfo/info.xml (add <version>$version</version> to appinfo/info.xml and remove appinfo/version)</error>");
- });
-
- if(OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
- $infoChecker->listen('InfoChecker', 'mandatoryFieldFound', function($key, $value) use ($output) {
- $output->writeln("<info>Mandatory field available: $key => $value</info>");
- });
-
- $infoChecker->listen('InfoChecker', 'optionalFieldFound', function($key, $value) use ($output) {
- $output->writeln("<info>Optional field available: $key => $value</info>");
- });
-
- $infoChecker->listen('InfoChecker', 'unusedFieldFound', function($key, $value) use ($output) {
- $output->writeln("<info>Unused field available: $key => $value</info>");
- });
- }
-
$infoErrors = $infoChecker->analyse($appId);
$errors = array_merge($errors, $infoErrors);
diff --git a/core/register_command.php b/core/register_command.php
index 372d775dc14..578b4f799b6 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -40,8 +40,7 @@
$application->add(new \Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand());
$application->add(new OC\Core\Command\Status);
$application->add(new OC\Core\Command\Check(\OC::$server->getSystemConfig()));
-$infoParser = new \OC\App\InfoParser();
-$application->add(new OC\Core\Command\App\CheckCode($infoParser));
+$application->add(new OC\Core\Command\App\CheckCode());
$application->add(new OC\Core\Command\L10n\CreateJs());
$application->add(new \OC\Core\Command\Integrity\SignApp(
\OC::$server->getIntegrityCodeChecker(),
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 0e921ba1b7f..81037b42613 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -411,6 +411,7 @@ class AppManager implements IAppManager {
/**
* @inheritdoc
+ * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::isShipped()
*/
public function isShipped($appId) {
$this->loadShippedJson();
@@ -422,6 +423,10 @@ class AppManager implements IAppManager {
return in_array($appId, $alwaysEnabled, true);
}
+ /**
+ * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::loadShippedJson()
+ * @throws \Exception
+ */
private function loadShippedJson() {
if ($this->shippedApps === null) {
$shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
diff --git a/lib/private/App/CodeChecker/InfoChecker.php b/lib/private/App/CodeChecker/InfoChecker.php
index e8791bd7037..f5de6d376d8 100644
--- a/lib/private/App/CodeChecker/InfoChecker.php
+++ b/lib/private/App/CodeChecker/InfoChecker.php
@@ -23,121 +23,88 @@
namespace OC\App\CodeChecker;
-use OC\App\InfoParser;
use OC\Hooks\BasicEmitter;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
class InfoChecker extends BasicEmitter {
- /** @var InfoParser */
- private $infoParser;
+ /** @var string[] */
+ private $shippedApps;
- private $mandatoryFields = [
- 'author',
- 'description',
- 'dependencies',
- 'id',
- 'licence',
- 'name',
- 'version',
- ];
- private $optionalFields = [
- 'bugs',
- 'category',
- 'default_enable',
- 'documentation',
- 'namespace',
- 'ocsid',
- 'public',
- 'remote',
- 'repository',
- 'types',
- 'website',
- ];
- private $deprecatedFields = [
- 'info',
- 'require',
- 'requiremax',
- 'requiremin',
- 'shipped',
- 'standalone',
- ];
-
- public function __construct(InfoParser $infoParser) {
- $this->infoParser = $infoParser;
- }
+ /** @var string[] */
+ private $alwaysEnabled;
/**
* @param string $appId
* @return array
+ * @throws \RuntimeException
*/
- public function analyse($appId) {
+ public function analyse($appId): array {
$appPath = \OC_App::getAppPath($appId);
if ($appPath === false) {
throw new \RuntimeException("No app with given id <$appId> known.");
}
- $errors = [];
-
- $info = $this->infoParser->parse($appPath . '/appinfo/info.xml');
-
- if (!isset($info['dependencies']['nextcloud']['@attributes']['min-version'])) {
- $errors[] = [
- 'type' => 'missingRequirement',
- 'field' => 'min',
- ];
- $this->emit('InfoChecker', 'missingRequirement', ['min']);
- }
-
- if (!isset($info['dependencies']['nextcloud']['@attributes']['max-version'])) {
- $errors[] = [
- 'type' => 'missingRequirement',
- 'field' => 'max',
- ];
- $this->emit('InfoChecker', 'missingRequirement', ['max']);
- }
-
- foreach ($info as $key => $value) {
- if(is_array($value)) {
- $value = json_encode($value);
- }
- if (in_array($key, $this->mandatoryFields)) {
- $this->emit('InfoChecker', 'mandatoryFieldFound', [$key, $value]);
- continue;
- }
+ $xml = new \DOMDocument();
+ $xml->load($appPath . '/appinfo/info.xml');
- if (in_array($key, $this->optionalFields)) {
- $this->emit('InfoChecker', 'optionalFieldFound', [$key, $value]);
- continue;
+ $schema = \OC::$SERVERROOT . '/resources/app-info.xsd';
+ try {
+ if ($this->isShipped($appId)) {
+ // Shipped apps are allowed to have the public and default_enabled tags
+ $schema = \OC::$SERVERROOT . '/resources/app-info-shipped.xsd';
}
-
- if (in_array($key, $this->deprecatedFields)) {
- // skip empty arrays - empty arrays for remote and public are always added
- if($value === '[]' && in_array($key, ['public', 'remote', 'info'])) {
- continue;
- }
- $this->emit('InfoChecker', 'deprecatedFieldFound', [$key, $value]);
- continue;
- }
-
- $this->emit('InfoChecker', 'unusedFieldFound', [$key, $value]);
+ } catch (\Exception $e) {
+ // Assume it is not shipped
}
- foreach ($this->mandatoryFields as $key) {
- if(!isset($info[$key])) {
- $this->emit('InfoChecker', 'mandatoryFieldMissing', [$key]);
+ $errors = [];
+ if (!$xml->schemaValidate($schema)) {
+ foreach (libxml_get_errors() as $error) {
$errors[] = [
- 'type' => 'mandatoryFieldMissing',
- 'field' => $key,
+ 'type' => 'parseError',
+ 'field' => $error->message,
];
+ $this->emit('InfoChecker', 'parseError', [$error->message]);
}
}
- $versionFile = $appPath . '/appinfo/version';
- if (is_file($versionFile)) {
- $version = trim(file_get_contents($versionFile));
- $this->emit('InfoChecker', 'migrateVersion', [$version]);
- }
-
return $errors;
}
+
+ /**
+ * This is a copy of \OC\App\AppManager::isShipped(), keep both in sync.
+ * This method is copied, so the code checker works even when Nextcloud is
+ * not installed yet. The AppManager requires a database connection, which
+ * fails in that case.
+ *
+ * @param string $appId
+ * @return bool
+ * @throws \Exception
+ */
+ protected function isShipped(string $appId): bool {
+ $this->loadShippedJson();
+ return \in_array($appId, $this->shippedApps, true);
+ }
+
+ /**
+ * This is a copy of \OC\App\AppManager::loadShippedJson(), keep both in sync
+ * This method is copied, so the code checker works even when Nextcloud is
+ * not installed yet. The AppManager requires a database connection, which
+ * fails in that case.
+ *
+ * @throws \Exception
+ */
+ protected function loadShippedJson() {
+ if ($this->shippedApps === null) {
+ $shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
+ if (!file_exists($shippedJson)) {
+ throw new \Exception("File not found: $shippedJson");
+ }
+ $content = json_decode(file_get_contents($shippedJson), true);
+ $this->shippedApps = $content['shippedApps'];
+ $this->alwaysEnabled = $content['alwaysEnabled'];
+ }
+ }
}
diff --git a/resources/app-info-shipped.xsd b/resources/app-info-shipped.xsd
new file mode 100644
index 00000000000..97221d1fb9c
--- /dev/null
+++ b/resources/app-info-shipped.xsd
@@ -0,0 +1,671 @@
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xs:element name="info">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="id" type="id" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="name" type="l10n-string" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="summary" type="l10n-string" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="description" type="l10n-text" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="version" type="semver"
+ minOccurs="1" maxOccurs="1"/>
+ <xs:element name="licence" type="licence" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="author" type="author" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="namespace" type="limited-string"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="default_enable" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="types" type="types" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="documentation" type="documentation"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="category" type="category" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="website" type="url" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="discussion" type="url" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="bugs" type="url" minOccurs="1"
+ maxOccurs="1"/>
+ <xs:element name="repository" type="repository" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="screenshot" type="screenshot" minOccurs="0"
+ maxOccurs="10"/>
+ <xs:element name="dependencies" type="dependencies"
+ minOccurs="1" maxOccurs="1"/>
+ <xs:element name="background-jobs" type="jobs"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="repair-steps" type="repair-steps"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="two-factor-providers"
+ type="two-factor-providers"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="commands" type="commands"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="settings" type="settings" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="activity" type="activity" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="navigations" type="navigations" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="contactsmenu" type="contactsmenu" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="collaboration" type="collaboration" minOccurs="0"
+ maxOccurs="1" />
+ <xs:element name="sabre" type="sabre" minOccurs="0"
+ maxOccurs="1" />
+ <xs:element name="public" type="public" minOccurs="0"
+ maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:unique name="uniqueNameL10n">
+ <xs:selector xpath="name"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueSummaryL10n">
+ <xs:selector xpath="summary"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueDescriptionL10n">
+ <xs:selector xpath="description"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueLicense">
+ <xs:selector xpath="licence"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueTypes">
+ <xs:selector xpath="types/type"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueCategory">
+ <xs:selector xpath="category"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueDatabase">
+ <xs:selector xpath="dependencies/database"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueLib">
+ <xs:selector xpath="dependencies/lib"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueCommand">
+ <xs:selector xpath="dependencies/command"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ </xs:element>
+
+ <!-- basic types -->
+ <xs:simpleType name="empty-string">
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="non-empty-string">
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="limited-string">
+ <xs:restriction base="non-empty-string">
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="l10n-text">
+ <xs:simpleContent>
+ <xs:extension base="non-empty-string">
+ <xs:attribute name="lang" type="l10n-code" default="en"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="l10n-string">
+ <xs:simpleContent>
+ <xs:restriction base="l10n-text">
+ <xs:maxLength value="128"/>
+ </xs:restriction>
+ </xs:simpleContent>
+ </xs:complexType>
+
+
+ <xs:simpleType name="l10n-code">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="af"/>
+ <xs:enumeration value="ar"/>
+ <xs:enumeration value="ast"/>
+ <xs:enumeration value="az"/>
+ <xs:enumeration value="bg"/>
+ <xs:enumeration value="be"/>
+ <xs:enumeration value="bn"/>
+ <xs:enumeration value="br"/>
+ <xs:enumeration value="bs"/>
+ <xs:enumeration value="ca"/>
+ <xs:enumeration value="cs"/>
+ <xs:enumeration value="cy"/>
+ <xs:enumeration value="da"/>
+ <xs:enumeration value="de"/>
+ <xs:enumeration value="el"/>
+ <xs:enumeration value="en"/>
+ <xs:enumeration value="eo"/>
+ <xs:enumeration value="es"/>
+ <xs:enumeration value="es-ar"/>
+ <xs:enumeration value="es-co"/>
+ <xs:enumeration value="es-mx"/>
+ <xs:enumeration value="es-ni"/>
+ <xs:enumeration value="es-ve"/>
+ <xs:enumeration value="et"/>
+ <xs:enumeration value="eu"/>
+ <xs:enumeration value="fa"/>
+ <xs:enumeration value="fi"/>
+ <xs:enumeration value="fr"/>
+ <xs:enumeration value="fy"/>
+ <xs:enumeration value="ga"/>
+ <xs:enumeration value="gd"/>
+ <xs:enumeration value="gl"/>
+ <xs:enumeration value="he"/>
+ <xs:enumeration value="hi"/>
+ <xs:enumeration value="hr"/>
+ <xs:enumeration value="hu"/>
+ <xs:enumeration value="ia"/>
+ <xs:enumeration value="id"/>
+ <xs:enumeration value="io"/>
+ <xs:enumeration value="is"/>
+ <xs:enumeration value="it"/>
+ <xs:enumeration value="ja"/>
+ <xs:enumeration value="ka"/>
+ <xs:enumeration value="kk"/>
+ <xs:enumeration value="km"/>
+ <xs:enumeration value="kn"/>
+ <xs:enumeration value="ko"/>
+ <xs:enumeration value="lb"/>
+ <xs:enumeration value="lt"/>
+ <xs:enumeration value="lv"/>
+ <xs:enumeration value="mk"/>
+ <xs:enumeration value="ml"/>
+ <xs:enumeration value="mn"/>
+ <xs:enumeration value="mr"/>
+ <xs:enumeration value="my"/>
+ <xs:enumeration value="nb"/>
+ <xs:enumeration value="ne"/>
+ <xs:enumeration value="nl"/>
+ <xs:enumeration value="nn"/>
+ <xs:enumeration value="os"/>
+ <xs:enumeration value="pa"/>
+ <xs:enumeration value="pl"/>
+ <xs:enumeration value="pt"/>
+ <xs:enumeration value="pt-br"/>
+ <xs:enumeration value="ro"/>
+ <xs:enumeration value="ru"/>
+ <xs:enumeration value="sk"/>
+ <xs:enumeration value="sl"/>
+ <xs:enumeration value="sq"/>
+ <xs:enumeration value="sr"/>
+ <xs:enumeration value="sr-latn"/>
+ <xs:enumeration value="sv"/>
+ <xs:enumeration value="sw"/>
+ <xs:enumeration value="ta"/>
+ <xs:enumeration value="te"/>
+ <xs:enumeration value="th"/>
+ <xs:enumeration value="tr"/>
+ <xs:enumeration value="tt"/>
+ <xs:enumeration value="udm"/>
+ <xs:enumeration value="uk"/>
+ <xs:enumeration value="ur"/>
+ <xs:enumeration value="vi"/>
+ <xs:enumeration value="zh-hans"/>
+ <xs:enumeration value="zh-hant"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="semver">
+ <xs:restriction base="limited-string">
+ <xs:pattern
+ value="(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="version">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[0-9]+(\.[0-9]+){0,2}"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="url">
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="https?://.+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-user-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|user-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-admin-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|admin-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-developer-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|developer-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="secure-url">
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="https://.+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="email">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[^@]+@[^\.]+\..+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- first level elements -->
+ <xs:complexType name="screenshot">
+ <xs:simpleContent>
+ <xs:extension base="secure-url">
+ <xs:attribute name="small-thumbnail" use="optional"
+ type="secure-url"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="id">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[a-z]+[a-z0-9_]*[a-z0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="author">
+ <xs:simpleContent>
+ <xs:extension base="limited-string">
+ <xs:attribute name="mail" type="email" use="optional"/>
+ <xs:attribute name="homepage" type="url" use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="repository">
+ <xs:simpleContent>
+ <xs:extension base="url">
+ <xs:attribute name="type" type="vcs" use="optional"
+ default="git"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="vcs">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="git"/>
+ <xs:enumeration value="mercurial"/>
+ <xs:enumeration value="subversion"/>
+ <xs:enumeration value="bzr"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="types">
+ <xs:sequence>
+ <xs:element name="prelogin" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="filesystem" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="authentication" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="logging" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="dav" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="prevent_group_restriction" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="category">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="security"/>
+ <xs:enumeration value="customization"/>
+ <xs:enumeration value="files"/>
+ <xs:enumeration value="integration"/>
+ <xs:enumeration value="monitoring"/>
+ <xs:enumeration value="multimedia"/>
+ <xs:enumeration value="office"/>
+ <xs:enumeration value="organization"/>
+ <xs:enumeration value="social"/>
+ <xs:enumeration value="tools"/>
+ <xs:enumeration value="games"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="licence">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="agpl"/>
+ <xs:enumeration value="mpl"/>
+ <xs:enumeration value="apache"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="databases">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="sqlite"/>
+ <xs:enumeration value="mysql"/>
+ <xs:enumeration value="pgsql"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="documentation">
+ <xs:sequence>
+ <xs:element name="user" type="doc-user-url" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="admin" type="doc-admin-url" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="developer" type="doc-developer-url" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="settings">
+ <xs:sequence>
+ <xs:element name="admin" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="admin-section" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="personal" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="personal-section" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity">
+ <xs:sequence>
+ <xs:element name="settings" type="activity-settings" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="filters" type="activity-filters" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="providers" type="activity-providers" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-settings">
+ <xs:sequence>
+ <xs:element name="setting" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-filters">
+ <xs:sequence>
+ <xs:element name="filter" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-providers">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="navigations">
+ <xs:sequence>
+ <xs:element name="navigation" type="navigation" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="navigation">
+ <xs:sequence>
+ <xs:element name="id" type="id" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="name" type="non-empty-string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="route" type="route" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="icon" type="xs:anyURI" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="order" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="type" type="navigation-type" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="role" type="navigation-role" default="all" use="optional"/>
+ </xs:complexType>
+
+ <xs:simpleType name="navigation-role">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="all"/>
+ <xs:enumeration value="admin"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="navigation-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="link"/>
+ <xs:enumeration value="settings"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="route">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="[0-9a-zA-Z_]+(\.[0-9a-zA-Z_]+){2}"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="contactsmenu">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration">
+ <xs:sequence>
+ <xs:element name="plugins" type="collaboration-plugins" minOccurs="0" maxOccurs="1">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration-plugins">
+ <xs:sequence>
+ <xs:element name="plugin" type="collaboration-plugins-plugin" minOccurs="1" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration-plugins-plugin">
+ <xs:simpleContent>
+ <xs:extension base="php-class">
+ <xs:attribute name="type" type="collaboration-plugin-type" use="required"/>
+ <xs:attribute name="share-type" type="share-type" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="collaboration-plugin-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="collaborator-search"/>
+ <xs:enumeration value="autocomplete-sort"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="sabre">
+ <xs:sequence>
+ <xs:element name="collections" type="sabre-collections" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="plugins" type="sabre-plugins" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sabre-collections">
+ <xs:sequence>
+ <xs:element name="collection" type="php-class" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sabre-plugins">
+ <xs:sequence>
+ <xs:element name="plugin" type="php-class" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="share-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SHARE_TYPE_USER"/>
+ <xs:enumeration value="SHARE_TYPE_GROUP"/>
+ <xs:enumeration value="SHARE_TYPE_LINK"/>
+ <xs:enumeration value="SHARE_TYPE_EMAIL"/>
+ <xs:enumeration value="SHARE_TYPE_CONTACT"/>
+ <xs:enumeration value="SHARE_TYPE_REMOTE"/>
+ <xs:enumeration value="SHARE_TYPE_CIRCLE"/>
+ <xs:enumeration value="SHARE_TYPE_GUEST"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+
+ <xs:complexType name="public">
+ <xs:sequence>
+ <xs:element name="webdav" type="path" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="files" type="path" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- dependencies -->
+ <xs:complexType name="dependencies">
+ <xs:sequence>
+ <xs:element name="php" type="php" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="database" type="database" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="command" type="shell-command" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="lib" type="min-max-version" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="owncloud" type="owncloud" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="nextcloud" type="nextcloud" minOccurs="1"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="owncloud">
+ <xs:attribute name="min-version" type="version" use="required"/>
+ <xs:attribute name="max-version" type="version" use="optional"/>
+ </xs:complexType>
+
+ <xs:complexType name="nextcloud">
+ <xs:attribute name="min-version" type="version" use="required"/>
+ <xs:attribute name="max-version" type="version" use="required"/>
+ </xs:complexType>
+
+ <xs:simpleType name="shell-command">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[a-zA-Z\-_]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="min-max-version">
+ <xs:simpleContent>
+ <xs:extension base="limited-string">
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="database">
+ <xs:simpleContent>
+ <xs:extension base="databases">
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="php">
+ <xs:simpleContent>
+ <xs:extension base="empty-string">
+ <xs:attribute name="min-int-size" type="bits" use="optional"
+ default="32"/>
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="bits">
+ <xs:restriction base="xs:int">
+ <xs:enumeration value="32"/>
+ <xs:enumeration value="64"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="repair-steps">
+ <xs:sequence>
+ <xs:element name="pre-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="post-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="live-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="install" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="uninstall" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="jobs">
+ <xs:sequence>
+ <xs:element name="job" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="steps">
+ <xs:sequence>
+ <xs:element name="step" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="two-factor-providers">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="commands">
+ <xs:sequence>
+ <xs:element name="command" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="php-class">
+ <xs:restriction base="xs:string">
+ <xs:pattern
+ value="[a-zA-Z_][0-9a-zA-Z_]*(\\[a-zA-Z_][0-9a-zA-Z_]*)*"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="path">
+ <xs:restriction base="xs:string">
+ <xs:pattern
+ value="[a-zA-Z_][0-9a-zA-Z_]*(/[a-zA-Z_][0-9a-zA-Z_]*)*\.php"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+</xs:schema>
diff --git a/resources/app-info.xsd b/resources/app-info.xsd
new file mode 100644
index 00000000000..4460b0f63b9
--- /dev/null
+++ b/resources/app-info.xsd
@@ -0,0 +1,652 @@
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xs:element name="info">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="id" type="id" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="name" type="l10n-string" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="summary" type="l10n-string" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="description" type="l10n-text" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="version" type="semver"
+ minOccurs="1" maxOccurs="1"/>
+ <xs:element name="licence" type="licence" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="author" type="author" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="namespace" type="limited-string"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="types" type="types" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="documentation" type="documentation"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="category" type="category" minOccurs="1"
+ maxOccurs="unbounded"/>
+ <xs:element name="website" type="url" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="discussion" type="url" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="bugs" type="url" minOccurs="1"
+ maxOccurs="1"/>
+ <xs:element name="repository" type="repository" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="screenshot" type="screenshot" minOccurs="0"
+ maxOccurs="10"/>
+ <xs:element name="dependencies" type="dependencies"
+ minOccurs="1" maxOccurs="1"/>
+ <xs:element name="background-jobs" type="jobs"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="repair-steps" type="repair-steps"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="two-factor-providers"
+ type="two-factor-providers"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="commands" type="commands"
+ minOccurs="0" maxOccurs="1"/>
+ <xs:element name="settings" type="settings" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="activity" type="activity" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="navigations" type="navigations" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="contactsmenu" type="contactsmenu" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="collaboration" type="collaboration" minOccurs="0"
+ maxOccurs="1" />
+ <xs:element name="sabre" type="sabre" minOccurs="0"
+ maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:unique name="uniqueNameL10n">
+ <xs:selector xpath="name"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueSummaryL10n">
+ <xs:selector xpath="summary"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueDescriptionL10n">
+ <xs:selector xpath="description"/>
+ <xs:field xpath="@lang"/>
+ </xs:unique>
+ <xs:unique name="uniqueLicense">
+ <xs:selector xpath="licence"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueTypes">
+ <xs:selector xpath="types/type"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueCategory">
+ <xs:selector xpath="category"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueDatabase">
+ <xs:selector xpath="dependencies/database"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueLib">
+ <xs:selector xpath="dependencies/lib"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ <xs:unique name="uniqueCommand">
+ <xs:selector xpath="dependencies/command"/>
+ <xs:field xpath="."/>
+ </xs:unique>
+ </xs:element>
+
+ <!-- basic types -->
+ <xs:simpleType name="empty-string">
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="non-empty-string">
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="limited-string">
+ <xs:restriction base="non-empty-string">
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="l10n-text">
+ <xs:simpleContent>
+ <xs:extension base="non-empty-string">
+ <xs:attribute name="lang" type="l10n-code" default="en"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="l10n-string">
+ <xs:simpleContent>
+ <xs:restriction base="l10n-text">
+ <xs:maxLength value="128"/>
+ </xs:restriction>
+ </xs:simpleContent>
+ </xs:complexType>
+
+
+ <xs:simpleType name="l10n-code">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="af"/>
+ <xs:enumeration value="ar"/>
+ <xs:enumeration value="ast"/>
+ <xs:enumeration value="az"/>
+ <xs:enumeration value="bg"/>
+ <xs:enumeration value="be"/>
+ <xs:enumeration value="bn"/>
+ <xs:enumeration value="br"/>
+ <xs:enumeration value="bs"/>
+ <xs:enumeration value="ca"/>
+ <xs:enumeration value="cs"/>
+ <xs:enumeration value="cy"/>
+ <xs:enumeration value="da"/>
+ <xs:enumeration value="de"/>
+ <xs:enumeration value="el"/>
+ <xs:enumeration value="en"/>
+ <xs:enumeration value="eo"/>
+ <xs:enumeration value="es"/>
+ <xs:enumeration value="es-ar"/>
+ <xs:enumeration value="es-co"/>
+ <xs:enumeration value="es-mx"/>
+ <xs:enumeration value="es-ni"/>
+ <xs:enumeration value="es-ve"/>
+ <xs:enumeration value="et"/>
+ <xs:enumeration value="eu"/>
+ <xs:enumeration value="fa"/>
+ <xs:enumeration value="fi"/>
+ <xs:enumeration value="fr"/>
+ <xs:enumeration value="fy"/>
+ <xs:enumeration value="ga"/>
+ <xs:enumeration value="gd"/>
+ <xs:enumeration value="gl"/>
+ <xs:enumeration value="he"/>
+ <xs:enumeration value="hi"/>
+ <xs:enumeration value="hr"/>
+ <xs:enumeration value="hu"/>
+ <xs:enumeration value="ia"/>
+ <xs:enumeration value="id"/>
+ <xs:enumeration value="io"/>
+ <xs:enumeration value="is"/>
+ <xs:enumeration value="it"/>
+ <xs:enumeration value="ja"/>
+ <xs:enumeration value="ka"/>
+ <xs:enumeration value="kk"/>
+ <xs:enumeration value="km"/>
+ <xs:enumeration value="kn"/>
+ <xs:enumeration value="ko"/>
+ <xs:enumeration value="lb"/>
+ <xs:enumeration value="lt"/>
+ <xs:enumeration value="lv"/>
+ <xs:enumeration value="mk"/>
+ <xs:enumeration value="ml"/>
+ <xs:enumeration value="mn"/>
+ <xs:enumeration value="mr"/>
+ <xs:enumeration value="my"/>
+ <xs:enumeration value="nb"/>
+ <xs:enumeration value="ne"/>
+ <xs:enumeration value="nl"/>
+ <xs:enumeration value="nn"/>
+ <xs:enumeration value="os"/>
+ <xs:enumeration value="pa"/>
+ <xs:enumeration value="pl"/>
+ <xs:enumeration value="pt"/>
+ <xs:enumeration value="pt-br"/>
+ <xs:enumeration value="ro"/>
+ <xs:enumeration value="ru"/>
+ <xs:enumeration value="sk"/>
+ <xs:enumeration value="sl"/>
+ <xs:enumeration value="sq"/>
+ <xs:enumeration value="sr"/>
+ <xs:enumeration value="sr-latn"/>
+ <xs:enumeration value="sv"/>
+ <xs:enumeration value="sw"/>
+ <xs:enumeration value="ta"/>
+ <xs:enumeration value="te"/>
+ <xs:enumeration value="th"/>
+ <xs:enumeration value="tr"/>
+ <xs:enumeration value="tt"/>
+ <xs:enumeration value="udm"/>
+ <xs:enumeration value="uk"/>
+ <xs:enumeration value="ur"/>
+ <xs:enumeration value="vi"/>
+ <xs:enumeration value="zh-hans"/>
+ <xs:enumeration value="zh-hant"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="semver">
+ <xs:restriction base="limited-string">
+ <xs:pattern
+ value="(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="version">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[0-9]+(\.[0-9]+){0,2}"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="url">
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="https?://.+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-user-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|user-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-admin-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|admin-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="doc-developer-url">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="https://.+|developer-[a-z]+[\-a-z]*[a-z]+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="secure-url">
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="https://.+"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="email">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[^@]+@[^\.]+\..+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- first level elements -->
+ <xs:complexType name="screenshot">
+ <xs:simpleContent>
+ <xs:extension base="secure-url">
+ <xs:attribute name="small-thumbnail" use="optional"
+ type="secure-url"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="id">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[a-z]+[a-z0-9_]*[a-z0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="author">
+ <xs:simpleContent>
+ <xs:extension base="limited-string">
+ <xs:attribute name="mail" type="email" use="optional"/>
+ <xs:attribute name="homepage" type="url" use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="repository">
+ <xs:simpleContent>
+ <xs:extension base="url">
+ <xs:attribute name="type" type="vcs" use="optional"
+ default="git"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="vcs">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="git"/>
+ <xs:enumeration value="mercurial"/>
+ <xs:enumeration value="subversion"/>
+ <xs:enumeration value="bzr"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="types">
+ <xs:sequence>
+ <xs:element name="prelogin" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="filesystem" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="authentication" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="logging" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="dav" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="prevent_group_restriction" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="category">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="security"/>
+ <xs:enumeration value="customization"/>
+ <xs:enumeration value="files"/>
+ <xs:enumeration value="integration"/>
+ <xs:enumeration value="monitoring"/>
+ <xs:enumeration value="multimedia"/>
+ <xs:enumeration value="office"/>
+ <xs:enumeration value="organization"/>
+ <xs:enumeration value="social"/>
+ <xs:enumeration value="tools"/>
+ <xs:enumeration value="games"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="licence">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="agpl"/>
+ <xs:enumeration value="mpl"/>
+ <xs:enumeration value="apache"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="databases">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="sqlite"/>
+ <xs:enumeration value="mysql"/>
+ <xs:enumeration value="pgsql"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="documentation">
+ <xs:sequence>
+ <xs:element name="user" type="doc-user-url" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="admin" type="doc-admin-url" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="developer" type="doc-developer-url" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="settings">
+ <xs:sequence>
+ <xs:element name="admin" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="admin-section" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="personal" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="personal-section" type="php-class" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity">
+ <xs:sequence>
+ <xs:element name="settings" type="activity-settings" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="filters" type="activity-filters" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="providers" type="activity-providers" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-settings">
+ <xs:sequence>
+ <xs:element name="setting" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-filters">
+ <xs:sequence>
+ <xs:element name="filter" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="activity-providers">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="navigations">
+ <xs:sequence>
+ <xs:element name="navigation" type="navigation" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="navigation">
+ <xs:sequence>
+ <xs:element name="id" type="id" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="name" type="non-empty-string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="route" type="route" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="icon" type="xs:anyURI" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="order" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="type" type="navigation-type" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="role" type="navigation-role" default="all" use="optional"/>
+ </xs:complexType>
+
+ <xs:simpleType name="navigation-role">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="all"/>
+ <xs:enumeration value="admin"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="navigation-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="link"/>
+ <xs:enumeration value="settings"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="route">
+ <xs:restriction base="non-empty-string">
+ <xs:pattern value="[0-9a-zA-Z_]+(\.[0-9a-zA-Z_]+){2}"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="contactsmenu">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration">
+ <xs:sequence>
+ <xs:element name="plugins" type="collaboration-plugins" minOccurs="0" maxOccurs="1">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration-plugins">
+ <xs:sequence>
+ <xs:element name="plugin" type="collaboration-plugins-plugin" minOccurs="1" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="collaboration-plugins-plugin">
+ <xs:simpleContent>
+ <xs:extension base="php-class">
+ <xs:attribute name="type" type="collaboration-plugin-type" use="required"/>
+ <xs:attribute name="share-type" type="share-type" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="collaboration-plugin-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="collaborator-search"/>
+ <xs:enumeration value="autocomplete-sort"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="sabre">
+ <xs:sequence>
+ <xs:element name="collections" type="sabre-collections" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="plugins" type="sabre-plugins" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sabre-collections">
+ <xs:sequence>
+ <xs:element name="collection" type="php-class" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="sabre-plugins">
+ <xs:sequence>
+ <xs:element name="plugin" type="php-class" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="share-type">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SHARE_TYPE_USER"/>
+ <xs:enumeration value="SHARE_TYPE_GROUP"/>
+ <xs:enumeration value="SHARE_TYPE_LINK"/>
+ <xs:enumeration value="SHARE_TYPE_EMAIL"/>
+ <xs:enumeration value="SHARE_TYPE_CONTACT"/>
+ <xs:enumeration value="SHARE_TYPE_REMOTE"/>
+ <xs:enumeration value="SHARE_TYPE_CIRCLE"/>
+ <xs:enumeration value="SHARE_TYPE_GUEST"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- dependencies -->
+ <xs:complexType name="dependencies">
+ <xs:sequence>
+ <xs:element name="php" type="php" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="database" type="database" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="command" type="shell-command" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="lib" type="min-max-version" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xs:element name="owncloud" type="owncloud" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="nextcloud" type="nextcloud" minOccurs="1"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="owncloud">
+ <xs:attribute name="min-version" type="version" use="required"/>
+ <xs:attribute name="max-version" type="version" use="optional"/>
+ </xs:complexType>
+
+ <xs:complexType name="nextcloud">
+ <xs:attribute name="min-version" type="version" use="required"/>
+ <xs:attribute name="max-version" type="version" use="required"/>
+ </xs:complexType>
+
+ <xs:simpleType name="shell-command">
+ <xs:restriction base="limited-string">
+ <xs:pattern value="[a-zA-Z\-_]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="min-max-version">
+ <xs:simpleContent>
+ <xs:extension base="limited-string">
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="database">
+ <xs:simpleContent>
+ <xs:extension base="databases">
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="php">
+ <xs:simpleContent>
+ <xs:extension base="empty-string">
+ <xs:attribute name="min-int-size" type="bits" use="optional"
+ default="32"/>
+ <xs:attribute name="min-version" type="version"
+ use="optional"/>
+ <xs:attribute name="max-version" type="version"
+ use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="bits">
+ <xs:restriction base="xs:int">
+ <xs:enumeration value="32"/>
+ <xs:enumeration value="64"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="repair-steps">
+ <xs:sequence>
+ <xs:element name="pre-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="post-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="live-migration" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="install" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ <xs:element name="uninstall" type="steps" minOccurs="0"
+ maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="jobs">
+ <xs:sequence>
+ <xs:element name="job" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="steps">
+ <xs:sequence>
+ <xs:element name="step" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="two-factor-providers">
+ <xs:sequence>
+ <xs:element name="provider" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="commands">
+ <xs:sequence>
+ <xs:element name="command" type="php-class" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="php-class">
+ <xs:restriction base="xs:string">
+ <xs:pattern
+ value="[a-zA-Z_][0-9a-zA-Z_]*(\\[a-zA-Z_][0-9a-zA-Z_]*)*"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+</xs:schema>
diff --git a/tests/apps/testapp-dependency-missing/appinfo/info.xml b/tests/apps/testapp-dependency-missing/appinfo/info.xml
deleted file mode 100644
index c765400a76f..00000000000
--- a/tests/apps/testapp-dependency-missing/appinfo/info.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<info>
- <id>testapp-infoxml-version</id>
- <version>1.2.3</version>
- <author>Jane</author>
- <description>A b c</description>
- <licence>Abc</licence>
- <name>Test app</name>
-</info>
diff --git a/tests/apps/testapp-infoxml/appinfo/info.xml b/tests/apps/testapp-infoxml/appinfo/info.xml
deleted file mode 100644
index d4df1c3cd3f..00000000000
--- a/tests/apps/testapp-infoxml/appinfo/info.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<info>
- <id>testapp-infoxml</id>
- <version>1.2.3</version>
- <author>Jane</author>
- <description>A b c</description>
- <licence>Abc</licence>
- <name>Test app</name>
- <dependencies>
- <nextcloud min-version="12.0" max-version="12.0"/>
- </dependencies>
-</info>
diff --git a/tests/apps/testapp-name-missing/appinfo/info.xml b/tests/apps/testapp-name-missing/appinfo/info.xml
deleted file mode 100644
index 591c4361899..00000000000
--- a/tests/apps/testapp-name-missing/appinfo/info.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<info>
- <id>testapp-version</id>
- <version>1.1.1</version>
- <author>Jane</author>
- <description>A b c</description>
- <licence>Abc</licence>
- <dependencies>
- <nextcloud min-version="12.0" max-version="12.0"/>
- </dependencies>
-</info>
diff --git a/tests/apps/testapp-version/appinfo/info.xml b/tests/apps/testapp-version/appinfo/info.xml
deleted file mode 100644
index 28e2475800f..00000000000
--- a/tests/apps/testapp-version/appinfo/info.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<info>
- <id>testapp-version</id>
- <author>Jane</author>
- <description>A b c</description>
- <licence>Abc</licence>
- <name>Test app</name>
- <dependencies>
- <nextcloud min-version="12.0" max-version="12.0"/>
- </dependencies>
-</info>
diff --git a/tests/apps/testapp-version/appinfo/version b/tests/apps/testapp-version/appinfo/version
deleted file mode 100644
index 0495c4a88ca..00000000000
--- a/tests/apps/testapp-version/appinfo/version
+++ /dev/null
@@ -1 +0,0 @@
-1.2.3
diff --git a/tests/apps/testapp_dependency_missing/appinfo/info.xml b/tests/apps/testapp_dependency_missing/appinfo/info.xml
new file mode 100644
index 00000000000..b0ca188aefc
--- /dev/null
+++ b/tests/apps/testapp_dependency_missing/appinfo/info.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>testapp_infoxml</id>
+ <name>Test app</name>
+ <summary>A b c</summary>
+ <description>A b c</description>
+ <version>1.2.3</version>
+ <licence>agpl</licence>
+ <author>Jane</author>
+ <category>games</category>
+ <bugs>https://example.org</bugs>
+</info>
diff --git a/tests/apps/testapp_infoxml/appinfo/info.xml b/tests/apps/testapp_infoxml/appinfo/info.xml
new file mode 100644
index 00000000000..b7575687fe5
--- /dev/null
+++ b/tests/apps/testapp_infoxml/appinfo/info.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>testapp_infoxml</id>
+ <name>Test app</name>
+ <summary>A b c</summary>
+ <description>A b c</description>
+ <version>1.2.3</version>
+ <licence>agpl</licence>
+ <author>Jane</author>
+ <category>games</category>
+ <bugs>https://example.org</bugs>
+ <dependencies>
+ <nextcloud min-version="12.0" max-version="12.0"/>
+ </dependencies>
+</info>
diff --git a/tests/apps/testapp_name_missing/appinfo/info.xml b/tests/apps/testapp_name_missing/appinfo/info.xml
new file mode 100644
index 00000000000..872c8752c75
--- /dev/null
+++ b/tests/apps/testapp_name_missing/appinfo/info.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>testapp_name_missing</id>
+ <summary>A b c</summary>
+ <description>A b c</description>
+ <version>1.2.3</version>
+ <licence>agpl</licence>
+ <author>Jane</author>
+ <category>games</category>
+ <bugs>https://example.org</bugs>
+ <dependencies>
+ <nextcloud min-version="12.0" max-version="12.0"/>
+ </dependencies>
+</info>
diff --git a/tests/apps/testapp_version/appinfo/info.xml b/tests/apps/testapp_version/appinfo/info.xml
new file mode 100644
index 00000000000..3a48fccd45f
--- /dev/null
+++ b/tests/apps/testapp_version/appinfo/info.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>testapp_version</id>
+ <name>Test app</name>
+ <summary>A b c</summary>
+ <description>A b c</description>
+ <licence>agpl</licence>
+ <author>Jane</author>
+ <category>games</category>
+ <bugs>https://example.org</bugs>
+ <dependencies>
+ <nextcloud min-version="12.0" max-version="12.0"/>
+ </dependencies>
+</info>
diff --git a/tests/lib/App/CodeChecker/InfoCheckerTest.php b/tests/lib/App/CodeChecker/InfoCheckerTest.php
index 760d9880739..3128f902f47 100644
--- a/tests/lib/App/CodeChecker/InfoCheckerTest.php
+++ b/tests/lib/App/CodeChecker/InfoCheckerTest.php
@@ -44,19 +44,21 @@ class InfoCheckerTest extends TestCase {
protected function setUp() {
parent::setUp();
- $this->infoChecker = new InfoChecker(new InfoParser());
+ $this->infoChecker = new InfoChecker();
}
public function appInfoData() {
return [
- ['testapp-infoxml', []],
- ['testapp-version', [['type' => 'mandatoryFieldMissing', 'field' => 'version']]],
- ['testapp-dependency-missing', [
- ['type' => 'missingRequirement', 'field' => 'min'],
- ['type' => 'missingRequirement', 'field' => 'max'],
- ['type' => 'mandatoryFieldMissing', 'field' => 'dependencies'],
+ ['testapp_infoxml', []],
+ ['testapp_version', [
+ ['type' => 'parseError', 'field' => 'Element \'licence\': This element is not expected. Expected is one of ( description, version ).' . "\n"],
+ ]],
+ ['testapp_dependency_missing', [
+ ['type' => 'parseError', 'field' => 'Element \'info\': Missing child element(s). Expected is one of ( repository, screenshot, dependencies ).' . "\n"],
+ ]],
+ ['testapp_name_missing', [
+ ['type' => 'parseError', 'field' => 'Element \'summary\': This element is not expected. Expected is ( name ).' . "\n"],
]],
- ['testapp-name-missing', [['type' => 'mandatoryFieldMissing', 'field' => 'name']]],
];
}
@@ -68,6 +70,7 @@ class InfoCheckerTest extends TestCase {
*/
public function testApps($appId, $expectedErrors) {
$errors = $this->infoChecker->analyse($appId);
+ libxml_clear_errors();
$this->assertEquals($expectedErrors, $errors);
}