Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1429234
checkDependencies.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
checkDependencies.php
View Options
<?php
/**
* (C) 2019 Kunal Mehta <legoktm@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
use
MediaWiki\MainConfigNames
;
use
MediaWiki\Registration\ExtensionDependencyError
;
use
MediaWiki\Registration\ExtensionRegistry
;
// @codeCoverageIgnoreStart
require_once
__DIR__
.
'/Maintenance.php'
;
// @codeCoverageIgnoreEnd
/**
* Checks dependencies for extensions, mostly without loading them
*
* @since 1.34
*/
class
CheckDependencies
extends
Maintenance
{
/** @var bool */
private
$checkDev
;
public
function
__construct
()
{
parent
::
__construct
();
$this
->
addDescription
(
'Check dependencies for extensions'
);
$this
->
addOption
(
'extensions'
,
'Comma separated list of extensions to check'
,
false
,
true
);
$this
->
addOption
(
'skins'
,
'Comma separated list of skins to check'
,
false
,
true
);
$this
->
addOption
(
'json'
,
'Output in JSON'
);
$this
->
addOption
(
'dev'
,
'Check development dependencies too'
);
}
public
function
execute
()
{
$this
->
checkDev
=
$this
->
hasOption
(
'dev'
);
$extensions
=
$this
->
hasOption
(
'extensions'
)
?
explode
(
','
,
$this
->
getOption
(
'extensions'
)
)
:
[];
$skins
=
$this
->
hasOption
(
'skins'
)
?
explode
(
','
,
$this
->
getOption
(
'skins'
)
)
:
[];
$dependencies
=
[];
// Note that we can only use the main registry if we are
// not checking development dependencies.
$registry
=
ExtensionRegistry
::
getInstance
();
foreach
(
$extensions
as
$extension
)
{
if
(
!
$this
->
checkDev
&&
$registry
->
isLoaded
(
$extension
)
)
{
// If it's already loaded, we know all the dependencies resolved.
$this
->
addToDependencies
(
$dependencies
,
[
$extension
],
[]
);
continue
;
}
$this
->
loadThing
(
$dependencies
,
$extension
,
[
$extension
],
[]
);
}
foreach
(
$skins
as
$skin
)
{
if
(
!
$this
->
checkDev
&&
$registry
->
isLoaded
(
$skin
)
)
{
// If it's already loaded, we know all the dependencies resolved.
$this
->
addToDependencies
(
$dependencies
,
[],
[
$skin
]
);
continue
;
}
$this
->
loadThing
(
$dependencies
,
$skin
,
[],
[
$skin
]
);
}
if
(
$this
->
hasOption
(
'json'
)
)
{
$this
->
output
(
json_encode
(
$dependencies
)
.
"
\n
"
);
}
else
{
$this
->
output
(
$this
->
formatForHumans
(
$dependencies
)
.
"
\n
"
);
}
}
private
function
loadThing
(
&
$dependencies
,
$name
,
$extensions
,
$skins
)
{
$extDir
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
ExtensionDirectory
);
$styleDir
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
StyleDirectory
);
$queue
=
[];
$missing
=
false
;
foreach
(
$extensions
as
$extension
)
{
$path
=
"$extDir/$extension/extension.json"
;
if
(
file_exists
(
$path
)
)
{
// 1 is ignored
$queue
[
$path
]
=
1
;
$this
->
addToDependencies
(
$dependencies
,
[
$extension
],
[],
$name
);
}
else
{
$missing
=
true
;
$this
->
addToDependencies
(
$dependencies
,
[
$extension
],
[],
$name
,
'missing'
);
}
}
foreach
(
$skins
as
$skin
)
{
$path
=
"$styleDir/$skin/skin.json"
;
if
(
file_exists
(
$path
)
)
{
$queue
[
$path
]
=
1
;
$this
->
addToDependencies
(
$dependencies
,
[],
[
$skin
],
$name
);
}
else
{
$missing
=
true
;
$this
->
addToDependencies
(
$dependencies
,
[],
[
$skin
],
$name
,
'missing'
);
}
}
if
(
$missing
)
{
// Stuff is missing, give up
return
;
}
$registry
=
new
ExtensionRegistry
();
$registry
->
setCheckDevRequires
(
$this
->
checkDev
);
try
{
$registry
->
readFromQueue
(
$queue
);
}
catch
(
ExtensionDependencyError
$e
)
{
$reason
=
false
;
if
(
$e
->
incompatibleCore
)
{
$reason
=
'incompatible-core'
;
}
elseif
(
$e
->
incompatibleSkins
)
{
$reason
=
'incompatible-skins'
;
}
elseif
(
$e
->
incompatibleExtensions
)
{
$reason
=
'incompatible-extensions'
;
}
elseif
(
$e
->
missingExtensions
||
$e
->
missingSkins
)
{
// There's an extension missing in the dependency tree,
// so add those to the dependency list and try again
$this
->
loadThing
(
$dependencies
,
$name
,
array_merge
(
$extensions
,
$e
->
missingExtensions
),
array_merge
(
$skins
,
$e
->
missingSkins
)
);
return
;
}
else
{
// missing-phpExtension
// missing-ability
// XXX: ???
$this
->
fatalError
(
$e
->
getMessage
()
);
}
$this
->
addToDependencies
(
$dependencies
,
$extensions
,
$skins
,
$name
,
$reason
,
$e
->
getMessage
()
);
}
$this
->
addToDependencies
(
$dependencies
,
$extensions
,
$skins
,
$name
);
}
private
function
addToDependencies
(
&
$dependencies
,
$extensions
,
$skins
,
$why
=
null
,
$status
=
null
,
$message
=
null
)
{
$mainRegistry
=
ExtensionRegistry
::
getInstance
();
$iter
=
[
'extensions'
=>
$extensions
,
'skins'
=>
$skins
];
foreach
(
$iter
as
$type
=>
$things
)
{
foreach
(
$things
as
$thing
)
{
$preStatus
=
$dependencies
[
$type
][
$thing
][
'status'
]
??
false
;
if
(
$preStatus
!==
'loaded'
)
{
// OK to overwrite
if
(
$status
)
{
$tStatus
=
$status
;
}
else
{
$tStatus
=
$mainRegistry
->
isLoaded
(
$thing
)
?
'loaded'
:
'present'
;
}
$dependencies
[
$type
][
$thing
][
'status'
]
=
$tStatus
;
}
if
(
$why
!==
null
)
{
$dependencies
[
$type
][
$thing
][
'why'
][]
=
$why
;
// XXX: this is a bit messy
$dependencies
[
$type
][
$thing
][
'why'
]
=
array_unique
(
$dependencies
[
$type
][
$thing
][
'why'
]
);
}
if
(
$message
!==
null
)
{
$dependencies
[
$type
][
$thing
][
'message'
]
=
trim
(
$message
);
}
}
}
}
private
function
formatForHumans
(
$dependencies
)
{
$text
=
''
;
foreach
(
$dependencies
as
$type
=>
$things
)
{
$text
.=
ucfirst
(
$type
)
.
"
\n
"
.
str_repeat
(
'='
,
strlen
(
$type
)
)
.
"
\n
"
;
foreach
(
$things
as
$thing
=>
$info
)
{
$why
=
$info
[
'why'
]
??
[];
if
(
$why
)
{
$whyText
=
'(because: '
.
implode
(
','
,
$why
)
.
') '
;
}
else
{
$whyText
=
''
;
}
$msg
=
isset
(
$info
[
'message'
]
)
?
", {$info['message']}"
:
''
;
$text
.=
"$thing: {$info['status']}{$msg} $whyText
\n
"
;
}
$text
.=
"
\n
"
;
}
return
trim
(
$text
);
}
}
// @codeCoverageIgnoreStart
$maintClass
=
CheckDependencies
::
class
;
require_once
RUN_MAINTENANCE_IF_MAIN
;
// @codeCoverageIgnoreEnd
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 17:18 (10 h, 14 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
81/fc/46062e71b4528a03db422d6a5704
Default Alt Text
checkDependencies.php (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment