aboutsummaryrefslogtreecommitdiffstats
path: root/core/Command/Db
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2024-07-18 10:35:48 -0100
committerMaxence Lange <maxence@artificial-owl.com>2024-07-29 12:44:52 -0100
commit79e60148799eee50b08c5edf07b91ba8428642fd (patch)
tree8ce10b3bc67ebeadab7af3d43bab3970fbab08ec /core/Command/Db
parent88cfab4f329c7ee1f360be1ad7d90cf767da3720 (diff)
downloadnextcloud-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.php40
-rw-r--r--core/Command/Db/Migrations/PreviewCommand.php121
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');
- }
}
}