Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
MigrateConfig
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 4
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 initServices
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 fatalStatus
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace MediaWiki\Extension\CommunityConfiguration\Maintenance;
4
5use Maintenance;
6use MediaWiki\Context\RequestContext;
7use MediaWiki\Extension\CommunityConfiguration\CommunityConfigurationServices;
8use MediaWiki\Extension\CommunityConfiguration\Provider\ConfigurationProviderFactory;
9use MediaWiki\Extension\CommunityConfiguration\Schema\SchemaMigrator;
10use MediaWiki\Permissions\UltimateAuthority;
11use MediaWiki\Status\StatusFormatter;
12use MediaWiki\User\User;
13use StatusValue;
14
15$IP = getenv( 'MW_INSTALL_PATH' );
16if ( $IP === false ) {
17    $IP = __DIR__ . '/../../..';
18}
19require_once "$IP/maintenance/Maintenance.php";
20
21class MigrateConfig extends Maintenance {
22
23    private StatusFormatter $statusFormatter;
24    private ConfigurationProviderFactory $providerFactory;
25    private SchemaMigrator $schemaMigrator;
26
27    public function __construct() {
28        parent::__construct();
29        $this->requireExtension( 'CommunityConfiguration' );
30
31        $this->addDescription( 'Migrate configuration provider to a different version' );
32        $this->addArg(
33            'provider',
34            'ID of the provider to upgrade'
35        );
36        $this->addOption(
37            'version',
38            'Version to upgrade to (defaults to newest available)',
39            false,
40            true
41        );
42        $this->addOption(
43            'dry-run',
44            'Do not actually save the edit'
45        );
46    }
47
48    private function initServices(): void {
49        $ccServices = CommunityConfigurationServices::wrap( $this->getServiceContainer() );
50        $this->statusFormatter = $this->getServiceContainer()->getFormatterFactory()->getStatusFormatter(
51            RequestContext::getMain()
52        );
53        $this->providerFactory = $ccServices->getConfigurationProviderFactory();
54        $this->schemaMigrator = $ccServices->getSchemaMigrator();
55    }
56
57    private function fatalStatus( StatusValue $status, string $headline ) {
58        $this->fatalError(
59            "$headline.\n\n== Error details ==\n"
60            . $this->statusFormatter->getWikiText( $status )
61        );
62    }
63
64    /**
65     * @inheritDoc
66     */
67    public function execute() {
68        $this->initServices();
69
70        $provider = $this->providerFactory->newProvider( $this->getArg( 'provider' ) );
71
72        $validator = $provider->getValidator();
73        if ( !$validator->areSchemasSupported() ) {
74            $this->fatalError( 'Provider ' . $provider->getId() . ' does not support schemas.' );
75        }
76
77        $targetVersion = $this->getOption( 'version' ) ?? $validator->getSchemaVersion();
78
79        // NOTE: We will be writing the data back; ensure we are not running into any cache
80        // issues by purging it.
81        $provider->getStore()->invalidate();
82        $conversionStatus = $this->schemaMigrator->convertDataToVersion(
83            $provider,
84            $targetVersion
85        );
86
87        if ( !$conversionStatus->isOK() ) {
88            $this->fatalStatus( $conversionStatus, 'Failed to convert the config data' );
89        }
90
91        if ( $this->hasOption( 'dry-run' ) ) {
92            $this->output( 'Would save:' . PHP_EOL );
93            $this->output( var_export( $conversionStatus->getValue(), true ) . PHP_EOL );
94            return;
95        }
96
97        $status = $provider->storeValidConfiguration(
98            $conversionStatus->getValue(),
99            new UltimateAuthority( User::newSystemUser( User::MAINTENANCE_SCRIPT_USER ) ),
100            'Migrating data to new format'
101        );
102        if ( !$status->isOK() ) {
103            $this->fatalStatus( $status, 'Failed to update the store with new config' );
104        }
105
106        $this->output( 'All done!' . PHP_EOL );
107    }
108}
109
110$maintClass = MigrateConfig::class;
111require_once RUN_MAINTENANCE_IF_MAIN;