2024-07-17 10:49:11 -01:00
< ? 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 ;
2024-07-18 10:35:48 -01:00
use OC\Migration\MetadataManager ;
use OC\Updater\ReleaseMetadata ;
2024-07-17 10:49:11 -01:00
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 ;
2024-07-26 16:35:51 -01:00
/**
* @ since 30.0 . 0
*/
2024-07-17 10:49:11 -01:00
class PreviewCommand extends Command {
2024-07-18 10:35:48 -01:00
private bool $initiated = false ;
2024-07-17 10:49:11 -01:00
public function __construct (
2024-07-18 10:35:48 -01:00
private readonly MetadataManager $metadataManager ,
private readonly ReleaseMetadata $releaseMetadata ,
2024-07-17 10:49:11 -01:00
) {
parent :: __construct ();
}
2024-07-18 10:35:48 -01:00
protected function configure () : void {
2024-07-17 10:49:11 -01:00
$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' );
2024-07-18 10:35:48 -01:00
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 );
}
2024-07-17 10:49:11 -01:00
2024-07-18 10:35:48 -01:00
$parsed = $this -> metadataManager -> getMigrationsAttributesFromReleaseMetadata ( $metadata [ 'migrations' ] ? ? [], true );
2024-07-17 10:49:11 -01:00
$table = new Table ( $output );
2024-07-18 10:35:48 -01:00
$this -> displayMigrations ( $table , 'core' , $parsed [ 'core' ] ? ? []);
foreach ( $parsed [ 'apps' ] as $appId => $migrations ) {
if ( ! empty ( $migrations )) {
$this -> displayMigrations ( $table , $appId , $migrations );
}
}
2024-07-17 10:49:11 -01:00
$table -> render ();
2024-08-06 22:22:38 -01:00
$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>' );
}
2024-07-17 10:49:11 -01:00
return 0 ;
}
private function displayMigrations ( Table $table , string $appId , array $data ) : void {
2024-07-18 10:35:48 -01:00
if ( empty ( $data )) {
return ;
}
if ( $this -> initiated ) {
$table -> addRow ( new TableSeparator ());
}
$this -> initiated = true ;
2024-07-17 10:49:11 -01:00
$table -> addRow (
[
new TableCell (
$appId ,
[
'colspan' => 2 ,
'style' => new TableCellStyle ([ 'cellFormat' => '<info>%s</info>' ])
]
)
]
) -> addRow ( new TableSeparator ());
2024-07-18 10:35:48 -01:00
/** @var MigrationAttribute[] $attributes */
2024-07-17 10:49:11 -01:00
foreach ( $data as $migration => $attributes ) {
$attributesStr = [];
2024-08-06 22:22:38 -01:00
if ( empty ( $attributes )) {
$attributesStr [] = '<comment>(metadata not set)</comment>' ;
}
2024-07-17 10:49:11 -01:00
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 )]);
}
}
}