Refactor checkComposerLockUpToDate.php logic out to reuseable class
Introduce LockFileChecker that used to check whether composer-installed dependencies (no-dev) are up-to-date. Bug: T283389 Change-Id: I0d56f235604d5c856bae5d170230f8c7ca0729c6
This commit is contained in:
parent
5dca00526a
commit
20e77793b8
13 changed files with 242 additions and 52 deletions
|
|
@ -996,6 +996,7 @@ $wgAutoloadLocalClasses = [
|
|||
'MediaWiki\\CommentFormatter\\StringCommentIterator' => __DIR__ . '/includes/CommentFormatter/StringCommentIterator.php',
|
||||
'MediaWiki\\CommentStore\\CommentStore' => __DIR__ . '/includes/CommentStore/CommentStore.php',
|
||||
'MediaWiki\\CommentStore\\CommentStoreComment' => __DIR__ . '/includes/CommentStore/CommentStoreComment.php',
|
||||
'MediaWiki\\Composer\\LockFileChecker' => __DIR__ . '/includes/composer/LockFileChecker.php',
|
||||
'MediaWiki\\Config\\Config' => __DIR__ . '/includes/config/Config.php',
|
||||
'MediaWiki\\Config\\ConfigException' => __DIR__ . '/includes/config/ConfigException.php',
|
||||
'MediaWiki\\Config\\ConfigFactory' => __DIR__ . '/includes/config/ConfigFactory.php',
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class AutoLoader {
|
|||
'MediaWiki\\Block\\' => __DIR__ . '/block/',
|
||||
'MediaWiki\\Cache\\' => __DIR__ . '/cache/',
|
||||
'MediaWiki\\ChangeTags\\' => __DIR__ . '/changetags/',
|
||||
'MediaWiki\\Composer\\' => __DIR__ . '/composer/',
|
||||
'MediaWiki\\Config\\' => __DIR__ . '/config/',
|
||||
'MediaWiki\\Content\\' => __DIR__ . '/content/',
|
||||
'MediaWiki\\DB\\' => __DIR__ . '/db/',
|
||||
|
|
|
|||
104
includes/composer/LockFileChecker.php
Normal file
104
includes/composer/LockFileChecker.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Composer;
|
||||
|
||||
use Composer\Semver\Semver;
|
||||
use ComposerJson;
|
||||
use ComposerLock;
|
||||
use Status;
|
||||
|
||||
/**
|
||||
* Used to check whether composer-installed dependencies (no-dev) are up-to-date
|
||||
* @since 1.42
|
||||
*/
|
||||
class LockFileChecker {
|
||||
/** @var ComposerJson */
|
||||
private $composerJson;
|
||||
|
||||
/** @var ComposerJson */
|
||||
private $composerLock;
|
||||
|
||||
/**
|
||||
* @param ComposerJson $composerJson
|
||||
* @param ComposerLock $composerLock
|
||||
*/
|
||||
public function __construct( ComposerJson $composerJson, ComposerLock $composerLock ) {
|
||||
$this->composerJson = $composerJson;
|
||||
$this->composerLock = $composerLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a {@link Status} instance,
|
||||
* you can use {@link Status::isGood()} to simply determine that
|
||||
* the composer-installed dependencies are up-to-date.
|
||||
* @return Status
|
||||
*/
|
||||
public function check(): Status {
|
||||
$status = Status::newGood();
|
||||
$requiredButOld = [];
|
||||
$requiredButMissing = [];
|
||||
|
||||
$installed = $this->composerLock->getInstalledDependencies();
|
||||
foreach ( $this->composerJson->getRequiredDependencies() as $name => $version ) {
|
||||
// Not installed at all.
|
||||
if ( !isset( $installed[$name] ) ) {
|
||||
$requiredButMissing[] = [
|
||||
'name' => $name,
|
||||
'wantedVersion' => $version
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Installed; need to check it's the right version
|
||||
if ( !SemVer::satisfies( $installed[$name]['version'], $version ) ) {
|
||||
$requiredButOld[] = [
|
||||
'name' => $name,
|
||||
'wantedVersion' => $version,
|
||||
'suppliedVersion' => $installed[$name]['version']
|
||||
];
|
||||
}
|
||||
|
||||
// We're happy; loop to the next dependency.
|
||||
}
|
||||
|
||||
if ( count( $requiredButOld ) === 0 && count( $requiredButMissing ) === 0 ) {
|
||||
// We couldn't find any out-of-date or missing dependencies, so assume everything is ok!
|
||||
return $status;
|
||||
}
|
||||
|
||||
foreach ( $requiredButOld as [
|
||||
"name" => $name,
|
||||
"suppliedVersion" => $suppliedVersion,
|
||||
"wantedVersion" => $wantedVersion
|
||||
] ) {
|
||||
$status->error( 'composer-deps-outdated', $name, $suppliedVersion, $wantedVersion );
|
||||
}
|
||||
|
||||
foreach ( $requiredButMissing as [
|
||||
"name" => $name,
|
||||
"wantedVersion" => $wantedVersion
|
||||
] ) {
|
||||
$status->error( 'composer-deps-notinstalled', $name, $wantedVersion );
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
|
@ -4644,5 +4644,7 @@
|
|||
"benefit-1-description": "Watchlists that allow you to keep track of pages that you’re interested in.",
|
||||
"benefit-2-description": "Permanent list of contributions you’ve made to the project.",
|
||||
"benefit-3-description": "Preferences that allow you to customize your experience.",
|
||||
"temp-user-unable-to-acquire": "Unable to acquire a temporary account username. Please try again."
|
||||
"temp-user-unable-to-acquire": "Unable to acquire a temporary account username. Please try again.",
|
||||
"composer-deps-outdated": "$1: $2 installed, $3 required.",
|
||||
"composer-deps-notinstalled": "$1: not installed, $2 required."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4901,5 +4901,7 @@
|
|||
"benefit-1-description": "The text for the first benefit shown on signup for temporary users.",
|
||||
"benefit-2-description": "The text for the second benefit shown on signup for temporary users.",
|
||||
"benefit-3-description": "The text for the third benefit shown on signup for temporary users.",
|
||||
"temp-user-unable-to-acquire": "The error message shown when the server was unable to acquire a temporary account username for the user."
|
||||
"temp-user-unable-to-acquire": "The error message shown when the server was unable to acquire a temporary account username for the user.",
|
||||
"composer-deps-outdated": "Error in check composer-installed dependencies. Parameters:\n* $1 - Dependency name.\n* $2 - Installed version\n* $3 - Required version.",
|
||||
"composer-deps-notinstalled": "Error message if a composer dependency is not install. Parameters:\n* $1 - Dependency name.\n* $2 - Required version."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
use Composer\Semver\Semver;
|
||||
use MediaWiki\Composer\LockFileChecker;
|
||||
|
||||
/**
|
||||
* Checks whether your composer-installed dependencies are up to date
|
||||
|
|
@ -35,58 +35,23 @@ class CheckComposerLockUpToDate extends Maintenance {
|
|||
$lock = new ComposerLock( $lockLocation );
|
||||
$json = new ComposerJson( $jsonLocation );
|
||||
|
||||
$requiredButOld = [];
|
||||
$requiredButMissing = [];
|
||||
|
||||
// Check all the dependencies to see if any are old
|
||||
$installed = $lock->getInstalledDependencies();
|
||||
foreach ( $json->getRequiredDependencies() as $name => $version ) {
|
||||
// Not installed at all.
|
||||
if ( !isset( $installed[$name] ) ) {
|
||||
$requiredButMissing[] = [
|
||||
'name' => $name,
|
||||
'wantedVersion' => $version
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Installed; need to check it's the right version
|
||||
if ( !SemVer::satisfies( $installed[$name]['version'], $version ) ) {
|
||||
$requiredButOld[] = [
|
||||
'name' => $name,
|
||||
'wantedVersion' => $version,
|
||||
'suppliedVersion' => $installed[$name]['version']
|
||||
];
|
||||
}
|
||||
|
||||
// We're happy; loop to the next dependency.
|
||||
}
|
||||
|
||||
if ( count( $requiredButOld ) === 0 && count( $requiredButMissing ) === 0 ) {
|
||||
// We couldn't find any out-of-date or missing dependencies, so assume everything is ok!
|
||||
$checker = new LockFileChecker( $json, $lock );
|
||||
$result = $checker->check();
|
||||
if ( $result->isGood() ) {
|
||||
// We couldn't find any out-of-date dependencies, so assume everything is ok!
|
||||
$this->output( "Your composer.lock file is up to date with current dependencies!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $requiredButOld as [
|
||||
"name" => $name,
|
||||
"suppliedVersion" => $suppliedVersion,
|
||||
"wantedVersion" => $wantedVersion
|
||||
] ) {
|
||||
$this->error( "$name: $suppliedVersion installed, $wantedVersion required.\n" );
|
||||
}
|
||||
|
||||
foreach ( $requiredButMissing as [
|
||||
"name" => $name,
|
||||
"wantedVersion" => $wantedVersion
|
||||
] ) {
|
||||
$this->error( "$name: not installed, $wantedVersion required.\n" );
|
||||
}
|
||||
|
||||
$this->fatalError(
|
||||
'Error: your composer.lock file is not up to date. ' .
|
||||
} else {
|
||||
foreach ( $result->getErrors() as $error ) {
|
||||
$this->error(
|
||||
wfMessage( $error['message'], ...$error['params'] )->inLanguage( 'en' )->plain() . "\n"
|
||||
);
|
||||
}
|
||||
$this->fatalError(
|
||||
'Error: your composer.lock file is not up to date. ' .
|
||||
'Run "composer update --no-dev" to install newer dependencies'
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/**
|
||||
* 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\Composer\LockFileChecker;
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Composer\LockFileChecker
|
||||
*/
|
||||
class LockFileCheckerTest extends MediaWikiIntegrationTestCase {
|
||||
public function testOk() {
|
||||
$json = new ComposerJson( __DIR__ . '/composer-testcase1.json' );
|
||||
$lock = new ComposerLock( __DIR__ . '/composer-testcase1.lock' );
|
||||
$checker = new LockFileChecker( $json, $lock );
|
||||
$status = $checker->check();
|
||||
$this->assertTrue( $status->isGood() );
|
||||
}
|
||||
|
||||
public function testOutdated() {
|
||||
$json = new ComposerJson( __DIR__ . '/composer-testcase2.json' );
|
||||
$lock = new ComposerLock( __DIR__ . '/composer-testcase2.lock' );
|
||||
$checker = new LockFileChecker( $json, $lock );
|
||||
$status = $checker->check();
|
||||
$this->assertFalse( $status->isGood() );
|
||||
$this->assertSame( 'wikimedia/relpath: 2.9.9 installed, 3.0.0 required.', $status->getMessage()->plain() );
|
||||
}
|
||||
|
||||
public function testNotInstalled() {
|
||||
$json = new ComposerJson( __DIR__ . '/composer-testcase3.json' );
|
||||
$lock = new ComposerLock( __DIR__ . '/composer-testcase3.lock' );
|
||||
$checker = new LockFileChecker( $json, $lock );
|
||||
$status = $checker->check();
|
||||
$this->assertFalse( $status->isGood() );
|
||||
$errors = $status->getErrors();
|
||||
$msgs = [];
|
||||
foreach ( $errors as $error ) {
|
||||
$msgs[] = wfMessage( $error['message'], ...$error['params'] )->plain();
|
||||
}
|
||||
$this->assertArrayEquals( [
|
||||
'wikimedia/relpath: 2.9.9 installed, 3.0.0 required.',
|
||||
'wikimedia/at-ease: not installed, 2.1.0 required.',
|
||||
], $msgs );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"wikimedia/at-ease": "2.1.0",
|
||||
"wikimedia/relpath": "3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "wikimedia/at-ease",
|
||||
"version": "v2.1.0",
|
||||
"type": "library"
|
||||
},
|
||||
{
|
||||
"name": "wikimedia/relpath",
|
||||
"version": "3.0.0",
|
||||
"type": "library"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"wikimedia/at-ease": "2.1.0",
|
||||
"wikimedia/relpath": "3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "wikimedia/at-ease",
|
||||
"version": "v2.1.0",
|
||||
"type": "library"
|
||||
},
|
||||
{
|
||||
"name": "wikimedia/relpath",
|
||||
"version": "2.9.9",
|
||||
"type": "library"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"wikimedia/at-ease": "2.1.0",
|
||||
"wikimedia/relpath": "3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "wikimedia/relpath",
|
||||
"version": "2.9.9",
|
||||
"type": "library"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue