diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2024-07-18 10:35:48 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2024-07-29 12:44:52 -0100 |
commit | 79e60148799eee50b08c5edf07b91ba8428642fd (patch) | |
tree | 8ce10b3bc67ebeadab7af3d43bab3970fbab08ec /core/Command/Db | |
parent | 88cfab4f329c7ee1f360be1ad7d90cf767da3720 (diff) | |
download | nextcloud-server-79e60148799eee50b08c5edf07b91ba8428642fd.tar.gz nextcloud-server-79e60148799eee50b08c5edf07b91ba8428642fd.zip |
feat(upgrade): release metadata
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'core/Command/Db')
-rw-r--r-- | core/Command/Db/Migrations/GenerateMetadataCommand.php | 40 | ||||
-rw-r--r-- | core/Command/Db/Migrations/PreviewCommand.php | 121 |
2 files changed, 37 insertions, 124 deletions
diff --git a/core/Command/Db/Migrations/GenerateMetadataCommand.php b/core/Command/Db/Migrations/GenerateMetadataCommand.php index addcb59e68b..64840bea230 100644 --- a/core/Command/Db/Migrations/GenerateMetadataCommand.php +++ b/core/Command/Db/Migrations/GenerateMetadataCommand.php @@ -8,23 +8,21 @@ declare(strict_types=1); */ namespace OC\Core\Command\Db\Migrations; -use OC\DB\Connection; -use OC\DB\MigrationService; +use OC\Migration\MetadataManager; use OCP\App\IAppManager; -use ReflectionClass; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class GenerateMetadataCommand extends Command { public function __construct( - private readonly Connection $connection, + private readonly MetadataManager $metadataManager, private readonly IAppManager $appManager, ) { parent::__construct(); } - protected function configure() { + protected function configure(): void { $this->setName('migrations:generate-metadata') ->setHidden(true) ->setDescription('Generate metadata from DB migrations - internal and should not be used'); @@ -45,7 +43,9 @@ class GenerateMetadataCommand extends Command { return 0; } - private function extractMigrationMetadata(): array { + + + public function extractMigrationMetadata(): array { return [ 'core' => $this->extractMigrationMetadataFromCore(), 'apps' => $this->extractMigrationMetadataFromApps() @@ -53,7 +53,7 @@ class GenerateMetadataCommand extends Command { } private function extractMigrationMetadataFromCore(): array { - return $this->extractMigrationAttributes('core'); + return $this->metadataManager->extractMigrationAttributes('core'); } /** @@ -72,35 +72,11 @@ class GenerateMetadataCommand extends Command { if (!$alreadyLoaded) { $this->appManager->loadApp($appId); } - $metadata[$appId] = $this->extractMigrationAttributes($appId); + $metadata[$appId] = $this->metadataManager->extractMigrationAttributes($appId); if (!$alreadyLoaded) { $this->appManager->disableApp($appId); } } return $metadata; } - - /** - * We get all migrations from an app, and for each migration we extract attributes - * - * @param string $appId - * - * @return array - * @throws \Exception - */ - private function extractMigrationAttributes(string $appId): array { - $ms = new MigrationService($appId, $this->connection); - - $metadata = []; - foreach($ms->getAvailableVersions() as $version) { - $metadata[$version] = []; - $class = new ReflectionClass($ms->createInstance($version)); - $attributes = $class->getAttributes(); - foreach ($attributes as $attribute) { - $metadata[$version][] = $attribute->newInstance(); - } - } - - return $metadata; - } } diff --git a/core/Command/Db/Migrations/PreviewCommand.php b/core/Command/Db/Migrations/PreviewCommand.php index 17d1d8b01ec..b1881a0c42c 100644 --- a/core/Command/Db/Migrations/PreviewCommand.php +++ b/core/Command/Db/Migrations/PreviewCommand.php @@ -8,12 +8,9 @@ declare(strict_types=1); */ namespace OC\Core\Command\Db\Migrations; -use OC\DB\Connection; -use OC\DB\MigrationService; -use OCP\Migration\Attributes\GenericMigrationAttribute; +use OC\Migration\MetadataManager; +use OC\Updater\ReleaseMetadata; use OCP\Migration\Attributes\MigrationAttribute; -use OCP\Migration\Exceptions\AttributeException; -use Psr\Log\LoggerInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Helper\TableCell; @@ -24,14 +21,15 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class PreviewCommand extends Command { + private bool $initiated = false; public function __construct( - private readonly Connection $connection, - private readonly LoggerInterface $logger, + private readonly MetadataManager $metadataManager, + private readonly ReleaseMetadata $releaseMetadata, ) { parent::__construct(); } - protected function configure() { + protected function configure(): void { $this ->setName('migrations:preview') ->setDescription('Get preview of available DB migrations in case of initiating an upgrade') @@ -42,21 +40,37 @@ class PreviewCommand extends Command { 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); + } - $metadata = $this->getMetadata($version); - $parsed = $this->getMigrationsAttributes($metadata); + $parsed = $this->metadataManager->getMigrationsAttributesFromReleaseMetadata($metadata['migrations'] ?? [], true); $table = new Table($output); - $this->displayMigrations($table, 'core', $parsed['core']); - + $this->displayMigrations($table, 'core', $parsed['core'] ?? []); + foreach ($parsed['apps'] as $appId => $migrations) { + if (!empty($migrations)) { + $this->displayMigrations($table, $appId, $migrations); + } + } $table->render(); return 0; } private function displayMigrations(Table $table, string $appId, array $data): void { - $done = $this->getDoneMigrations($appId); - $done = array_diff($done, ['30000Date20240429122720']); + if (empty($data)) { + return; + } + + if ($this->initiated) { + $table->addRow(new TableSeparator()); + } + $this->initiated = true; $table->addRow( [ @@ -70,13 +84,9 @@ class PreviewCommand extends Command { ] )->addRow(new TableSeparator()); + /** @var MigrationAttribute[] $attributes */ foreach($data as $migration => $attributes) { - if (in_array($migration, $done)) { - continue; - } - $attributesStr = []; - /** @var MigrationAttribute[] $attributes */ foreach($attributes as $attribute) { $definition = '<info>' . $attribute->definition() . "</info>"; $definition .= empty($attribute->getDescription()) ? '' : "\n " . $attribute->getDescription(); @@ -85,78 +95,5 @@ class PreviewCommand extends Command { } $table->addRow([$migration, implode("\n", $attributesStr)]); } - - } - - - - - - private function getMetadata(string $version): array { - $metadata = json_decode(file_get_contents('/tmp/nextcloud-' . $version . '.metadata'), true); - if (!$metadata) { - throw new \Exception(); - } - return $metadata['migrations'] ?? []; - } - - private function getDoneMigrations(string $appId): array { - $ms = new MigrationService($appId, $this->connection); - return $ms->getMigratedVersions(); - } - - private function getMigrationsAttributes(array $metadata): array { - $appsAttributes = []; - foreach (array_keys($metadata['apps']) as $appId) { - $appsAttributes[$appId] = $this->parseMigrations($metadata['apps'][$appId] ?? []); - } - - return [ - 'core' => $this->parseMigrations($metadata['core'] ?? []), - 'apps' => $appsAttributes - ]; - } - - private function parseMigrations(array $migrations): array { - $parsed = []; - foreach (array_keys($migrations) as $entry) { - $items = $migrations[$entry]; - $parsed[$entry] = []; - foreach ($items as $item) { - try { - $parsed[$entry][] = $this->createAttribute($item); - } catch (AttributeException $e) { - $this->logger->warning( - 'exception while trying to create attribute', - ['exception' => $e, 'item' => json_encode($item)] - ); - $parsed[$entry][] = new GenericMigrationAttribute($item); - } - } - } - - return $parsed; - } - - /** - * @param array $item - * - * @return MigrationAttribute|null - * @throws AttributeException - */ - private function createAttribute(array $item): ?MigrationAttribute { - $class = $item['class'] ?? ''; - $namespace = 'OCP\Migration\Attributes\\'; - if (!str_starts_with($class, $namespace) - || !ctype_alpha(substr($class, strlen($namespace)))) { - throw new AttributeException('class name does not looks valid'); - } - - try { - $attribute = new $class(); - return $attribute->import($item); - } catch (\Error) { - throw new AttributeException('cannot import Attribute'); - } } } |