MediaWiki  master
updateExtensionJsonSchema.php
Go to the documentation of this file.
1 <?php
2 
3 use Composer\Semver\VersionParser;
4 
5 require_once __DIR__ . '/Maintenance.php';
6 
8 
9  public function __construct() {
10  parent::__construct();
11  $this->addDescription( 'Updates extension.json files to the latest manifest_version' );
12  $this->addArg( 'path', 'Location to the extension.json or skin.json you wish to convert',
13  /* $required = */ true );
14  }
15 
16  public function execute() {
17  $filename = $this->getArg( 0 );
18  if ( !is_readable( $filename ) ) {
19  $this->fatalError( "Error: Unable to read $filename" );
20  }
21 
22  $json = FormatJson::decode( file_get_contents( $filename ), true );
23  if ( !is_array( $json ) ) {
24  $this->fatalError( "Error: Invalid JSON" );
25  }
26 
27  if ( !isset( $json['manifest_version'] ) ) {
28  $json['manifest_version'] = 1;
29  }
30 
31  if ( $json['manifest_version'] == ExtensionRegistry::MANIFEST_VERSION ) {
32  $this->output( "Already at the latest version: {$json['manifest_version']}\n" );
33  return;
34  }
35 
36  while ( $json['manifest_version'] !== ExtensionRegistry::MANIFEST_VERSION ) {
37  $json['manifest_version'] += 1;
38  $func = "updateTo{$json['manifest_version']}";
39  $this->$func( $json );
40  }
41 
42  $this->updateRequiredMwVersion( $json );
43 
44  file_put_contents( $filename, FormatJson::encode( $json, "\t", FormatJson::ALL_OK ) . "\n" );
45  $this->output( "Updated to {$json['manifest_version']}...\n" );
46  }
47 
51  protected function updateRequiredMwVersion( &$json ) {
52  if ( !isset( $json['requires'] ) ) {
53  $json['requires'] = [];
54  }
55 
56  $needNewVersion = true;
57 
58  // When version is set, parse it and compare against requirement for new manifest
59  if ( isset( $json['requires'][ExtensionRegistry::MEDIAWIKI_CORE] ) ) {
60  $versionParser = new VersionParser();
61  $currentRequired = $versionParser->parseConstraints(
62  // @phan-suppress-next-line PhanTypeInvalidDimOffset isset check exists
63  $json['requires'][ExtensionRegistry::MEDIAWIKI_CORE]
64  );
65  $newRequired = $versionParser->parseConstraints(
66  // The match works only when using an equal comparision
67  str_replace( '>=', '==', ExtensionRegistry::MANIFEST_VERSION_MW_VERSION )
68  );
69  if ( !$currentRequired->matches( $newRequired ) ) {
70  $needNewVersion = false;
71  }
72  }
73 
74  if ( $needNewVersion ) {
75  // Set or update a requirement on the MediaWiki version
76  // that the current MANIFEST_VERSION was introduced in.
77  $json['requires'][ExtensionRegistry::MEDIAWIKI_CORE] =
79  }
80  }
81 
82  protected function updateTo2( &$json ) {
83  if ( isset( $json['config'] ) ) {
84  $config = $json['config'];
85  $json['config'] = [];
86  if ( isset( $config['_prefix'] ) ) {
87  $json = wfArrayInsertAfter( $json, [
88  'config_prefix' => $config['_prefix']
89  ], 'config' );
90  unset( $config['_prefix'] );
91  }
92 
93  foreach ( $config as $name => $value ) {
94  if ( $name[0] !== '@' ) {
95  $json['config'][$name] = [ 'value' => $value ];
96  if ( isset( $value[ExtensionRegistry::MERGE_STRATEGY] ) ) {
97  $json['config'][$name]['merge_strategy'] = $value[ExtensionRegistry::MERGE_STRATEGY];
98  unset( $json['config'][$name]['value'][ExtensionRegistry::MERGE_STRATEGY] );
99  }
100  if ( isset( $config["@$name"] ) ) {
101  // Put 'description' first for better human-legibility.
102  $json['config'][$name] = array_merge(
103  [ 'description' => $config["@$name"] ],
104  $json['config'][$name]
105  );
106  }
107  }
108  }
109  }
110 
111  // Re-maps top level keys under attributes
112  $attributes = [
113  'CodeMirrorPluginModules' => [ 'CodeMirror', 'PluginModules' ],
114  'CodeMirrorTagModes' => [ 'CodeMirror', 'TagModes' ],
115  'EventLoggingSchemas' => [ 'EventLogging', 'Schemas' ],
116  'SyntaxHighlightModels' => [ 'SyntaxHighlight', 'Models' ],
117  'VisualEditorAvailableContentModels' => [ 'VisualEditor', 'AvailableContentModels' ],
118  'VisualEditorAvailableNamespaces' => [ 'VisualEditor', 'AvailableNamespaces' ],
119  'VisualEditorPreloadModules' => [ 'VisualEditor', 'PreloadModules' ],
120  'VisualEditorPluginModules' => [ 'VisualEditor', 'PluginModules' ],
121  ];
122 
123  foreach ( $attributes as $name => $value ) {
124  if ( !isset( $json[$name] ) ) {
125  continue;
126  }
127 
128  $json['attributes'][$value[0]][$value[1]] = $json[$name];
129  unset( $json[$name] );
130  }
131  }
132 }
133 
134 $maintClass = UpdateExtensionJsonSchema::class;
135 require_once RUN_MAINTENANCE_IF_MAIN;
RUN_MAINTENANCE_IF_MAIN
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:38
wfArrayInsertAfter
wfArrayInsertAfter(array $array, array $insert, $after)
Insert array into another array after the specified KEY
Definition: GlobalFunctions.php:209
ExtensionRegistry\MANIFEST_VERSION
const MANIFEST_VERSION
Version of the highest supported manifest version Note: Update MANIFEST_VERSION_MW_VERSION when chang...
Definition: ExtensionRegistry.php:28
UpdateExtensionJsonSchema\updateRequiredMwVersion
updateRequiredMwVersion(&$json)
Definition: updateExtensionJsonSchema.php:51
UpdateExtensionJsonSchema\updateTo2
updateTo2(&$json)
Definition: updateExtensionJsonSchema.php:82
Maintenance\fatalError
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
Definition: Maintenance.php:486
Maintenance\addDescription
addDescription( $text)
Set the description text.
Definition: Maintenance.php:327
Maintenance
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:55
FormatJson\ALL_OK
const ALL_OK
Skip escaping as many characters as reasonably possible.
Definition: FormatJson.php:55
ExtensionRegistry\MERGE_STRATEGY
const MERGE_STRATEGY
Special key that defines the merge strategy.
Definition: ExtensionRegistry.php:53
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:174
FormatJson\encode
static encode( $value, $pretty=false, $escaping=0)
Returns the JSON representation of a value.
Definition: FormatJson.php:115
ExtensionRegistry\MANIFEST_VERSION_MW_VERSION
const MANIFEST_VERSION_MW_VERSION
MediaWiki version constraint representing what the current highest MANIFEST_VERSION is supported in.
Definition: ExtensionRegistry.php:34
ExtensionRegistry\MEDIAWIKI_CORE
const MEDIAWIKI_CORE
"requires" key that applies to MediaWiki core
Definition: ExtensionRegistry.php:22
UpdateExtensionJsonSchema
Definition: updateExtensionJsonSchema.php:7
UpdateExtensionJsonSchema\__construct
__construct()
Default constructor.
Definition: updateExtensionJsonSchema.php:9
Maintenance\$config
Config $config
Accessible via getConfig()
Definition: Maintenance.php:149
$maintClass
$maintClass
Definition: updateExtensionJsonSchema.php:134
Maintenance\addArg
addArg( $arg, $description, $required=true)
Add some args that are needed.
Definition: Maintenance.php:298
Maintenance\output
output( $out, $channel=null)
Throw some output to the user.
Definition: Maintenance.php:433
UpdateExtensionJsonSchema\execute
execute()
Do the actual work.
Definition: updateExtensionJsonSchema.php:16
Maintenance\getArg
getArg( $argId=0, $default=null)
Get an argument.
Definition: Maintenance.php:351