PreviewCommand.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\Core\Command\Db\Migrations;
  8. use OC\Migration\MetadataManager;
  9. use OC\Updater\ReleaseMetadata;
  10. use OCP\Migration\Attributes\MigrationAttribute;
  11. use Symfony\Component\Console\Command\Command;
  12. use Symfony\Component\Console\Helper\Table;
  13. use Symfony\Component\Console\Helper\TableCell;
  14. use Symfony\Component\Console\Helper\TableCellStyle;
  15. use Symfony\Component\Console\Helper\TableSeparator;
  16. use Symfony\Component\Console\Input\InputArgument;
  17. use Symfony\Component\Console\Input\InputInterface;
  18. use Symfony\Component\Console\Output\OutputInterface;
  19. /**
  20. * @since 30.0.0
  21. */
  22. class PreviewCommand extends Command {
  23. private bool $initiated = false;
  24. public function __construct(
  25. private readonly MetadataManager $metadataManager,
  26. private readonly ReleaseMetadata $releaseMetadata,
  27. ) {
  28. parent::__construct();
  29. }
  30. protected function configure(): void {
  31. $this
  32. ->setName('migrations:preview')
  33. ->setDescription('Get preview of available DB migrations in case of initiating an upgrade')
  34. ->addArgument('version', InputArgument::REQUIRED, 'The destination version number');
  35. parent::configure();
  36. }
  37. public function execute(InputInterface $input, OutputInterface $output): int {
  38. $version = $input->getArgument('version');
  39. if (filter_var($version, FILTER_VALIDATE_URL)) {
  40. $metadata = $this->releaseMetadata->downloadMetadata($version);
  41. } elseif (str_starts_with($version, '/')) {
  42. $metadata = json_decode(file_get_contents($version), true, flags: JSON_THROW_ON_ERROR);
  43. } else {
  44. $metadata = $this->releaseMetadata->getMetadata($version);
  45. }
  46. $parsed = $this->metadataManager->getMigrationsAttributesFromReleaseMetadata($metadata['migrations'] ?? [], true);
  47. $table = new Table($output);
  48. $this->displayMigrations($table, 'core', $parsed['core'] ?? []);
  49. foreach ($parsed['apps'] as $appId => $migrations) {
  50. if (!empty($migrations)) {
  51. $this->displayMigrations($table, $appId, $migrations);
  52. }
  53. }
  54. $table->render();
  55. $unsupportedApps = $this->metadataManager->getUnsupportedApps($metadata['migrations']);
  56. if (!empty($unsupportedApps)) {
  57. $output->writeln('');
  58. $output->writeln('Those apps are not supporting metadata yet and might initiate migrations on upgrade: <info>' . implode(', ', $unsupportedApps) . '</info>');
  59. }
  60. return 0;
  61. }
  62. private function displayMigrations(Table $table, string $appId, array $data): void {
  63. if (empty($data)) {
  64. return;
  65. }
  66. if ($this->initiated) {
  67. $table->addRow(new TableSeparator());
  68. }
  69. $this->initiated = true;
  70. $table->addRow(
  71. [
  72. new TableCell(
  73. $appId,
  74. [
  75. 'colspan' => 2,
  76. 'style' => new TableCellStyle(['cellFormat' => '<info>%s</info>'])
  77. ]
  78. )
  79. ]
  80. )->addRow(new TableSeparator());
  81. /** @var MigrationAttribute[] $attributes */
  82. foreach ($data as $migration => $attributes) {
  83. $attributesStr = [];
  84. if (empty($attributes)) {
  85. $attributesStr[] = '<comment>(metadata not set)</comment>';
  86. }
  87. foreach ($attributes as $attribute) {
  88. $definition = '<info>' . $attribute->definition() . '</info>';
  89. $definition .= empty($attribute->getDescription()) ? '' : "\n " . $attribute->getDescription();
  90. $definition .= empty($attribute->getNotes()) ? '' : "\n <comment>" . implode("</comment>\n <comment>", $attribute->getNotes()) . '</comment>';
  91. $attributesStr[] = $definition;
  92. }
  93. $table->addRow([$migration, implode("\n", $attributesStr)]);
  94. }
  95. }
  96. }