public function execute() { global $IP; $lockLocation = "{$IP}/composer.lock"; $jsonLocation = "{$IP}/composer.json"; if (!file_exists($lockLocation)) { // Maybe they're using mediawiki/vendor? $lockLocation = "{$IP}/vendor/composer.lock"; if (!file_exists($lockLocation)) { $this->error('Could not find composer.lock file. Have you run "composer install"?', 1); } } $lock = new ComposerLock($lockLocation); $json = new ComposerJson($jsonLocation); // Check all the dependencies to see if any are old $found = false; $installed = $lock->getInstalledDependencies(); foreach ($json->getRequiredDependencies() as $name => $version) { if (isset($installed[$name])) { if ($installed[$name]['version'] !== $version) { $this->output("{$name}: {$installed[$name]['version']} installed, {$version} required.\n"); $found = true; } } else { $this->output("{$name}: not installed, {$version} required.\n"); $found = true; } } if ($found) { $this->error('Error: your composer.lock file is not up to date. ' . 'Run "composer update" to install newer dependencies', 1); } else { // 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"); } }
public function execute() { global $IP; $lockLocation = "{$IP}/composer.lock"; $jsonLocation = "{$IP}/composer.json"; if (!file_exists($lockLocation)) { // Maybe they're using mediawiki/vendor? $lockLocation = "{$IP}/vendor/composer.lock"; if (!file_exists($lockLocation)) { $this->error('Could not find composer.lock file. Have you run "composer install"?', 1); } } $lock = new ComposerLock($lockLocation); $json = new ComposerJson($jsonLocation); if ($lock->getHash() === $json->getHash()) { $this->output("Your composer.lock file is up to date with current dependencies!\n"); return; } // Out of date, lets figure out which dependencies are old $found = false; $installed = $lock->getInstalledDependencies(); foreach ($json->getRequiredDependencies() as $name => $version) { if (isset($installed[$name])) { if ($installed[$name]['version'] !== $version) { $this->output("{$name}: {$installed[$name]['version']} installed, {$version} required.\n"); $found = true; } } else { $this->output("{$name}: not installed, {$version} required.\n"); $found = true; } } if ($found) { $this->error('Error: your composer.lock file is not up to date, run "composer update" to install newer dependencies', 1); } else { // The hash is the entire composer.json file, so it can be updated without any of the dependencies changing // 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"); } }
/** * @covers ComposerLock::getInstalledDependencies */ public function testGetInstalledDependencies() { $lock = new ComposerLock($this->lock); $this->assertArrayEquals(['wikimedia/cdb' => ['version' => '1.0.1', 'type' => 'library', 'licenses' => ['GPL-2.0'], 'authors' => [['name' => 'Tim Starling', 'email' => '*****@*****.**'], ['name' => 'Chad Horohoe', 'email' => '*****@*****.**']], 'description' => 'Constant Database (CDB) wrapper library for PHP. ' . 'Provides pure-PHP fallback when dba_* functions are absent.'], 'cssjanus/cssjanus' => ['version' => '1.1.1', 'type' => 'library', 'licenses' => ['Apache-2.0'], 'authors' => [], 'description' => 'Convert CSS stylesheets between left-to-right and right-to-left.'], 'leafo/lessphp' => ['version' => '0.5.0', 'type' => 'library', 'licenses' => ['MIT', 'GPL-3.0'], 'authors' => [['name' => 'Leaf Corcoran', 'email' => '*****@*****.**', 'homepage' => 'http://leafo.net']], 'description' => 'lessphp is a compiler for LESS written in PHP.'], 'psr/log' => ['version' => '1.0.0', 'type' => 'library', 'licenses' => ['MIT'], 'authors' => [['name' => 'PHP-FIG', 'homepage' => 'http://www.php-fig.org/']], 'description' => 'Common interface for logging libraries'], 'oojs/oojs-ui' => ['version' => '0.6.0', 'type' => 'library', 'licenses' => ['MIT'], 'authors' => [], 'description' => ''], 'composer/installers' => ['version' => '1.0.19', 'type' => 'composer-installer', 'licenses' => ['MIT'], 'authors' => [['name' => 'Kyle Robinson Young', 'email' => '*****@*****.**', 'homepage' => 'https://github.com/shama']], 'description' => 'A multi-framework Composer library installer'], 'mediawiki/translate' => ['version' => '2014.12', 'type' => 'mediawiki-extension', 'licenses' => ['GPL-2.0+'], 'authors' => [['name' => 'Niklas Laxström', 'email' => '*****@*****.**', 'role' => 'Lead nitpicker'], ['name' => 'Siebrand Mazeland', 'email' => '*****@*****.**', 'role' => 'Developer']], 'description' => 'The only standard solution to translate any kind ' . 'of text with an avant-garde web interface within MediaWiki, ' . 'including your documentation and software'], 'mediawiki/universal-language-selector' => ['version' => '2014.12', 'type' => 'mediawiki-extension', 'licenses' => ['GPL-2.0+', 'MIT'], 'authors' => [], 'description' => 'The primary aim is to allow users to select a language ' . 'and configure its support in an easy way. ' . 'Main features are language selection, input methods and web fonts.']], $lock->getInstalledDependencies(), false, true); }
protected function appendInstalledLibraries($property) { global $IP; $path = "{$IP}/composer.lock"; if (!file_exists($path)) { // Maybe they're using mediawiki/vendor? $path = "{$IP}/vendor/composer.lock"; if (!file_exists($path)) { return true; } } $data = array(); $lock = new ComposerLock($path); foreach ($lock->getInstalledDependencies() as $name => $info) { if (strpos($info['type'], 'mediawiki-') === 0) { // Skip any extensions or skins since they'll be listed // in their proper section continue; } $data[] = array('name' => $name, 'version' => $info['version']); } ApiResult::setIndexedTagName($data, 'library'); return $this->getResult()->addValue('query', $property, $data); }
/** * @covers ComposerLock::getInstalledDependencies */ public function testGetInstalledDependencies() { $lock = new ComposerLock($this->lock); $this->assertArrayEquals(array('wikimedia/cdb' => array('version' => '1.0.1', 'type' => 'library'), 'cssjanus/cssjanus' => array('version' => '1.1.1', 'type' => 'library'), 'leafo/lessphp' => array('version' => '0.5.0', 'type' => 'library'), 'psr/log' => array('version' => '1.0.0', 'type' => 'library'), 'oojs/oojs-ui' => array('version' => '0.6.0', 'type' => 'library'), 'composer/installers' => array('version' => '1.0.19', 'type' => 'composer-installer'), 'mediawiki/translate' => array('version' => '2014.12', 'type' => 'mediawiki-extension'), 'mediawiki/universal-language-selector' => array('version' => '2014.12', 'type' => 'mediawiki-extension')), $lock->getInstalledDependencies(), false, true); }
/** * Generate an HTML table for external libraries that are installed * * @return string */ protected function getExternalLibraries() { global $IP; $path = "{$IP}/composer.lock"; if (!file_exists($path)) { // Maybe they're using mediawiki/vendor? $path = "{$IP}/vendor/composer.lock"; if (!file_exists($path)) { return ''; } } $lock = new ComposerLock($path); $out = Html::element('h2', array('id' => 'mw-version-libraries'), $this->msg('version-libraries')->text()); $out .= Html::openElement('table', array('class' => 'wikitable plainlinks', 'id' => 'sv-libraries')); $out .= Html::openElement('tr') . Html::element('th', array(), $this->msg('version-libraries-library')->text()) . Html::element('th', array(), $this->msg('version-libraries-version')->text()) . Html::closeElement('tr'); foreach ($lock->getInstalledDependencies() as $name => $info) { if (strpos($info['type'], 'mediawiki-') === 0) { // Skip any extensions or skins since they'll be listed // in their proper section continue; } $out .= Html::openElement('tr') . Html::rawElement('td', array(), Linker::makeExternalLink("https://packagist.org/packages/{$name}", $name)) . Html::element('td', array(), $info['version']) . Html::closeElement('tr'); } $out .= Html::closeElement('table'); return $out; }
/** * Generate an HTML table for external libraries that are installed * * @return string */ protected function getExternalLibraries() { global $IP; $path = "{$IP}/composer.lock"; if (!file_exists($path)) { // Maybe they're using mediawiki/vendor? $path = "{$IP}/vendor/composer.lock"; if (!file_exists($path)) { return ''; } } $lock = new ComposerLock($path); $out = Html::element('h2', array('id' => 'mw-version-libraries'), $this->msg('version-libraries')->text()); $out .= Html::openElement('table', array('class' => 'wikitable plainlinks', 'id' => 'sv-libraries')); $out .= Html::openElement('tr') . Html::element('th', array(), $this->msg('version-libraries-library')->text()) . Html::element('th', array(), $this->msg('version-libraries-version')->text()) . Html::element('th', array(), $this->msg('version-libraries-license')->text()) . Html::element('th', array(), $this->msg('version-libraries-description')->text()) . Html::element('th', array(), $this->msg('version-libraries-authors')->text()) . Html::closeElement('tr'); foreach ($lock->getInstalledDependencies() as $name => $info) { if (strpos($info['type'], 'mediawiki-') === 0) { // Skip any extensions or skins since they'll be listed // in their proper section continue; } $authors = array_map(function ($arr) { // If a homepage is set, link to it if (isset($arr['homepage'])) { return "[{$arr['homepage']} {$arr['name']}]"; } return $arr['name']; }, $info['authors']); $authors = $this->listAuthors($authors, false, "{$IP}/vendor/{$name}"); $out .= Html::openElement('tr') . Html::rawElement('td', array(), Linker::makeExternalLink("https://packagist.org/packages/{$name}", $name, true, '', array('class' => 'mw-version-library-name'))) . Html::element('td', array(), $info['version']) . Html::element('td', array(), $this->listToText($info['licenses'])) . Html::element('td', array(), $info['description']) . Html::rawElement('td', array(), $authors) . Html::closeElement('tr'); } $out .= Html::closeElement('table'); return $out; }