diff --git a/composer.json b/composer.json index 04e1806eebf20292b6882da3ffe647d4a959c88d..7f170ce71d7eaad6c12614095bbc9643a3a29722 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "license": "GPL-2.0+", "require": { "composer/installers": "^1.0.21", - "wikimedia/composer-merge-plugin": "^1.3.0" + "wikimedia/composer-merge-plugin": "~1.3" }, "replace": { "drupal/core": "~8.0" diff --git a/composer.lock b/composer.lock index fa73dd41286994ccd0d1a0a9d5106c1e1a7e20d4..32535367bf1b2c38e8e5361f23d0d44127c81d8c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2be29019515c847055593ea41b88475d", - "content-hash": "f38613812a285c03a1a18458384fe0b1", + "hash": "dac77f10c1f7585fd1f7344c6a376338", + "content-hash": "73cbcb262208c5d802cb528279f2a95c", "packages": [ { "name": "composer/installers", @@ -1980,16 +1980,16 @@ }, { "name": "wikimedia/composer-merge-plugin", - "version": "dev-master", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e" + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/f770a4dd9771041f713f5ba3d8e4ba702015653d", - "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", "shasum": "" }, "require": { @@ -1999,8 +1999,7 @@ "require-dev": { "composer/composer": "1.0.*@dev", "jakub-onderka/php-parallel-lint": "~0.8", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.0", + "phpunit/phpunit": "~4.8|~5.0", "squizlabs/php_codesniffer": "~2.1.0" }, "type": "composer-plugin", @@ -2026,7 +2025,7 @@ } ], "description": "Composer plugin to merge multiple composer.json files", - "time": "2015-09-22 21:14:25" + "time": "2015-11-06 20:31:16" }, { "name": "zendframework/zend-diactoros", diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 229e81743f9ec2cba3ffb5e58913f68ec9f196f3..b58ef9a848e69ee4d1288e53da5ef9a7d886cbaa 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -96,58 +96,6 @@ "zikula" ] }, - { - "name": "wikimedia/composer-merge-plugin", - "version": "dev-master", - "version_normalized": "9999999-dev", - "source": { - "type": "git", - "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/f770a4dd9771041f713f5ba3d8e4ba702015653d", - "reference": "47bb3388cfeae41a38087ac8465a7d08fa92ea2e", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": ">=5.3.2" - }, - "require-dev": { - "composer/composer": "1.0.*@dev", - "jakub-onderka/php-parallel-lint": "~0.8", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.1.0" - }, - "time": "2015-09-22 21:14:25", - "type": "composer-plugin", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - }, - "class": "Wikimedia\\Composer\\MergePlugin" - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Wikimedia\\Composer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bryan Davis", - "email": "bd808@wikimedia.org" - } - ], - "description": "Composer plugin to merge multiple composer.json files" - }, { "name": "composer/semver", "version": "1.0.0", @@ -3858,5 +3806,56 @@ "keywords": [ "templating" ] + }, + { + "name": "wikimedia/composer-merge-plugin", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/composer-merge-plugin.git", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.2" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "jakub-onderka/php-parallel-lint": "~0.8", + "phpunit/phpunit": "~4.8|~5.0", + "squizlabs/php_codesniffer": "~2.1.0" + }, + "time": "2015-11-06 20:31:16", + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + }, + "class": "Wikimedia\\Composer\\MergePlugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Wikimedia\\Composer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bryan Davis", + "email": "bd808@wikimedia.org" + } + ], + "description": "Composer plugin to merge multiple composer.json files" } ] diff --git a/vendor/wikimedia/composer-merge-plugin/.arcconfig b/vendor/wikimedia/composer-merge-plugin/.arcconfig new file mode 100644 index 0000000000000000000000000000000000000000..3dfae3d906e0e5411bc7ae734210e79892ddc246 --- /dev/null +++ b/vendor/wikimedia/composer-merge-plugin/.arcconfig @@ -0,0 +1,6 @@ +{ + "phabricator.uri" : "https://phabricator.wikimedia.org/", + "repository.callsign" : "GCMP", + "history.immutable" : false, + "unit.engine": "PhpunitTestEngine" +} diff --git a/vendor/wikimedia/composer-merge-plugin/.arclint b/vendor/wikimedia/composer-merge-plugin/.arclint new file mode 100644 index 0000000000000000000000000000000000000000..da42f29a25389d166bd72ace2a52934cdf983c98 --- /dev/null +++ b/vendor/wikimedia/composer-merge-plugin/.arclint @@ -0,0 +1,13 @@ +{ + "exclude": "(^vendor/)", + "linters": { + "php": { + "type": "php", + "include": "(\\.php$)" + }, + "json": { + "type": "json", + "include": "(\\.json$)" + } + } +} diff --git a/vendor/wikimedia/composer-merge-plugin/README.md b/vendor/wikimedia/composer-merge-plugin/README.md index 7f54beeec9272cbe35327c2541079b50d9ea44f7..f020d40ae890d44d16901700e74af2347d1a4879 100644 --- a/vendor/wikimedia/composer-merge-plugin/README.md +++ b/vendor/wikimedia/composer-merge-plugin/README.md @@ -1,26 +1,29 @@ -[![Latest Stable Version](https://img.shields.io/packagist/v/wikimedia/composer-merge-plugin.svg?style=flat)](https://packagist.org/packages/wikimedia/composer-merge-plugin) [![License](https://img.shields.io/packagist/l/wikimedia/composer-merge-plugin.svg?style=flat)](https://github.com/wikimedia/composer-merge-plugin/blob/master/LICENSE) -[![Build Status](https://img.shields.io/travis/wikimedia/composer-merge-plugin.svg?style=flat)](https://travis-ci.org/wikimedia/composer-merge-plugin) -[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/wikimedia/composer-merge-plugin/master.svg?style=flat)](https://scrutinizer-ci.com/g/wikimedia/composer-merge-plugin/?branch=master) +[![Latest Stable Version]](https://packagist.org/packages/wikimedia/composer-merge-plugin) [![License]](https://github.com/wikimedia/composer-merge-plugin/blob/master/LICENSE) +[![Build Status]](https://travis-ci.org/wikimedia/composer-merge-plugin) +[![Code Coverage]](https://scrutinizer-ci.com/g/wikimedia/composer-merge-plugin/?branch=master) Composer Merge Plugin ===================== -Merge one or more additional composer.json files at [Composer] runtime. +Merge multiple composer.json files at [Composer] runtime. Composer Merge Plugin is intended to allow easier dependency management for applications which ship a composer.json file and expect some deployments to install additional Composer managed libraries. It does this by allowing the application's top level `composer.json` file to provide a list of optional additional configuration files. When Composer is run it will parse these files -and merge their configuration into the base configuration. This combined -configuration will allow downloading additional libraries and generating the -autoloader. It was specifically created to help with installation of -[MediaWiki] which has core Composer managed library requirements and optional -libraries and extensions which may also be managed via Composer. +and merge their configuration settings into the base configuration. This +combined configuration will then be used when downloading additional libraries +and generating the autoloader. + +Composer Merge Plugin was created to help with installation of [MediaWiki] +which has core library requirements as well as optional libraries and +extensions which may be managed via Composer. Installation ------------ + ``` $ composer require wikimedia/composer-merge-plugin ``` @@ -40,58 +43,101 @@ Usage "composer.local.json", "extensions/*/composer.json" ], - "recurse": false, + "require": [ + "submodule/composer.json" + ], + "recurse": true, "replace": false, + "merge-dev": true, "merge-extra": false } } } ``` -The `include` key can specify either a single value or an array of values. -Each value is treated as a `glob()` pattern identifying additional -composer.json style configuration files to merge into the configuration for -the current Composer execution. By default the merge plugin is recursive, if -an included file also has a "merge-plugin" section it will also be processed. -This functionality can be disabled by setting `"recurse": false` inside the -"merge-plugin" section. -These sections of the found configuration files will be merged into the root -package configuration as though they were directly included in the top-level -composer.json file: +Plugin configuration +-------------------- + +The plugin reads its configuration from the `merge-plugin` section of your +composer.json's `extra` section. An `include` setting is required to tell +Composer Merge Plugin which file(s) to merge. + + +### include + +The `include` setting can specify either a single value or an array of values. +Each value is treated as a PHP `glob()` pattern identifying additional +composer.json style configuration files to merge into the root package +configuration for the current Composer execution. + +The following sections of the found configuration files will be merged into +the Composer root package configuration as though they were directly included +in the top-level composer.json file: * [autoload](https://getcomposer.org/doc/04-schema.md#autoload) * [autoload-dev](https://getcomposer.org/doc/04-schema.md#autoload-dev) + (optional, see [merge-dev](#merge-dev) below) * [conflict](https://getcomposer.org/doc/04-schema.md#conflict) * [provide](https://getcomposer.org/doc/04-schema.md#provide) * [replace](https://getcomposer.org/doc/04-schema.md#replace) * [repositories](https://getcomposer.org/doc/04-schema.md#repositories) * [require](https://getcomposer.org/doc/04-schema.md#require) * [require-dev](https://getcomposer.org/doc/04-schema.md#require-dev) + (optional, see [merge-dev](#merge-dev) below) * [suggest](https://getcomposer.org/doc/04-schema.md#suggest) +* [extra](https://getcomposer.org/doc/04-schema.md#extra) + (optional, see [merge-extra](#merge-extra) below) + + +### require + +The `require` setting is identical to `[include](#include)` except when +a pattern fails to match at least one file then it will cause an error. + +### recurse + +By default the merge plugin is recursive; if an included file has +a `merge-plugin` section it will also be processed. This functionality can be +disabled by adding a `"recurse": false` setting. -A `"merge-extra": true` setting enables the merging of the "extra" section of -included files as well. The normal merge mode for the extra section is to -accept the first version of any key found (e.g. a key in the master config -wins over the version found in an imported config). If `replace` mode is -active (see below) then this behavior changes and the last found key will win -(the key in the master config is replaced by the key in the imported config). -Note that the `merge-plugin` key itself is excluded from this merge process. -Your mileage with merging the extra section will vary depending on the plugins -being used and the order in which they are processed by Composer. - -By default, Composer's normal conflict resolution engine is used to determine -which version of a package should be installed if multiple files specify the -same package. A `"replace": true` setting can be provided inside the -"merge-plugin" section to change to a "last version specified wins" conflict -resolution strategy. In this mode, duplicate package declarations in merged -files will overwrite the declarations made in earlier files. Files are loaded -in the order specified in the `include` section with globbed files being -loaded in alphabetical order. + +### replace + +By default, Composer's conflict resolution engine is used to determine which +version of a package should be installed when multiple files specify the same +package. A `"replace": true` setting can be provided to change to a "last +version specified wins" conflict resolution strategy. In this mode, duplicate +package declarations found in merged files will overwrite the declarations +made by earlier files. Files are loaded in the order specified by the +`include` setting with globbed files being processed in alphabetical order. + + +### merge-dev + +By default, `autoload-dev` and `require-dev` sections of included files are +merged. A `"merge-dev": false` setting will disable this behavior. + + +### merge-extra + +A `"merge-extra": true` setting enables the merging the contents of the +`extra` section of included files as well. The normal merge mode for the extra +section is to accept the first version of any key found (e.g. a key in the +master config wins over the version found in any imported config). If +`replace` mode is active ([see above](#replace)) then this behavior changes +and the last key found will win (e.g. the key in the master config is replaced +by the key in the imported config). The usefulness of merging the extra +section will vary depending on the Composer plugins being used and the order +in which they are processed by Composer. + +Note that `merge-plugin` sections are excluded from the merge process, but are +always processed by the plugin unless [recursion](#recurse) is disabled. Running tests ------------- + ``` $ composer install $ composer test @@ -100,6 +146,7 @@ $ composer test Contributing ------------ + Bug, feature requests and other issues should be reported to the [GitHub project]. We accept code and documentation contributions via Pull Requests on GitHub as well. @@ -119,6 +166,7 @@ GitHub as well. License ------- + Composer Merge plugin is licensed under the MIT license. See the `LICENSE` file for more details. @@ -129,3 +177,7 @@ file for more details. [GitHub project]: https://github.com/wikimedia/composer-merge-plugin [PSR-2 Coding Standard]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md [PHP Code Sniffer]: http://pear.php.net/package/PHP_CodeSniffer +[Latest Stable Version]: https://img.shields.io/packagist/v/wikimedia/composer-merge-plugin.svg?style=flat +[License]: https://img.shields.io/packagist/l/wikimedia/composer-merge-plugin.svg?style=flat +[Build Status]: https://img.shields.io/travis/wikimedia/composer-merge-plugin.svg?style=flat +[Code Coverage]: https://img.shields.io/scrutinizer/coverage/g/wikimedia/composer-merge-plugin/master.svg?style=flat diff --git a/vendor/wikimedia/composer-merge-plugin/composer.json b/vendor/wikimedia/composer-merge-plugin/composer.json index 02d7d56d5e76d89c6a3a1bd1c52d8d480f0df0a7..dce70e7d2ed0377e50aaa7788b410359ddfc64d3 100644 --- a/vendor/wikimedia/composer-merge-plugin/composer.json +++ b/vendor/wikimedia/composer-merge-plugin/composer.json @@ -18,8 +18,7 @@ "require-dev": { "composer/composer": "1.0.*@dev", "jakub-onderka/php-parallel-lint": "~0.8", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.0", + "phpunit/phpunit": "~4.8|~5.0", "squizlabs/php_codesniffer": "~2.1.0" }, "autoload": { diff --git a/vendor/wikimedia/composer-merge-plugin/src/Logger.php b/vendor/wikimedia/composer-merge-plugin/src/Logger.php index b0c695c5e735db8187e0e830e1468e8d788a4b32..1635a2b0455150d089df6590070b4eab382f53c6 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/Logger.php +++ b/vendor/wikimedia/composer-merge-plugin/src/Logger.php @@ -42,24 +42,60 @@ public function __construct($name, IOInterface $io) /** * Log a debug message * + * Messages will be output at the "very verbose" logging level (eg `-vv` + * needed on the Composer command). + * + * @param string $message + */ + public function debug($message) + { + if ($this->inputOutput->isVeryVerbose()) { + $message = " [{$this->name}] {$message}"; + $this->log($message); + } + } + + /** + * Log an informative message + * * Messages will be output at the "verbose" logging level (eg `-v` needed * on the Composer command). * * @param string $message */ - public function debug($message) + public function info($message) { if ($this->inputOutput->isVerbose()) { $message = " [{$this->name}] {$message}"; + $this->log($message); + } + } - if (method_exists($this->inputOutput, 'writeError')) { - $this->inputOutput->writeError($message); - } else { - // @codeCoverageIgnoreStart - // Backwards compatiblity for Composer before cb336a5 - $this->inputOutput->write($message); - // @codeCoverageIgnoreEnd - } + /** + * Log a warning message + * + * @param string $message + */ + public function warning($message) + { + $message = " [{$this->name}] {$message}"; + $this->log($message); + } + + /** + * Write a message + * + * @param string $message + */ + protected function log($message) + { + if (method_exists($this->inputOutput, 'writeError')) { + $this->inputOutput->writeError($message); + } else { + // @codeCoverageIgnoreStart + // Backwards compatiblity for Composer before cb336a5 + $this->inputOutput->write($message); + // @codeCoverageIgnoreEnd } } } diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php index 476fdc9cad9a1d626b669390ecfc8764cdbce23d..ebecdff5e12f0dcb74f79545fb4e27d049ad292c 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php @@ -16,13 +16,17 @@ use Composer\Json\JsonFile; use Composer\Package\BasePackage; use Composer\Package\CompletePackage; +use Composer\Package\Link; use Composer\Package\Loader\ArrayLoader; +use Composer\Package\RootAliasPackage; use Composer\Package\RootPackage; +use Composer\Package\RootPackageInterface; use Composer\Package\Version\VersionParser; use UnexpectedValueException; /** - * Processing for a composer.json file that will be merged into a RootPackage + * Processing for a composer.json file that will be merged into + * a RootPackageInterface * * @author Bryan Davis */ @@ -79,6 +83,17 @@ public function getIncludes() $this->json['extra']['merge-plugin']['include'] : array(); } + /** + * Get list of additional packages to require if precessing recursively. + * + * @return array + */ + public function getRequires() + { + return isset($this->json['extra']['merge-plugin']['require']) ? + $this->json['extra']['merge-plugin']['require'] : array(); + } + /** * Read the contents of a composer.json style file into an array. * @@ -123,25 +138,30 @@ protected function loadPackage($json) } /** - * Merge this package into a RootPackage + * Merge this package into a RootPackageInterface * - * @param RootPackage $root + * @param RootPackageInterface $root * @param PluginState $state */ - public function mergeInto(RootPackage $root, PluginState $state) + public function mergeInto(RootPackageInterface $root, PluginState $state) { $this->addRepositories($root); - $this->mergeRequires($root, $state); - $this->mergeDevRequires($root, $state); + $this->mergeRequires('require', $root, $state); + if ($state->isDevMode()) { + $this->mergeRequires('require-dev', $root, $state); + } + + $this->mergePackageLinks('conflict', $root); + $this->mergePackageLinks('replace', $root); + $this->mergePackageLinks('provide', $root); - $this->mergeConflicts($root); - $this->mergeReplaces($root); - $this->mergeProvides($root); $this->mergeSuggests($root); - $this->mergeAutoload($root); - $this->mergeDevAutoload($root); + $this->mergeAutoload('autoload', $root); + if ($state->isDevMode()) { + $this->mergeAutoload('devAutoload', $root); + } $this->mergeExtra($root, $state); } @@ -150,9 +170,9 @@ public function mergeInto(RootPackage $root, PluginState $state) * Add a collection of repositories described by the given configuration * to the given package and the global repository manager. * - * @param RootPackage $root + * @param RootPackageInterface $root */ - protected function addRepositories(RootPackage $root) + protected function addRepositories(RootPackageInterface $root) { if (!isset($this->json['repositories'])) { return; @@ -164,7 +184,7 @@ protected function addRepositories(RootPackage $root) if (!isset($repoJson['type'])) { continue; } - $this->logger->debug("Adding {$repoJson['type']} repository"); + $this->logger->info("Adding {$repoJson['type']} repository"); $repo = $repoManager->createRepository( $repoJson['type'], $repoJson @@ -173,125 +193,102 @@ protected function addRepositories(RootPackage $root) $newRepos[] = $repo; } - $root->setRepositories(array_merge( + $unwrapped = self::unwrapIfNeeded($root, 'setRepositories'); + $unwrapped->setRepositories(array_merge( $newRepos, $root->getRepositories() )); } /** - * Merge require into a RootPackage + * Merge require or require-dev into a RootPackageInterface * - * @param RootPackage $root + * @param string $type 'require' or 'require-dev' + * @param RootPackageInterface $root * @param PluginState $state */ - protected function mergeRequires(RootPackage $root, PluginState $state) - { - $requires = $this->package->getRequires(); + protected function mergeRequires( + $type, + RootPackageInterface $root, + PluginState $state + ) { + $linkType = BasePackage::$supportedLinkTypes[$type]; + $getter = 'get' . ucfirst($linkType['method']); + $setter = 'set' . ucfirst($linkType['method']); + + $requires = $this->package->{$getter}(); if (empty($requires)) { return; } $this->mergeStabilityFlags($root, $requires); - $dups = array(); - $root->setRequires($this->mergeLinks( - $root->getRequires(), + $requires = $this->replaceSelfVersionDependencies( + $type, $requires, - $state->replaceDuplicateLinks(), - $dups - )); - $state->addDuplicateLinks('require', $dups); - } - - /** - * Merge require-dev into RootPackage - * - * @param RootPackage $root - * @param PluginState $state - */ - protected function mergeDevRequires(RootPackage $root, PluginState $state) - { - $requires = $this->package->getDevRequires(); - if (empty($requires)) { - return; - } - - $this->mergeStabilityFlags($root, $requires); + $root + ); - $dups = array(); - $root->setDevRequires($this->mergeLinks( - $root->getDevRequires(), + $root->{$setter}($this->mergeOrDefer( + $type, + $root->{$getter}(), $requires, - $state->replaceDuplicateLinks(), - $dups + $state )); - $state->addDuplicateLinks('require-dev', $dups); } /** * Merge two collections of package links and collect duplicates for * subsequent processing. * + * @param string $type 'require' or 'require-dev' * @param array $origin Primary collection * @param array $merge Additional collection - * @param bool $replace Replace exising links? - * @param array &dups Duplicate storage + * @param PluginState $state * @return array Merged collection */ - protected function mergeLinks( + protected function mergeOrDefer( + $type, array $origin, array $merge, - $replace, - array &$dups + $state ) { + $dups = array(); foreach ($merge as $name => $link) { - if (!isset($origin[$name]) || $replace) { - $this->logger->debug("Merging {$name}"); + if (!isset($origin[$name]) || $state->replaceDuplicateLinks()) { + $this->logger->info("Merging {$name}"); $origin[$name] = $link; } else { // Defer to solver. - $this->logger->debug( + $this->logger->info( "Deferring duplicate {$name}" ); $dups[] = $link; } } + $state->addDuplicateLinks($type, $dups); return $origin; } /** - * Merge autoload into a RootPackage + * Merge autoload or autoload-dev into a RootPackageInterface * - * @param RootPackage $root + * @param string $type 'autoload' or 'devAutoload' + * @param RootPackageInterface $root */ - protected function mergeAutoload(RootPackage $root) + protected function mergeAutoload($type, RootPackageInterface $root) { - $autoload = $this->package->getAutoload(); - if (empty($autoload)) { - return; - } - - $root->setAutoload(array_merge_recursive( - $root->getAutoload(), - $this->fixRelativePaths($autoload) - )); - } + $getter = 'get' . ucfirst($type); + $setter = 'set' . ucfirst($type); - /** - * Merge autoload-dev into a RootPackage - * - * @param RootPackage $root - */ - protected function mergeDevAutoload(RootPackage $root) - { - $autoload = $this->package->getDevAutoload(); + $autoload = $this->package->{$getter}(); if (empty($autoload)) { return; } - $root->setDevAutoload(array_merge_recursive( - $root->getDevAutoload(), + $unwrapped = self::unwrapIfNeeded($root, $setter); + $unwrapped->{$setter}(array_merge_recursive( + $root->{$getter}(), $this->fixRelativePaths($autoload) )); } @@ -319,83 +316,64 @@ function (&$path) use ($base) { /** * Extract and merge stability flags from the given collection of - * requires and merge them into a RootPackage + * requires and merge them into a RootPackageInterface * - * @param RootPackage $root + * @param RootPackageInterface $root * @param array $requires */ protected function mergeStabilityFlags( - RootPackage $root, + RootPackageInterface $root, array $requires ) { $flags = $root->getStabilityFlags(); - foreach ($requires as $name => $link) { - $name = strtolower($name); - $version = $link->getPrettyConstraint(); - $stability = VersionParser::parseStability($version); - $flags[$name] = BasePackage::$stabilities[$stability]; - } - $root->setStabilityFlags($flags); - } - - /** - * Merge conflicting packages into a RootPackage - * - * @param RootPackage $root - */ - protected function mergeConflicts(RootPackage $root) - { - $conflicts = $this->package->getConflicts(); - if (!empty($conflicts)) { - $root->setconflicts(array_merge( - $root->getConflicts(), - $conflicts - )); - } - } + $sf = new StabilityFlags($flags, $root->getMinimumStability()); - /** - * Merge replaced packages into a RootPackage - * - * @param RootPackage $root - */ - protected function mergeReplaces(RootPackage $root) - { - $replaces = $this->package->getReplaces(); - if (!empty($replaces)) { - $root->setReplaces(array_merge( - $root->getReplaces(), - $replaces - )); - } + $unwrapped = self::unwrapIfNeeded($root, 'setStabilityFlags'); + $unwrapped->setStabilityFlags(array_merge( + $flags, + $sf->extractAll($requires) + )); } /** - * Merge provided virtual packages into a RootPackage + * Merge package links of the given type into a RootPackageInterface * - * @param RootPackage $root + * @param string $type 'conflict', 'replace' or 'provide' + * @param RootPackageInterface $root */ - protected function mergeProvides(RootPackage $root) + protected function mergePackageLinks($type, RootPackageInterface $root) { - $provides = $this->package->getProvides(); - if (!empty($provides)) { - $root->setProvides(array_merge( - $root->getProvides(), - $provides + $linkType = BasePackage::$supportedLinkTypes[$type]; + $getter = 'get' . ucfirst($linkType['method']); + $setter = 'set' . ucfirst($linkType['method']); + + $links = $this->package->{$getter}(); + if (!empty($links)) { + $unwrapped = self::unwrapIfNeeded($root, $setter); + if ($root !== $unwrapped) { + $this->logger->warning( + 'This Composer version does not support ' . + "'{$type}' merging for aliased packages." + ); + } + $unwrapped->{$setter}(array_merge( + $root->{$getter}(), + $this->replaceSelfVersionDependencies($type, $links, $root) )); } } /** - * Merge suggested packages into a RootPackage + * Merge suggested packages into a RootPackageInterface * - * @param RootPackage $root + * @param RootPackageInterface $root */ - protected function mergeSuggests(RootPackage $root) + protected function mergeSuggests(RootPackageInterface $root) { $suggests = $this->package->getSuggests(); if (!empty($suggests)) { - $root->setSuggests(array_merge( + $unwrapped = self::unwrapIfNeeded($root, 'setSuggests'); + $unwrapped->setSuggests(array_merge( $root->getSuggests(), $suggests )); @@ -403,12 +381,12 @@ protected function mergeSuggests(RootPackage $root) } /** - * Merge extra config into a RootPackage + * Merge extra config into a RootPackageInterface * - * @param RootPackage $root + * @param RootPackageInterface $root * @param PluginState $state */ - public function mergeExtra(RootPackage $root, PluginState $state) + public function mergeExtra(RootPackageInterface $root, PluginState $state) { $extra = $this->package->getExtra(); unset($extra['merge-plugin']); @@ -417,21 +395,93 @@ public function mergeExtra(RootPackage $root, PluginState $state) } $rootExtra = $root->getExtra(); + $unwrapped = self::unwrapIfNeeded($root, 'setExtra'); if ($state->replaceDuplicateLinks()) { - $root->setExtra(array_merge($rootExtra, $extra)); + $unwrapped->setExtra( + array_merge($rootExtra, $extra) + ); } else { - foreach ($extra as $key => $value) { - if (isset($rootExtra[$key])) { - $this->logger->debug( - "Ignoring duplicate {$key} in ". - "{$this->path} extra config." + foreach (array_intersect( + array_keys($extra), + array_keys($rootExtra) + ) as $key) { + $this->logger->info( + "Ignoring duplicate {$key} in ". + "{$this->path} extra config." + ); + } + $unwrapped->setExtra( + array_merge($extra, $rootExtra) + ); + } + } + + /** + * Update Links with a 'self.version' constraint with the root package's + * version. + * + * @param string $type Link type + * @param array $links + * @param RootPackageInterface $root + * @return array + */ + protected function replaceSelfVersionDependencies( + $type, + array $links, + RootPackageInterface $root + ) { + $linkType = BasePackage::$supportedLinkTypes[$type]; + $version = $root->getVersion(); + $prettyVersion = $root->getPrettyVersion(); + $vp = new VersionParser(); + + return array_map( + function ($link) use ($linkType, $version, $prettyVersion, $vp) { + if ('self.version' === $link->getPrettyConstraint()) { + return new Link( + $link->getSource(), + $link->getTarget(), + $vp->parseConstraints($version), + $linkType['description'], + $prettyVersion ); } - } - $root->setExtra(array_merge($extra, $rootExtra)); + return $link; + }, + $links + ); + } + + /** + * Get a full featured Package from a RootPackageInterface. + * + * In Composer versions before 599ad77 the RootPackageInterface only + * defines a sub-set of operations needed by composer-merge-plugin and + * RootAliasPackage only implemented those methods defined by the + * interface. Most of the unimplemented methods in RootAliasPackage can be + * worked around because the getter methods that are implemented proxy to + * the aliased package which we can modify by unwrapping. The exception + * being modifying the 'conflicts', 'provides' and 'replaces' collections. + * We have no way to actually modify those collections unfortunately in + * older versions of Composer. + * + * @param RootPackageInterface $root + * @param string $method Method needed + * @return RootPackageInterface|RootPackage + */ + public static function unwrapIfNeeded( + RootPackageInterface $root, + $method = 'setExtra' + ) { + if ($root instanceof RootAliasPackage && + !method_exists($root, $method) + ) { + // Unwrap and return the aliased RootPackage. + $root = $root->getAliasOf(); } + return $root; } } // vim:sw=4:ts=4:sts=4:et: diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/MissingFileException.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/MissingFileException.php new file mode 100644 index 0000000000000000000000000000000000000000..873719d7e8df980be02a46b45a86af9272f30511 --- /dev/null +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/MissingFileException.php @@ -0,0 +1,18 @@ + + */ +class MissingFileException extends \RuntimeException +{ +} diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php index 061a64de4de427ba1e2278240e4c684bafdda236..a191c1e84f769360f7733c0e30f6e1932d80c52a 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php @@ -11,9 +11,6 @@ namespace Wikimedia\Composer\Merge; use Composer\Composer; -use Composer\Package\AliasPackage; -use Composer\Package\RootPackage; -use UnexpectedValueException; /** * Mutable plugin state @@ -32,6 +29,11 @@ class PluginState */ protected $includes = array(); + /** + * @var array $requires + */ + protected $requires = array(); + /** * @var array $duplicateLinks */ @@ -52,6 +54,12 @@ class PluginState */ protected $replace = false; + /** + * Whether to merge the -dev sections. + * @var bool $mergeDev + */ + protected $mergeDev = true; + /** * Whether to merge the extra section. * @@ -99,12 +107,14 @@ public function __construct(Composer $composer) */ public function loadSettings() { - $extra = $this->getRootPackage()->getExtra(); + $extra = $this->composer->getPackage()->getExtra(); $config = array_merge( array( 'include' => array(), + 'require' => array(), 'recurse' => true, 'replace' => false, + 'merge-dev' => true, 'merge-extra' => false, ), isset($extra['merge-plugin']) ? $extra['merge-plugin'] : array() @@ -112,41 +122,32 @@ public function loadSettings() $this->includes = (is_array($config['include'])) ? $config['include'] : array($config['include']); + $this->requires = (is_array($config['require'])) ? + $config['require'] : array($config['require']); $this->recurse = (bool)$config['recurse']; $this->replace = (bool)$config['replace']; + $this->mergeDev = (bool)$config['merge-dev']; $this->mergeExtra = (bool)$config['merge-extra']; } /** - * Get the root package + * Get list of filenames and/or glob patterns to include * - * @return RootPackage + * @return array */ - public function getRootPackage() + public function getIncludes() { - $root = $this->composer->getPackage(); - if ($root instanceof AliasPackage) { - $root = $root->getAliasOf(); - } - // @codeCoverageIgnoreStart - if (!$root instanceof RootPackage) { - throw new UnexpectedValueException( - 'Expected instance of RootPackage, got ' . - get_class($root) - ); - } - // @codeCoverageIgnoreEnd - return $root; + return $this->includes; } /** - * Get list of filenames and/or glob patterns to include + * Get list of filenames and/or glob patterns to require * * @return array */ - public function getIncludes() + public function getRequires() { - return $this->includes; + return $this->requires; } /** @@ -216,7 +217,7 @@ public function setDevMode($flag) */ public function isDevMode() { - return $this->devMode; + return $this->mergeDev && $this->devMode; } /** diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/StabilityFlags.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/StabilityFlags.php new file mode 100644 index 0000000000000000000000000000000000000000..1c106e028bed968e3a956409928f642e3c5ff603 --- /dev/null +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/StabilityFlags.php @@ -0,0 +1,181 @@ + + */ +class StabilityFlags +{ + + /** + * @var array Current package name => stability mappings + */ + protected $stabilityFlags; + + /** + * @var int Current default minimum stability + */ + protected $minimumStability; + + /** + * @var string Regex to extract an explict stability flag (eg '@dev') + */ + protected $explicitStabilityRe; + + + /** + * @param array $stabilityFlags Current package name => stability mappings + * @param int $minimumStability Current default minimum stability + */ + public function __construct( + array $stabilityFlags = array(), + $minimumStability = BasePackage::STABILITY_STABLE + ) { + $this->stabilityFlags = $stabilityFlags; + $this->minimumStability = $this->getStabilityInt($minimumStability); + $this->explicitStabilityRe = '/^[^@]*?@(' . + implode('|', array_keys(BasePackage::$stabilities)) . + ')$/i'; + } + + /** + * Get the stability value for a given string. + * + * @param string $name Stability name + * @return int Stability value + */ + protected function getStabilityInt($name) + { + $name = VersionParser::normalizeStability($name); + return isset(BasePackage::$stabilities[$name]) ? + BasePackage::$stabilities[$name] : + BasePackage::STABILITY_STABLE; + } + + /** + * Extract and merge stability flags from the given collection of + * requires with another collection of stability flags. + * + * @param array $requires New package name => link mappings + * @return array Unified package name => stability mappings + */ + public function extractAll(array $requires) + { + $flags = array(); + + foreach ($requires as $name => $link) { + $name = strtolower($name); + $version = $link->getPrettyConstraint(); + + $stability = $this->getExplicitStability($version); + + if ($stability === null) { + $stability = $this->getParsedStability($version); + } + + $flags[$name] = max($stability, $this->getCurrentStability($name)); + } + + // Filter out null stability values + return array_filter($flags, function ($v) { + return $v !== null; + }); + } + + + /** + * Extract the most unstable explicit stability (eg '@dev') from a version + * specification. + * + * @param string $version + * @return int|null Stability or null if no explict stability found + */ + protected function getExplicitStability($version) + { + $found = null; + $constraints = $this->splitConstraints($version); + foreach ($constraints as $constraint) { + if (preg_match($this->explicitStabilityRe, $constraint, $match)) { + $stability = $this->getStabilityInt($match[1]); + $found = max($stability, $found); + } + } + return $found; + } + + + /** + * Split a version specification into a list of version constraints. + * + * @param string $version + * @return array + */ + protected function splitConstraints($version) + { + $found = array(); + $orConstraints = preg_split('/\s*\|\|?\s*/', trim($version)); + foreach ($orConstraints as $constraints) { + $andConstraints = preg_split( + '/(?< ,]) *(?getStabilityInt( + VersionParser::parseStability($version) + ); + + if ($stability === BasePackage::STABILITY_STABLE || + $this->minimumStability > $stability + ) { + // Ignore if 'stable' or more stable than the global + // minimum + $stability = null; + } + + return $stability; + } + + + /** + * Get the current stability of a given package. + * + * @param string $name + * @return int|null Stability of null if not set + */ + protected function getCurrentStability($name) + { + return isset($this->stabilityFlags[$name]) ? + $this->stabilityFlags[$name] : null; + } +} +// vim:sw=4:ts=4:sts=4:et: diff --git a/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php b/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php index 112d410398b170c84acda2926f8f7d3bf594c299..ea41d41a5827ef1227edd8d8ce9712ff80ac69d4 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php +++ b/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php @@ -11,6 +11,7 @@ namespace Wikimedia\Composer; use Wikimedia\Composer\Merge\ExtraPackage; +use Wikimedia\Composer\Merge\MissingFileException; use Wikimedia\Composer\Merge\PluginState; use Composer\Composer; @@ -23,7 +24,7 @@ use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvents; use Composer\IO\IOInterface; -use Composer\Package\RootPackage; +use Composer\Package\RootPackageInterface; use Composer\Plugin\PluginInterface; use Composer\Script\Event; use Composer\Script\ScriptEvents; @@ -32,13 +33,17 @@ * Composer plugin that allows merging multiple composer.json files. * * When installed, this plugin will look for a "merge-plugin" key in the - * composer configuration's "extra" section. The value of this setting can be - * either a single value or an array of values. Each value is treated as - * a glob() pattern identifying additional composer.json style configuration - * files to merge into the configuration for the current compser execution. + * composer configuration's "extra" section. The value for this key is + * a set of options configuring the plugin. * - * The "require", "require-dev", "repositories", "extra" and "suggest" sections - * of the found configuration files will be merged into the root package + * An "include" setting is required. The value of this setting can be either + * a single value or an array of values. Each value is treated as a glob() + * pattern identifying additional composer.json style configuration files to + * merge into the configuration for the current compser execution. + * + * The "autoload", "autoload-dev", "conflict", "provide", "replace", + * "repositories", "require", "require-dev", and "suggest" sections of the + * found configuration files will be merged into the root package * configuration as though they were directly included in the top-level * composer.json file. * @@ -48,10 +53,10 @@ * change this default behaviour so that the last-defined version of a package * will win, allowing for force-overrides of package defines. * - * By default the "extra" section is not merged. This can be enabled with the - * 'merge-extra' key by setting it to true. In normal mode, when the same key - * is found in both the original and the imported extra section, the version - * in the original config is used and the imported version is skipped. If + * By default the "extra" section is not merged. This can be enabled by + * setitng the 'merge-extra' key to true. In normal mode, when the same key is + * found in both the original and the imported extra section, the version in + * the original config is used and the imported version is skipped. If * 'replace' mode is active, this behaviour changes so the imported version of * the key is used, replacing the version in the original config. * @@ -140,7 +145,8 @@ public function onInstallUpdateOrDump(Event $event) { $this->state->loadSettings(); $this->state->setDevMode($event->isDevMode()); - $this->mergeIncludes($this->state->getIncludes()); + $this->mergeFiles($this->state->getIncludes(), false); + $this->mergeFiles($this->state->getRequires(), true); if ($event->getName() === ScriptEvents::PRE_AUTOLOAD_DUMP) { $this->state->setDumpAutoloader(true); @@ -155,16 +161,29 @@ public function onInstallUpdateOrDump(Event $event) * Find configuration files matching the configured glob patterns and * merge their contents with the master package. * - * @param array $includes List of files/glob patterns + * @param array $patterns List of files/glob patterns + * @param bool $required Are the patterns required to match files? + * @throws MissingFileException when required and a pattern returns no + * results */ - protected function mergeIncludes(array $includes) + protected function mergeFiles(array $patterns, $required = false) { - $root = $this->state->getRootPackage(); - foreach (array_reduce( - array_map('glob', $includes), - 'array_merge', - array() - ) as $path) { + $root = $this->composer->getPackage(); + + $files = array_map( + function ($files, $pattern) use ($required) { + if ($required && !$files) { + throw new MissingFileException( + "merge-plugin: No files matched required '{$pattern}'" + ); + } + return $files; + }, + array_map('glob', $patterns), + $patterns + ); + + foreach (array_reduce($files, 'array_merge', array()) as $path) { $this->mergeFile($root, $path); } } @@ -172,26 +191,25 @@ protected function mergeIncludes(array $includes) /** * Read a JSON file and merge its contents * - * @param RootPackage $root + * @param RootPackageInterface $root * @param string $path */ - protected function mergeFile(RootPackage $root, $path) + protected function mergeFile(RootPackageInterface $root, $path) { if (isset($this->loadedFiles[$path])) { - $this->logger->debug( - "Skipping duplicate $path..." - ); + $this->logger->debug("Already merged $path"); return; } else { $this->loadedFiles[$path] = true; } - $this->logger->debug("Loading {$path}..."); + $this->logger->info("Loading {$path}..."); $package = new ExtraPackage($path, $this->composer, $this->logger); $package->mergeInto($root, $this->state); if ($this->state->recurseIncludes()) { - $this->mergeIncludes($package->getIncludes()); + $this->mergeFiles($package->getIncludes(), false); + $this->mergeFiles($package->getRequires(), true); } } @@ -207,14 +225,14 @@ public function onDependencySolve(InstallerEvent $event) { $request = $event->getRequest(); foreach ($this->state->getDuplicateLinks('require') as $link) { - $this->logger->debug( + $this->logger->info( "Adding dependency {$link}" ); $request->install($link->getTarget(), $link->getConstraint()); } if ($this->state->isDevMode()) { foreach ($this->state->getDuplicateLinks('require-dev') as $link) { - $this->logger->debug( + $this->logger->info( "Adding dev dependency {$link}" ); $request->install($link->getTarget(), $link->getConstraint()); @@ -234,7 +252,7 @@ public function onPostPackageInstall(PackageEvent $event) if ($op instanceof InstallOperation) { $package = $op->getPackage()->getName(); if ($package === self::PACKAGE_NAME) { - $this->logger->debug('composer-merge-plugin installed'); + $this->logger->info('composer-merge-plugin installed'); $this->state->setFirstInstall(true); $this->state->setLocked( $event->getComposer()->getLocker()->isLocked() @@ -255,7 +273,7 @@ public function onPostInstallOrUpdate(Event $event) // @codeCoverageIgnoreStart if ($this->state->isFirstInstall()) { $this->state->setFirstInstall(false); - $this->logger->debug( + $this->logger->info( '' . 'Running additional update to apply merge settings' . ''