aboutsummaryrefslogtreecommitdiffstats
path: root/core/Command/Db/Migrations
diff options
context:
space:
mode:
Diffstat (limited to 'core/Command/Db/Migrations')
-rw-r--r--core/Command/Db/Migrations/ExecuteCommand.php47
-rw-r--r--core/Command/Db/Migrations/GenerateCommand.php107
-rw-r--r--core/Command/Db/Migrations/GenerateFromSchemaFileCommand.php206
-rw-r--r--core/Command/Db/Migrations/GenerateMetadataCommand.php79
-rw-r--r--core/Command/Db/Migrations/MigrateCommand.php35
-rw-r--r--core/Command/Db/Migrations/PreviewCommand.php111
-rw-r--r--core/Command/Db/Migrations/StatusCommand.php34
7 files changed, 275 insertions, 344 deletions
diff --git a/core/Command/Db/Migrations/ExecuteCommand.php b/core/Command/Db/Migrations/ExecuteCommand.php
index cc3f7d67fc0..a89072c1ad1 100644
--- a/core/Command/Db/Migrations/ExecuteCommand.php
+++ b/core/Command/Db/Migrations/ExecuteCommand.php
@@ -1,26 +1,10 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
- * @copyright Copyright (c) 2017, ownCloud GmbH
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2017 ownCloud GmbH
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
-
namespace OC\Core\Command\Db\Migrations;
use OC\DB\Connection;
@@ -35,23 +19,10 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ExecuteCommand extends Command implements CompletionAwareInterface {
-
- /** @var Connection */
- private $connection;
-
- /** @var IConfig */
- private $config;
-
- /**
- * ExecuteCommand constructor.
- *
- * @param Connection $connection
- * @param IConfig $config
- */
- public function __construct(Connection $connection, IConfig $config) {
- $this->connection = $connection;
- $this->config = $config;
-
+ public function __construct(
+ private Connection $connection,
+ private IConfig $config,
+ ) {
parent::__construct();
}
@@ -79,7 +50,7 @@ class ExecuteCommand extends Command implements CompletionAwareInterface {
$olderVersions = $ms->getMigratedVersions();
$olderVersions[] = '0';
$olderVersions[] = 'prev';
- if (in_array($version, $olderVersions, true)) {
+ if (in_array($version, $olderVersions, true)) {
$output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
return 1;
}
diff --git a/core/Command/Db/Migrations/GenerateCommand.php b/core/Command/Db/Migrations/GenerateCommand.php
index 48fc59e77fb..a75280fa8b1 100644
--- a/core/Command/Db/Migrations/GenerateCommand.php
+++ b/core/Command/Db/Migrations/GenerateCommand.php
@@ -1,102 +1,86 @@
<?php
+
/**
- * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
- * @copyright Copyright (c) 2017, ownCloud GmbH
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2017 ownCloud GmbH
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
-
namespace OC\Core\Command\Db\Migrations;
use OC\DB\Connection;
use OC\DB\MigrationService;
use OC\Migration\ConsoleOutput;
use OCP\App\IAppManager;
+use OCP\Util;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
class GenerateCommand extends Command implements CompletionAwareInterface {
- protected static $_templateSimple =
- '<?php
+ protected static $_templateSimple
+ = '<?php
declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: {{year}} Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
namespace {{namespace}};
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
+use Override;
/**
- * Auto-generated migration step: Please modify to your needs!
+ * FIXME Auto-generated migration step: Please modify to your needs!
*/
class {{classname}} extends SimpleMigrationStep {
/**
* @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
+ #[Override]
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
}
/**
* @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
+ #[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
{{schemabody}}
}
/**
* @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
+ #[Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
}
}
';
- /** @var Connection */
- protected $connection;
-
- /** @var IAppManager */
- protected $appManager;
-
- /**
- * @param Connection $connection
- * @param IAppManager $appManager
- */
- public function __construct(Connection $connection, IAppManager $appManager) {
- $this->connection = $connection;
- $this->appManager = $appManager;
-
+ public function __construct(
+ protected Connection $connection,
+ protected IAppManager $appManager,
+ ) {
parent::__construct();
}
@@ -114,11 +98,42 @@ class {{classname}} extends SimpleMigrationStep {
$appName = $input->getArgument('app');
$version = $input->getArgument('version');
- if (!preg_match('/^\d{1,16}$/',$version)) {
+ if (!preg_match('/^\d{1,16}$/', $version)) {
$output->writeln('<error>The given version is invalid. Only 0-9 are allowed (max. 16 digits)</error>');
return 1;
}
+ if ($appName === 'core') {
+ $fullVersion = implode('.', Util::getVersion());
+ } else {
+ try {
+ $fullVersion = $this->appManager->getAppVersion($appName, false);
+ } catch (\Throwable $e) {
+ $fullVersion = '';
+ }
+ }
+
+ if ($fullVersion) {
+ [$major, $minor] = explode('.', $fullVersion);
+ $shouldVersion = (string)((int)$major * 1000 + (int)$minor);
+ if ($version !== $shouldVersion) {
+ $output->writeln('<comment>Unexpected migration version for current version: ' . $fullVersion . '</comment>');
+ $output->writeln('<comment> - Pattern: XYYY </comment>');
+ $output->writeln('<comment> - Expected: ' . $shouldVersion . '</comment>');
+ $output->writeln('<comment> - Actual: ' . $version . '</comment>');
+
+ if ($input->isInteractive()) {
+ /** @var QuestionHelper $helper */
+ $helper = $this->getHelper('question');
+ $question = new ConfirmationQuestion('Continue with your given version? (y/n) [n] ', false);
+
+ if (!$helper->ask($input, $output, $question)) {
+ return 1;
+ }
+ }
+ }
+ }
+
$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
$date = date('YmdHis');
@@ -144,7 +159,7 @@ class {{classname}} extends SimpleMigrationStep {
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app') {
- $allApps = \OC_App::getAllApps();
+ $allApps = $this->appManager->getAllAppsInAppsFolders();
return array_diff($allApps, \OC_App::getEnabledApps(true, true));
}
@@ -174,11 +189,13 @@ class {{classname}} extends SimpleMigrationStep {
'{{namespace}}',
'{{classname}}',
'{{schemabody}}',
+ '{{year}}',
];
$replacements = [
$ms->getMigrationsNamespace(),
$className,
$schemaBody,
+ date('Y')
];
$code = str_replace($placeHolders, $replacements, self::$_templateSimple);
$dir = $ms->getMigrationsDirectory();
@@ -187,7 +204,7 @@ class {{classname}} extends SimpleMigrationStep {
$path = $dir . '/' . $className . '.php';
if (file_put_contents($path, $code) === false) {
- throw new RuntimeException('Failed to generate new migration step.');
+ throw new RuntimeException('Failed to generate new migration step. Could not write to ' . $path);
}
return $path;
diff --git a/core/Command/Db/Migrations/GenerateFromSchemaFileCommand.php b/core/Command/Db/Migrations/GenerateFromSchemaFileCommand.php
deleted file mode 100644
index 9101957a97c..00000000000
--- a/core/Command/Db/Migrations/GenerateFromSchemaFileCommand.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Maxence Lange <maxence@artificial-owl.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace OC\Core\Command\Db\Migrations;
-
-use Doctrine\DBAL\Schema\Schema;
-use OC\DB\Connection;
-use OC\DB\MDB2SchemaReader;
-use OC\DB\MigrationService;
-use OC\Migration\ConsoleOutput;
-use OCP\App\IAppManager;
-use OCP\IConfig;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-
-class GenerateFromSchemaFileCommand extends GenerateCommand {
-
- /** @var IConfig */
- protected $config;
-
- public function __construct(IConfig $config, IAppManager $appManager, Connection $connection) {
- parent::__construct($connection, $appManager);
- $this->config = $config;
- }
-
-
- protected function configure() {
- parent::configure();
-
- $this->setName('migrations:generate-from-schema');
- }
-
- public function execute(InputInterface $input, OutputInterface $output): int {
- $appName = $input->getArgument('app');
- $version = $input->getArgument('version');
-
- if (!preg_match('/^\d{1,16}$/',$version)) {
- $output->writeln('<error>The given version is invalid. Only 0-9 are allowed (max. 16 digits)</error>');
- return 1;
- }
-
- $schemaFile = $this->appManager->getAppPath($appName) . '/appinfo/database.xml';
- if (!file_exists($schemaFile)) {
- $output->writeln('<error>App ' . $appName . ' does not have a database.xml file</error>');
- return 2;
- }
-
- $reader = new MDB2SchemaReader($this->config, $this->connection->getDatabasePlatform());
- $schema = new Schema();
- $reader->loadSchemaFromFile($schemaFile, $schema);
-
- $schemaBody = $this->schemaToMigration($schema);
-
- $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
-
- $date = date('YmdHis');
- $path = $this->generateMigration($ms, 'Version' . $version . 'Date' . $date, $schemaBody);
-
- $output->writeln("New migration class has been generated to <info>$path</info>");
- return 0;
- }
-
- /**
- * @param Schema $schema
- * @return string
- */
- protected function schemaToMigration(Schema $schema) {
- $content = <<<'EOT'
- /** @var ISchemaWrapper $schema */
- $schema = $schemaClosure();
-
-EOT;
-
- foreach ($schema->getTables() as $table) {
- $content .= str_replace('{{table-name}}', substr($table->getName(), 3), <<<'EOT'
-
- if (!$schema->hasTable('{{table-name}}')) {
- $table = $schema->createTable('{{table-name}}');
-
-EOT
- );
-
- foreach ($table->getColumns() as $column) {
- $content .= str_replace(['{{name}}', '{{type}}'], [$column->getName(), $column->getType()->getName()], <<<'EOT'
- $table->addColumn('{{name}}', '{{type}}', [
-
-EOT
- );
- if ($column->getAutoincrement()) {
- $content .= <<<'EOT'
- 'autoincrement' => true,
-
-EOT;
- }
- $content .= str_replace('{{notnull}}', $column->getNotnull() ? 'true' : 'false', <<<'EOT'
- 'notnull' => {{notnull}},
-
-EOT
- );
- if ($column->getLength() !== null) {
- $content .= str_replace('{{length}}', $column->getLength(), <<<'EOT'
- 'length' => {{length}},
-
-EOT
- );
- }
- $default = $column->getDefault();
- if ($default !== null) {
- if (is_string($default)) {
- $default = "'$default'";
- } elseif (is_bool($default)) {
- $default = ($default === true) ? 'true' : 'false';
- }
- $content .= str_replace('{{default}}', $default, <<<'EOT'
- 'default' => {{default}},
-
-EOT
- );
- }
- if ($column->getUnsigned()) {
- $content .= <<<'EOT'
- 'unsigned' => true,
-
-EOT;
- }
-
- $content .= <<<'EOT'
- ]);
-
-EOT;
- }
-
- $content .= <<<'EOT'
-
-EOT;
-
- $primaryKey = $table->getPrimaryKey();
- if ($primaryKey !== null) {
- $content .= str_replace('{{columns}}', implode('\', \'', $primaryKey->getUnquotedColumns()), <<<'EOT'
- $table->setPrimaryKey(['{{columns}}']);
-
-EOT
- );
- }
-
- foreach ($table->getIndexes() as $index) {
- if ($index->isPrimary()) {
- continue;
- }
-
- if ($index->isUnique()) {
- $content .= str_replace(
- ['{{columns}}', '{{name}}'],
- [implode('\', \'', $index->getUnquotedColumns()), $index->getName()],
- <<<'EOT'
- $table->addUniqueIndex(['{{columns}}'], '{{name}}');
-
-EOT
- );
- } else {
- $content .= str_replace(
- ['{{columns}}', '{{name}}'],
- [implode('\', \'', $index->getUnquotedColumns()), $index->getName()],
- <<<'EOT'
- $table->addIndex(['{{columns}}'], '{{name}}');
-
-EOT
- );
- }
- }
-
- $content .= <<<'EOT'
- }
-
-EOT;
- }
-
- $content .= <<<'EOT'
- return $schema;
-EOT;
-
- return $content;
- }
-}
diff --git a/core/Command/Db/Migrations/GenerateMetadataCommand.php b/core/Command/Db/Migrations/GenerateMetadataCommand.php
new file mode 100644
index 00000000000..581259c99df
--- /dev/null
+++ b/core/Command/Db/Migrations/GenerateMetadataCommand.php
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OC\Core\Command\Db\Migrations;
+
+use OC\Migration\MetadataManager;
+use OCP\App\IAppManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @since 30.0.0
+ */
+class GenerateMetadataCommand extends Command {
+ public function __construct(
+ private readonly MetadataManager $metadataManager,
+ private readonly IAppManager $appManager,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure(): void {
+ $this->setName('migrations:generate-metadata')
+ ->setHidden(true)
+ ->setDescription('Generate metadata from DB migrations - internal and should not be used');
+
+ parent::configure();
+ }
+
+ public function execute(InputInterface $input, OutputInterface $output): int {
+ $output->writeln(
+ json_encode(
+ [
+ 'migrations' => $this->extractMigrationMetadata()
+ ],
+ JSON_PRETTY_PRINT
+ )
+ );
+
+ return 0;
+ }
+
+ private function extractMigrationMetadata(): array {
+ return [
+ 'core' => $this->extractMigrationMetadataFromCore(),
+ 'apps' => $this->extractMigrationMetadataFromApps()
+ ];
+ }
+
+ private function extractMigrationMetadataFromCore(): array {
+ return $this->metadataManager->extractMigrationAttributes('core');
+ }
+
+ /**
+ * get all apps and extract attributes
+ *
+ * @return array
+ * @throws \Exception
+ */
+ private function extractMigrationMetadataFromApps(): array {
+ $allApps = $this->appManager->getAllAppsInAppsFolders();
+ $metadata = [];
+ foreach ($allApps as $appId) {
+ // We need to load app before being able to extract Migrations
+ $alreadyLoaded = $this->appManager->isAppLoaded($appId);
+ if (!$alreadyLoaded) {
+ $this->appManager->loadApp($appId);
+ }
+ $metadata[$appId] = $this->metadataManager->extractMigrationAttributes($appId);
+ }
+ return $metadata;
+ }
+}
diff --git a/core/Command/Db/Migrations/MigrateCommand.php b/core/Command/Db/Migrations/MigrateCommand.php
index 218c8aaf518..2e02f031479 100644
--- a/core/Command/Db/Migrations/MigrateCommand.php
+++ b/core/Command/Db/Migrations/MigrateCommand.php
@@ -1,25 +1,10 @@
<?php
+
/**
- * @copyright Copyright (c) 2017, ownCloud GmbH
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2017 ownCloud GmbH
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
-
namespace OC\Core\Command\Db\Migrations;
use OC\DB\Connection;
@@ -33,15 +18,9 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MigrateCommand extends Command implements CompletionAwareInterface {
-
- /** @var Connection */
- private $connection;
-
- /**
- * @param Connection $connection
- */
- public function __construct(Connection $connection) {
- $this->connection = $connection;
+ public function __construct(
+ private Connection $connection,
+ ) {
parent::__construct();
}
diff --git a/core/Command/Db/Migrations/PreviewCommand.php b/core/Command/Db/Migrations/PreviewCommand.php
new file mode 100644
index 00000000000..f5b850fff76
--- /dev/null
+++ b/core/Command/Db/Migrations/PreviewCommand.php
@@ -0,0 +1,111 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OC\Core\Command\Db\Migrations;
+
+use OC\Migration\MetadataManager;
+use OC\Updater\ReleaseMetadata;
+use OCP\Migration\Attributes\MigrationAttribute;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Helper\TableCell;
+use Symfony\Component\Console\Helper\TableCellStyle;
+use Symfony\Component\Console\Helper\TableSeparator;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @since 30.0.0
+ */
+class PreviewCommand extends Command {
+ private bool $initiated = false;
+ public function __construct(
+ private readonly MetadataManager $metadataManager,
+ private readonly ReleaseMetadata $releaseMetadata,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure(): void {
+ $this
+ ->setName('migrations:preview')
+ ->setDescription('Get preview of available DB migrations in case of initiating an upgrade')
+ ->addArgument('version', InputArgument::REQUIRED, 'The destination version number');
+
+ parent::configure();
+ }
+
+ public function execute(InputInterface $input, OutputInterface $output): int {
+ $version = $input->getArgument('version');
+ if (filter_var($version, FILTER_VALIDATE_URL)) {
+ $metadata = $this->releaseMetadata->downloadMetadata($version);
+ } elseif (str_starts_with($version, '/')) {
+ $metadata = json_decode(file_get_contents($version), true, flags: JSON_THROW_ON_ERROR);
+ } else {
+ $metadata = $this->releaseMetadata->getMetadata($version);
+ }
+
+ $parsed = $this->metadataManager->getMigrationsAttributesFromReleaseMetadata($metadata['migrations'] ?? [], true);
+
+ $table = new Table($output);
+ $this->displayMigrations($table, 'core', $parsed['core'] ?? []);
+ foreach ($parsed['apps'] as $appId => $migrations) {
+ if (!empty($migrations)) {
+ $this->displayMigrations($table, $appId, $migrations);
+ }
+ }
+ $table->render();
+
+ $unsupportedApps = $this->metadataManager->getUnsupportedApps($metadata['migrations']);
+ if (!empty($unsupportedApps)) {
+ $output->writeln('');
+ $output->writeln('Those apps are not supporting metadata yet and might initiate migrations on upgrade: <info>' . implode(', ', $unsupportedApps) . '</info>');
+ }
+
+ return 0;
+ }
+
+ private function displayMigrations(Table $table, string $appId, array $data): void {
+ if (empty($data)) {
+ return;
+ }
+
+ if ($this->initiated) {
+ $table->addRow(new TableSeparator());
+ }
+ $this->initiated = true;
+
+ $table->addRow(
+ [
+ new TableCell(
+ $appId,
+ [
+ 'colspan' => 2,
+ 'style' => new TableCellStyle(['cellFormat' => '<info>%s</info>'])
+ ]
+ )
+ ]
+ )->addRow(new TableSeparator());
+
+ /** @var MigrationAttribute[] $attributes */
+ foreach ($data as $migration => $attributes) {
+ $attributesStr = [];
+ if (empty($attributes)) {
+ $attributesStr[] = '<comment>(metadata not set)</comment>';
+ }
+ foreach ($attributes as $attribute) {
+ $definition = '<info>' . $attribute->definition() . '</info>';
+ $definition .= empty($attribute->getDescription()) ? '' : "\n " . $attribute->getDescription();
+ $definition .= empty($attribute->getNotes()) ? '' : "\n <comment>" . implode("</comment>\n <comment>", $attribute->getNotes()) . '</comment>';
+ $attributesStr[] = $definition;
+ }
+ $table->addRow([$migration, implode("\n", $attributesStr)]);
+ }
+ }
+}
diff --git a/core/Command/Db/Migrations/StatusCommand.php b/core/Command/Db/Migrations/StatusCommand.php
index 6c78bcd180c..97ecc76a924 100644
--- a/core/Command/Db/Migrations/StatusCommand.php
+++ b/core/Command/Db/Migrations/StatusCommand.php
@@ -1,27 +1,10 @@
<?php
+
/**
- * @copyright Copyright (c) 2017, ownCloud GmbH
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2017 ownCloud GmbH
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
-
namespace OC\Core\Command\Db\Migrations;
use OC\DB\Connection;
@@ -35,12 +18,9 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class StatusCommand extends Command implements CompletionAwareInterface {
-
- /** @var Connection */
- private $connection;
-
- public function __construct(Connection $connection) {
- $this->connection = $connection;
+ public function __construct(
+ private Connection $connection,
+ ) {
parent::__construct();
}