Legoktm has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/186380

Change subject: Add wikimedia/composer-merge-plugin 0.5.0
......................................................................

Add wikimedia/composer-merge-plugin 0.5.0

This code will not be run on the WMF cluster, but is necessary
so that users who use mediawiki/vendor can still run update.php
once it begins to run checkComposerLockUpToDate.php.

Change-Id: I72f89c435d75fb8eb6ad77d10f83fe1cad8d9e5b
---
M composer.json
M composer.lock
M composer/autoload_classmap.php
M composer/autoload_psr4.php
M composer/installed.json
A wikimedia/composer-merge-plugin/.gitignore
A wikimedia/composer-merge-plugin/.scrutinizer.yml
A wikimedia/composer-merge-plugin/.travis.yml
A wikimedia/composer-merge-plugin/LICENSE
A wikimedia/composer-merge-plugin/README.md
A wikimedia/composer-merge-plugin/composer.json
A wikimedia/composer-merge-plugin/example/.gitignore
A wikimedia/composer-merge-plugin/example/composer.json
A wikimedia/composer-merge-plugin/example/composer.local.json
A wikimedia/composer-merge-plugin/example/extensions/Foo/composer.json
A wikimedia/composer-merge-plugin/phpunit.xml.dist
A wikimedia/composer-merge-plugin/src/MergePlugin.php
A wikimedia/composer-merge-plugin/tests/phpunit/MergePluginTest.php
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.local.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.local.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.local.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/extensions/Foo/composer.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.json
A 
wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.local.json
27 files changed, 1,170 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vendor 
refs/changes/80/186380/1

diff --git a/composer.json b/composer.json
index 5616130..2bccf89 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,8 @@
                "Plancake/EmailParser": 
"dev-master#e7453ead1f3a74810d8050a30afb96feed74477a",
                "ruflin/elastica": "1.3.0.0",
                "oojs/oojs-ui": "0.6.3",
-               "wikimedia/cdb": "1.0.1"
+               "wikimedia/cdb": "1.0.1",
+               "wikimedia/composer-merge-plugin": "0.5.0"
        },
        "prefer-stable": true,
        "config": {
diff --git a/composer.lock b/composer.lock
index fc08191..44c8711 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at 
http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file";,
         "This file is @generated automatically"
     ],
-    "hash": "27b4084e1b32f5a6133e21941e1c0506",
+    "hash": "fcf22e8da6ae285a912ad68235f3cfc6",
     "packages": [
         {
             "name": "Plancake/EmailParser",
@@ -368,6 +368,47 @@
             "description": "Constant Database (CDB) wrapper library for PHP. 
Provides pure-PHP fallback when dba_* functions are absent.",
             "homepage": "https://www.mediawiki.org/wiki/CDB";,
             "time": "2014-12-08 19:26:44"
+        },
+        {
+            "name": "wikimedia/composer-merge-plugin",
+            "version": "v0.5.0",
+            "source": {
+                "type": "git",
+                "url": 
"https://github.com/wikimedia/composer-merge-plugin.git";,
+                "reference": "08ad40053b14d564dcd2a02239f67caa20d9ea75"
+            },
+            "dist": {
+                "type": "zip",
+                "url": 
"https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/08ad40053b14d564dcd2a02239f67caa20d9ea75";,
+                "reference": "08ad40053b14d564dcd2a02239f67caa20d9ea75",
+                "shasum": ""
+            },
+            "require": {
+                "composer-plugin-api": "1.0.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"
+            },
+            "type": "composer-plugin",
+            "extra": {
+                "class": "Wikimedia\\Composer\\MergePlugin"
+            },
+            "autoload": {
+                "psr-4": {
+                    "Wikimedia\\Composer\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/";,
+            "license": [
+                "MIT"
+            ],
+            "description": "Composer plugin to merge multiple composer.json 
files",
+            "time": "2014-12-29 20:05:19"
         }
     ],
     "packages-dev": [],
@@ -377,7 +418,6 @@
         "plancake/emailparser": 20
     },
     "prefer-stable": true,
-    "prefer-lowest": false,
     "platform": {
         "php": ">=5.3.3"
     },
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index 494f432..8acdb00 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -307,6 +307,7 @@
     'Psr\\Log\\LoggerAwareInterface' => $vendorDir . 
'/psr/log/Psr/Log/LoggerAwareInterface.php',
     'Psr\\Log\\LoggerInterface' => $vendorDir . 
'/psr/log/Psr/Log/LoggerInterface.php',
     'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
+    'Wikimedia\\Composer\\MergePlugin' => $vendorDir . 
'/wikimedia/composer-merge-plugin/src/MergePlugin.php',
     'lessc' => $vendorDir . '/leafo/lessphp/lessc.inc.php',
     'lessc_formatter_classic' => $vendorDir . '/leafo/lessphp/lessc.inc.php',
     'lessc_formatter_compressed' => $vendorDir . 
'/leafo/lessphp/lessc.inc.php',
diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php
index a06d53c..abd6ba8 100644
--- a/composer/autoload_psr4.php
+++ b/composer/autoload_psr4.php
@@ -6,5 +6,6 @@
 $baseDir = $vendorDir;
 
 return array(
+    'Wikimedia\\Composer\\' => array($vendorDir . 
'/wikimedia/composer-merge-plugin/src'),
     'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
 );
diff --git a/composer/installed.json b/composer/installed.json
index 02f23f5..ed8cfe8 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -377,5 +377,48 @@
             "MIT"
         ],
         "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";
+    },
+    {
+        "name": "wikimedia/composer-merge-plugin",
+        "version": "v0.5.0",
+        "version_normalized": "0.5.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/wikimedia/composer-merge-plugin.git";,
+            "reference": "08ad40053b14d564dcd2a02239f67caa20d9ea75"
+        },
+        "dist": {
+            "type": "zip",
+            "url": 
"https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/08ad40053b14d564dcd2a02239f67caa20d9ea75";,
+            "reference": "08ad40053b14d564dcd2a02239f67caa20d9ea75",
+            "shasum": ""
+        },
+        "require": {
+            "composer-plugin-api": "1.0.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": "2014-12-29 20:05:19",
+        "type": "composer-plugin",
+        "extra": {
+            "class": "Wikimedia\\Composer\\MergePlugin"
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Wikimedia\\Composer\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/";,
+        "license": [
+            "MIT"
+        ],
+        "description": "Composer plugin to merge multiple composer.json files"
     }
 ]
diff --git a/wikimedia/composer-merge-plugin/.gitignore 
b/wikimedia/composer-merge-plugin/.gitignore
new file mode 100644
index 0000000..6e09c41
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/.gitignore
@@ -0,0 +1,6 @@
+/.php-version
+/composer.lock
+/composer.phar
+/phpunit.xml
+/reports
+/vendor
diff --git a/wikimedia/composer-merge-plugin/.scrutinizer.yml 
b/wikimedia/composer-merge-plugin/.scrutinizer.yml
new file mode 100644
index 0000000..f851c82
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/.scrutinizer.yml
@@ -0,0 +1,58 @@
+filter:
+    excluded_paths:
+        - 'tests/*'
+
+checks:
+    php:
+        php5_style_constructor: true
+        parameters_in_camelcaps: true
+        parameter_non_unique: true
+        parameter_doc_comments: true
+        param_doc_comment_if_not_inferrable: true
+        overriding_private_members: true
+        optional_parameters_at_the_end: true
+        one_class_per_file: true
+        non_commented_empty_catch_block: true
+        no_unnecessary_if: true
+        code_rating: true
+        duplication: true
+        variable_existence: true
+        useless_calls: true
+        use_statement_alias_conflict: true
+        unused_variables: true
+        unused_properties: true
+        unused_methods: true
+        unreachable_code: true
+        sql_injection_vulnerabilities: true
+        security_vulnerabilities: true
+        precedence_mistakes: true
+        precedence_in_conditions: true
+        no_property_on_interface: true
+        no_non_implemented_abstract_methods: true
+        deprecated_code_usage: true
+        closure_use_not_conflicting: true
+        closure_use_modifiable: true
+        avoid_useless_overridden_methods: true
+        avoid_conflicting_incrementers: true
+        assignment_of_null_return: true
+        avoid_corrupting_byteorder_marks: true
+
+tools:
+    external_code_coverage:
+        timeout: 300
+        runs: 1
+    php_analyzer: true
+    php_code_coverage: false
+    php_code_sniffer:
+        config:
+            standard: PSR2
+        filter:
+            paths: ['src','tests']
+    php_cpd:
+        enabled: true
+        excluded_dirs: ['vendor', 'tests', 'example']
+    php_loc:
+        enabled: true
+        excluded_dirs: ['vendor', 'tests', 'example']
+    php_pdepend: true
+    php_sim: true
diff --git a/wikimedia/composer-merge-plugin/.travis.yml 
b/wikimedia/composer-merge-plugin/.travis.yml
new file mode 100644
index 0000000..9ec8e7e
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/.travis.yml
@@ -0,0 +1,26 @@
+language: php
+
+php:
+  - "5.3.3"
+  - "5.3"
+  - "5.4"
+  - "5.5"
+  - "5.6"
+  - "hhvm"
+
+sudo: false
+
+install: travis_retry composer install --no-interaction --prefer-source
+
+script: composer test
+
+after_script:
+  - wget https://scrutinizer-ci.com/ocular.phar
+  - php ocular.phar code-coverage:upload --format=php-clover 
reports/coverage.xml
+
+notifications:
+  irc:
+    channels:
+      - "chat.freenode.net#wikimedia-dev"
+    template:
+      - "%{repository}#%{build_number} (%{branch} - %{commit} %{author}): 
%{message} - %{build_url}"
diff --git a/wikimedia/composer-merge-plugin/LICENSE 
b/wikimedia/composer-merge-plugin/LICENSE
new file mode 100644
index 0000000..55e376b
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Bryan Davis, Wikimedia Foundation, and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wikimedia/composer-merge-plugin/README.md 
b/wikimedia/composer-merge-plugin/README.md
new file mode 100644
index 0000000..668cf78
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/README.md
@@ -0,0 +1,77 @@
+[![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)
+
+Composer Merge Plugin
+=====================
+
+Merge one or more additional composer.json files at runtime.
+
+Installation
+------------
+```
+$ composer require wikimedia/composer-merge-plugin
+```
+
+Usage
+-----
+
+```
+{
+    "require": {
+        "wikimedia/composer-merge-plugin": "dev-master"
+    },
+    "extra": {
+        "merge-plugin": {
+            "include": [
+                "composer.local.json",
+                "extensions/*/composer.json"
+            ]
+        }
+    }
+}
+```
+
+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.
+
+The "require", "require-dev", "repositories" 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.
+
+Running tests
+-------------
+```
+$ composer install
+$ 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.
+
+- [PSR-2 Coding Standard][] is used by the project. The included test
+  configuration uses [PHP Code Sniffer][] to validate the conventions.
+- Tests are encouraged. Our test coverage isn't perfect but we'd like it to
+  get better rather than worse, so please try to include tests with your
+  changes.
+- Keep the documentation up to date. Make sure `README.md` and other
+  relevant documentation is kept up to date with your changes.
+- One pull request per feature. Try to keep your changes focused on solving
+  a single problem. This will make it easier for us to review the change and
+  easier for you to make sure you have updated the necessary tests and
+  documentation.
+
+License
+-------
+Composer Merge plugin is licensed under the MIT license. See the `LICENSE`
+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
diff --git a/wikimedia/composer-merge-plugin/composer.json 
b/wikimedia/composer-merge-plugin/composer.json
new file mode 100644
index 0000000..5ef429a
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/composer.json
@@ -0,0 +1,38 @@
+{
+    "name": "wikimedia/composer-merge-plugin",
+    "description": "Composer plugin to merge multiple composer.json files",
+    "type": "composer-plugin",
+    "license": "MIT",
+    "minimum-stability": "dev",
+    "prefer-stable": true,
+    "require": {
+        "php": ">=5.3.2",
+        "composer-plugin-api": "1.0.0"
+    },
+    "require-dev": {
+        "composer/composer": "1.0.*@dev",
+        "phpunit/phpunit": "~4.0",
+        "jakub-onderka/php-parallel-lint": "~0.8",
+        "squizlabs/php_codesniffer": "~2.1.0",
+        "phpspec/prophecy-phpunit": "~1.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Wikimedia\\Composer\\": "src/"
+        }
+    },
+    "extra": {
+        "class": "Wikimedia\\Composer\\MergePlugin"
+    },
+    "config": {
+        "optimize-autoloader": true
+    },
+    "scripts": {
+        "test": [
+            "composer validate --no-interaction",
+            "parallel-lint src tests",
+            "phpunit --log-junit=reports/unitreport.xml --coverage-text 
--coverage-html=reports/coverage --coverage-clover=reports/coverage.xml",
+            "phpcs --encoding=utf-8 --standard=PSR2 
--report-checkstyle=reports/checkstyle-phpcs.xml --report-full --extensions=php 
src/* tests/phpunit/*"
+        ]
+    }
+}
diff --git a/wikimedia/composer-merge-plugin/example/.gitignore 
b/wikimedia/composer-merge-plugin/example/.gitignore
new file mode 100644
index 0000000..ff72e2d
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/example/.gitignore
@@ -0,0 +1,2 @@
+/composer.lock
+/vendor
diff --git a/wikimedia/composer-merge-plugin/example/composer.json 
b/wikimedia/composer-merge-plugin/example/composer.json
new file mode 100644
index 0000000..91c2175
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/example/composer.json
@@ -0,0 +1,22 @@
+{
+    "repositories": [
+        {
+            "type": "vcs",
+            "url": "./.."
+        }
+    ],
+    "require": {
+        "wikimedia/composer-merge-plugin": "*@dev"
+    },
+    "config": {
+        "preferred-install": "source"
+    },
+    "extra": {
+        "merge-plugin": {
+            "include": [
+                "composer.local.json",
+                "extensions/*/composer.json"
+            ]
+        }
+    }
+}
diff --git a/wikimedia/composer-merge-plugin/example/composer.local.json 
b/wikimedia/composer-merge-plugin/example/composer.local.json
new file mode 100644
index 0000000..4928c06
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/example/composer.local.json
@@ -0,0 +1,5 @@
+{
+    "require": {
+        "monolog/monolog": "~1.0"
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/example/extensions/Foo/composer.json 
b/wikimedia/composer-merge-plugin/example/extensions/Foo/composer.json
new file mode 100644
index 0000000..7e36e3f
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/example/extensions/Foo/composer.json
@@ -0,0 +1,6 @@
+{
+    "require": {
+        "wikimedia/cdb": "~1.0.0",
+        "monolog/monolog": "1.10.0"
+    }
+}
diff --git a/wikimedia/composer-merge-plugin/phpunit.xml.dist 
b/wikimedia/composer-merge-plugin/phpunit.xml.dist
new file mode 100644
index 0000000..b96cdab
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/phpunit.xml.dist
@@ -0,0 +1,12 @@
+<phpunit colors="true" strict="true">
+    <testsuites>
+        <testsuite name="Tests">
+            <directory>./tests/phpunit</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist addUncoveredFilesFromWhitelist="true">
+            <directory suffix=".php">./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/wikimedia/composer-merge-plugin/src/MergePlugin.php 
b/wikimedia/composer-merge-plugin/src/MergePlugin.php
new file mode 100644
index 0000000..8555ebb
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/src/MergePlugin.php
@@ -0,0 +1,375 @@
+<?php
+/**
+ * This file is part of the Composer Merge plugin.
+ *
+ * Copyright (C) 2014 Bryan Davis, Wikimedia Foundation, and contributors
+ *
+ * This software may be modified and distributed under the terms of the MIT
+ * license. See the LICENSE file for details.
+ */
+
+namespace Wikimedia\Composer;
+
+use Composer\Composer;
+use Composer\Config;
+use Composer\EventDispatcher\EventSubscriberInterface;
+use Composer\Factory;
+use Composer\Installer\InstallerEvent;
+use Composer\Installer\InstallerEvents;
+use Composer\IO\IOInterface;
+use Composer\Json\JsonFile;
+use Composer\Package\BasePackage;
+use Composer\Package\CompletePackage;
+use Composer\Package\LinkConstraint\SpecificConstraint;
+use Composer\Package\Loader\ArrayLoader;
+use Composer\Package\RootPackageInterface;
+use Composer\Package\Version\VersionParser;
+use Composer\Plugin\PluginInterface;
+use Composer\Script\CommandEvent;
+use Composer\Script\ScriptEvents;
+
+/**
+ * Composer plugin that allows merging multiple composer.json files.
+ *
+ * When installed, this plugin will look for a "merge-patterns" 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.
+ *
+ * The "require", "require-dev", "repositories" 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.
+ *
+ * If included files specify conflicting package versions for "require" or
+ * "require-dev", the normal Composer dependency solver process will be used
+ * to attempt to resolve the conflict.
+ *
+ * @code
+ * {
+ *     "require": {
+ *         "wikimedia/composer-merge-plugin": "dev-master"
+ *     },
+ *     "extra": {
+ *         "merge-plugin": {
+ *             "include": [
+ *                 "composer.local.json"
+ *             ]
+ *         }
+ *     }
+ * }
+ * @endcode
+ *
+ * @author Bryan Davis <[email protected]>
+ */
+class MergePlugin implements PluginInterface, EventSubscriberInterface
+{
+
+    /**
+     * @var Composer $composer
+     */
+    protected $composer;
+
+    /**
+     * @var IOInterface $inputOutput
+     */
+    protected $inputOutput;
+
+    /**
+     * @var ArrayLoader $loader
+     */
+    protected $loader;
+
+    /**
+     * @var array $duplicateLinks
+     */
+    protected $duplicateLinks;
+
+    /**
+     * @var bool $devMode
+     */
+    protected $devMode;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function activate(Composer $composer, IOInterface $io)
+    {
+        $this->composer = $composer;
+        $this->inputOutput = $io;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public static function getSubscribedEvents()
+    {
+        return array(
+            InstallerEvents::PRE_DEPENDENCIES_SOLVING => 'onDependencySolve',
+            ScriptEvents::PRE_INSTALL_CMD => 'onInstallOrUpdate',
+            ScriptEvents::PRE_UPDATE_CMD => 'onInstallOrUpdate',
+        );
+    }
+
+    /**
+     * Handle an event callback for an install or update command by checking
+     * for "merge-patterns" in the "extra" data and merging package contents
+     * if found.
+     *
+     * @param CommandEvent $event
+     */
+    public function onInstallOrUpdate(CommandEvent $event)
+    {
+        $config = $this->readConfig($this->composer->getPackage());
+        if ($config['include']) {
+            $this->loader = new ArrayLoader();
+            $this->duplicateLinks = array(
+                'require' => array(),
+                'require-dev' => array(),
+            );
+            $this->devMode = $event->isDevMode();
+            $this->mergePackages($config);
+        }
+    }
+
+    /**
+     * @param RootPackageInterface $package
+     * @return array
+     */
+    protected function readConfig(RootPackageInterface $package)
+    {
+        $config = array(
+            'include' => array(),
+        );
+        $extra = $package->getExtra();
+        if (isset($extra['merge-plugin'])) {
+            $config = array_merge($config, $extra['merge-plugin']);
+            if (!is_array($config['include'])) {
+                $config['include'] = array($config['include']);
+            }
+        }
+        return $config;
+    }
+
+    /**
+     * Find configuration files matching the configured glob patterns and
+     * merge their contents with the master package.
+     *
+     * @param array $config
+     */
+    protected function mergePackages(array $config)
+    {
+        $root = $this->composer->getPackage();
+        foreach (array_unique(array_reduce(
+            array_map('glob', $config['include']),
+            'array_merge',
+            array()
+        )) as $path) {
+            $this->debug("Loading <comment>{$path}</comment>...");
+            $json = $this->readPackageJson($path);
+            $package = $this->loader->load($json);
+
+            $this->mergeRequires($root, $package);
+            $this->mergeDevRequires($root, $package);
+
+            if (isset($json['repositories'])) {
+                $this->addRepositories($json['repositories'], $root);
+            }
+
+            if ($package->getSuggests()) {
+                $root->setSuggests(array_merge(
+                    $root->getSuggests(),
+                    $package->getSuggests()
+                ));
+            }
+        }
+    }
+
+    /**
+     * Read the contents of a composer.json style file into an array.
+     *
+     * The package contents are fixed up to be usable to create a Package
+     * object by providing dummy "name" and "version" values if they have not
+     * been provided in the file. This is consistent with the default root
+     * package loading behavior of Composer.
+     *
+     * @param string $path
+     * @return array
+     */
+    protected function readPackageJson($path)
+    {
+        $file = new JsonFile($path);
+        $json = $file->read();
+        if (!isset($json['name'])) {
+            $json['name'] = 'merge-plugin/' .
+                strtr($path, DIRECTORY_SEPARATOR, '-');
+        }
+        if (!isset($json['version'])) {
+            $json['version'] = '1.0.0';
+        }
+        return $json;
+    }
+
+    /**
+     * @param RootPackageInterface $root
+     * @param CompletePackage $package
+     */
+    protected function mergeRequires(
+        RootPackageInterface $root,
+        CompletePackage $package
+    ) {
+        $requires = $package->getRequires();
+        if (!$requires) {
+            return;
+        }
+
+        $this->mergeStabilityFlags($root, $requires);
+
+        $root->setRequires($this->mergeLinks(
+            $root->getRequires(),
+            $requires,
+            $this->duplicateLinks['require']
+        ));
+    }
+
+    /**
+     * @param RootPackageInterface $root
+     * @param CompletePackage $package
+     */
+    protected function mergeDevRequires(
+        RootPackageInterface $root,
+        CompletePackage $package
+    ) {
+        $requires = $package->getDevRequires();
+        if (!$requires) {
+            return;
+        }
+
+        $this->mergeStabilityFlags($root, $requires);
+
+        $root->setDevRequires($this->mergeLinks(
+            $root->getDevRequires(),
+            $requires,
+            $this->duplicateLinks['require-dev']
+        ));
+    }
+
+    /**
+     * Extract and merge stability flags from the given collection of
+     * requires.
+     *
+     * @param RootPackageInterface $root
+     * @param array $requires
+     */
+    protected function mergeStabilityFlags(
+        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);
+    }
+
+    /**
+     * Add a collection of repositories described by the given configuration
+     * to the given package and the global repository manager.
+     *
+     * @param array $repositories
+     * @param RootPackageInterface $root
+     */
+    protected function addRepositories(
+        array $repositories,
+        RootPackageInterface $root
+    ) {
+        $repoManager = $this->composer->getRepositoryManager();
+        $newRepos = array();
+
+        foreach ($repositories as $repoJson) {
+            $this->debug("Adding {$repoJson['type']} repository");
+            $repo = $repoManager->createRepository(
+                $repoJson['type'],
+                $repoJson
+            );
+            $repoManager->addRepository($repo);
+            $newRepos[] = $repo;
+        }
+
+        $root->setRepositories(array_merge(
+            $newRepos,
+            $root->getRepositories()
+        ));
+    }
+
+    /**
+     * Merge two collections of package links and collect duplicates for
+     * subsequent processing.
+     *
+     * @param array $origin Primary collection
+     * @param array $merge Additional collection
+     * @param array &dups Duplicate storage
+     * @return array Merged collection
+     */
+    protected function mergeLinks(array $origin, array $merge, array &$dups)
+    {
+        foreach ($merge as $name => $link) {
+            if (!isset($origin[$name])) {
+                $this->debug("Merging <comment>{$name}</comment>");
+                $origin[$name] = $link;
+            } else {
+                // Defer to solver.
+                $this->debug("Deferring duplicate <comment>{$name}</comment>");
+                $dups[] = $link;
+            }
+        }
+        return $origin;
+    }
+
+    /**
+     * Handle an event callback for pre-dependency solving phase of an install
+     * or update by adding any duplicate package dependencies found during
+     * initial merge processing to the request that will be processed by the
+     * dependency solver.
+     *
+     * @param InstallerEvent $event
+     */
+    public function onDependencySolve(InstallerEvent $event)
+    {
+        if (!$this->duplicateLinks) {
+            return;
+        }
+
+        $request = $event->getRequest();
+        foreach ($this->duplicateLinks['require'] as $link) {
+            $this->debug("Adding dependency <comment>{$link}</comment>");
+            $request->install($link->getTarget(), $link->getConstraint());
+        }
+        if ($this->devMode) {
+            foreach ($this->duplicateLinks['require-dev'] as $link) {
+                $this->debug("Adding dev dependency 
<comment>{$link}</comment>");
+                $request->install($link->getTarget(), $link->getConstraint());
+            }
+        }
+    }
+
+    /**
+     * Log a debug message
+     *
+     * Messages will be output at the "verbose" logging level (eg `-v` needed
+     * on the Composer command).
+     *
+     * @param string $message
+     */
+    protected function debug($message)
+    {
+        if ($this->inputOutput->isVerbose()) {
+            $this->inputOutput->write("  <info>[merge]</info> {$message}");
+        }
+    }
+}
+// vim:sw=4:ts=4:sts=4:et:
diff --git a/wikimedia/composer-merge-plugin/tests/phpunit/MergePluginTest.php 
b/wikimedia/composer-merge-plugin/tests/phpunit/MergePluginTest.php
new file mode 100644
index 0000000..d4271fd
--- /dev/null
+++ b/wikimedia/composer-merge-plugin/tests/phpunit/MergePluginTest.php
@@ -0,0 +1,351 @@
+<?php
+/**
+ * This file is part of the Composer Merge plugin.
+ *
+ * Copyright (C) 2014 Bryan Davis, Wikimedia Foundation, and contributors
+ *
+ * This software may be modified and distributed under the terms of the MIT
+ * license. See the LICENSE file for details.
+ */
+
+namespace Wikimedia\Composer;
+
+use Composer\Composer;
+use Composer\Installer\InstallerEvent;
+use Composer\Installer\InstallerEvents;
+use Composer\IO\IOInterface;
+use Composer\Package\BasePackage;
+use Composer\Package\PackageInterface;
+use Composer\Package\RootPackage;
+use Composer\Script\CommandEvent;
+use Composer\Script\ScriptEvents;
+use Prophecy\Argument;
+
+/**
+ * @covers Wikimedia\Composer\MergePlugin
+ */
+class MergePluginTest extends \Prophecy\PhpUnit\ProphecyTestCase
+{
+
+    /**
+     * @var Composer
+     */
+    protected $composer;
+
+    /**
+     * @var IOInterface
+     */
+    protected $io;
+
+    /**
+     * @var MergePlugin
+     */
+    protected $fixture;
+
+    protected function setUp()
+    {
+        parent::setUp();
+        $this->composer = $this->prophesize('Composer\Composer');
+        $this->io = $this->prophesize('Composer\IO\IOInterface');
+
+        $this->fixture = new MergePlugin();
+        $this->fixture->activate(
+            $this->composer->reveal(),
+            $this->io->reveal()
+        );
+    }
+
+    public function testSubscribedEvents()
+    {
+        $subscriptions = MergePlugin::getSubscribedEvents();
+        $this->assertEquals(3, count($subscriptions));
+        $this->assertArrayHasKey(
+            InstallerEvents::PRE_DEPENDENCIES_SOLVING,
+            $subscriptions
+        );
+        $this->assertArrayHasKey(ScriptEvents::PRE_INSTALL_CMD, 
$subscriptions);
+        $this->assertArrayHasKey(ScriptEvents::PRE_UPDATE_CMD, $subscriptions);
+    }
+
+    /**
+     * Given a root package with no requires
+     *   and a composer.local.json with one require
+     * When the plugin is run
+     * Then the root package should inherit the require
+     *   and no modifications should be made by the pre-dependency hook.
+     */
+    public function testOneMergeNoConflicts()
+    {
+        $that = $this;
+        $dir = $this->fixtureDir(__FUNCTION__);
+
+        $root = $this->rootFromJson("{$dir}/composer.json");
+
+        $root->setRequires(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $requires = $args[0];
+                $that->assertEquals(1, count($requires));
+                $that->assertArrayHasKey('monolog/monolog', $requires);
+            }
+        );
+
+        $root->getDevRequires()->shouldNotBeCalled();
+        $root->getRepositories()->shouldNotBeCalled();
+        $root->getSuggests()->shouldNotBeCalled();
+
+        $extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
+
+        $this->assertEquals(0, count($extraInstalls));
+    }
+
+    /**
+     * Given a root package with requires
+     *   and a composer.local.json with requires
+     *   and the same package is listed in multiple files
+     * When the plugin is run
+     * Then the root package should inherit the non-conflicting requires
+     *   and extra installs should be proposed by the pre-dependency hook.
+     */
+    public function testOneMergeWithConflicts()
+    {
+        $that = $this;
+        $dir = $this->fixtureDir(__FUNCTION__);
+
+        $root = $this->rootFromJson("{$dir}/composer.json");
+
+        $root->setRequires(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $requires = $args[0];
+                $that->assertEquals(2, count($requires));
+                $that->assertArrayHasKey(
+                    'wikimedia/composer-merge-plugin',
+                    $requires
+                );
+                $that->assertArrayHasKey('monolog/monolog', $requires);
+            }
+        );
+
+        $root->getDevRequires()->shouldBeCalled();
+        $root->setDevRequires(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $requires = $args[0];
+                $that->assertEquals(2, count($requires));
+                $that->assertArrayHasKey('foo', $requires);
+                $that->assertArrayHasKey('xyzzy', $requires);
+            }
+        );
+
+        $root->getRepositories()->shouldNotBeCalled();
+        $root->getSuggests()->shouldNotBeCalled();
+
+        $extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
+
+        $this->assertEquals(1, count($extraInstalls));
+        $this->assertEquals('monolog/monolog', $extraInstalls[0][0]);
+    }
+
+    /**
+     * Given a root package
+     *   and a composer.local.json with a repository
+     * When the plugin is run
+     * Then the root package should inherit the repository
+     */
+    public function testMergedRepositories()
+    {
+        $that = $this;
+        $io = $this->io;
+        $dir = $this->fixtureDir(__FUNCTION__);
+
+        $repoManager = $this->prophesize(
+            'Composer\Repository\RepositoryManager'
+        );
+        $repoManager->createRepository(
+            Argument::type('string'),
+            Argument::type('array')
+        )->will(
+            function ($args) use ($that, $io) {
+                $that->assertEquals('vcs', $args[0]);
+                $that->assertEquals(
+                    'https://github.com/bd808/composer-merge-plugin.git',
+                    $args[1]['url']
+                );
+
+                return new \Composer\Repository\VcsRepository(
+                    $args[1],
+                    $io->reveal(),
+                    new \Composer\Config()
+                );
+            }
+        );
+        $repoManager->addRepository(Argument::any())->will(
+            function ($args) use ($that) {
+                $that->assertInstanceOf(
+                    'Composer\Repository\VcsRepository',
+                    $args[0]
+                );
+            }
+        );
+        $this->composer->getRepositoryManager()->will(
+            function () use ($repoManager) {
+                return $repoManager->reveal();
+            }
+        );
+
+        $root = $this->rootFromJson("{$dir}/composer.json");
+
+        $root->setRequires(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $requires = $args[0];
+                $that->assertEquals(1, count($requires));
+                $that->assertArrayHasKey(
+                    'wikimedia/composer-merge-plugin',
+                    $requires
+                );
+            }
+        );
+
+        $root->getDevRequires()->shouldNotBeCalled();
+        $root->setDevRequires()->shouldNotBeCalled();
+
+        $root->setRepositories(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $repos = $args[0];
+                $that->assertEquals(1, count($repos));
+            }
+        );
+
+        $root->getSuggests()->shouldNotBeCalled();
+
+        $extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
+
+        $this->assertEquals(0, count($extraInstalls));
+    }
+
+    /**
+     * Given a root package
+     *   and a composer.local.json with required packages
+     * When the plugin is run
+     * Then the root package should be updated with stability flags.
+     */
+    public function testUpdateStabilityFlags()
+    {
+        $that = $this;
+        $dir = $this->fixtureDir(__FUNCTION__);
+        $root = $this->rootFromJson("{$dir}/composer.json");
+
+        $root->setRequires(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                $requires = $args[0];
+                $that->assertEquals(4, count($requires));
+                $that->assertArrayHasKey('test/foo', $requires);
+                $that->assertArrayHasKey('test/bar', $requires);
+                $that->assertArrayHasKey('test/baz', $requires);
+                $that->assertArrayHasKey('test/xyzzy', $requires);
+            }
+        );
+
+        $root->getDevRequires()->shouldNotBeCalled();
+        $root->setDevRequires(Argument::any())->shouldNotBeCalled();
+
+        $root->getRepositories()->shouldNotBeCalled();
+        $root->setRepositories(Argument::any())->shouldNotBeCalled();
+
+        $root->getSuggests()->shouldNotBeCalled();
+        $root->setSuggests(Argument::any())->shouldNotBeCalled();
+
+        $extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
+
+        $this->assertEquals(0, count($extraInstalls));
+    }
+
+    /**
+     * @param RootPackage $package
+     * @param string $directory Working directory for composer run
+     * @return array Constrains added by MergePlugin::onDependencySolve
+     */
+    protected function triggerPlugin($package, $directory)
+    {
+        chdir($directory);
+        $this->composer->getPackage()->willReturn($package);
+
+        $event = new CommandEvent(
+            ScriptEvents::PRE_INSTALL_CMD,
+            $this->composer->reveal(),
+            $this->io->reveal(),
+            true, //dev mode
+            array(),
+            array()
+        );
+        $this->fixture->onInstallOrUpdate($event);
+
+        $requestInstalls = array();
+        $request = $this->prophesize('Composer\DependencyResolver\Request');
+        $request->install(Argument::any(), Argument::any())->will(
+            function ($args) use (&$requestInstalls) {
+                $requestInstalls[] = $args;
+            }
+        );
+
+        $event = new InstallerEvent(
+            InstallerEvents::PRE_DEPENDENCIES_SOLVING,
+            $this->composer->reveal(),
+            $this->io->reveal(),
+            
$this->prophesize('Composer\DependencyResolver\PolicyInterface')->reveal(),
+            $this->prophesize('Composer\DependencyResolver\Pool')->reveal(),
+            
$this->prophesize('Composer\Repository\CompositeRepository')->reveal(),
+            $request->reveal(),
+            array()
+        );
+
+        $this->fixture->onDependencySolve($event);
+        return $requestInstalls;
+    }
+
+    /**
+     * @param string $subdir
+     * @return string
+     */
+    protected function fixtureDir($subdir)
+    {
+        return __DIR__ . "/fixtures/{$subdir}";
+    }
+
+    /**
+     * @param string $file
+     * @return ObjectProphecy
+     */
+    protected function rootFromJson($file)
+    {
+        $that = $this;
+        $json = json_decode(file_get_contents($file), true);
+        $data = array_merge(
+            array(
+                'repositories' => array(),
+                'require' => array(),
+                'require-dev' => array(),
+                'suggest' => array(),
+                'extra' => array(),
+            ),
+            $json
+        );
+
+        $root = $this->prophesize('Composer\Package\RootPackage');
+        $root->getRequires()->willReturn($data['require'])->shouldBeCalled();
+        $root->getDevRequires()->willReturn($data['require-dev']);
+        $root->getRepositories()->willReturn($data['repositories']);
+        $root->getSuggests()->willReturn($data['suggest']);
+        $root->getExtra()->willReturn($data['extra'])->shouldBeCalled();
+
+        $root->getStabilityFlags()->willReturn(array());
+        $root->setStabilityFlags(Argument::type('array'))->will(
+            function ($args) use ($that) {
+                foreach ($args[0] as $key => $value) {
+                    $that->assertContains($value, BasePackage::$stabilities);
+                }
+            }
+        );
+
+        return $root;
+    }
+}
+// vim:sw=4:ts=4:sts=4:et:
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.json
new file mode 100644
index 0000000..719cce6
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.json
@@ -0,0 +1,7 @@
+{
+    "extra": {
+        "merge-plugin": {
+            "include": "composer.local.json"
+        }
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.local.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.local.json
new file mode 100644
index 0000000..f2aa67b
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testMergedRepositories/composer.local.json
@@ -0,0 +1,11 @@
+{
+    "repositories": [
+        {
+            "type": "vcs",
+            "url": "https://github.com/bd808/composer-merge-plugin.git";
+        }
+    ],
+    "require": {
+        "wikimedia/composer-merge-plugin": "dev-master#deadbeef"
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.json
new file mode 100644
index 0000000..719cce6
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.json
@@ -0,0 +1,7 @@
+{
+    "extra": {
+        "merge-plugin": {
+            "include": "composer.local.json"
+        }
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.local.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.local.json
new file mode 100644
index 0000000..4928c06
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeNoConflicts/composer.local.json
@@ -0,0 +1,5 @@
+{
+    "require": {
+        "monolog/monolog": "~1.0"
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.json
new file mode 100644
index 0000000..9aac436
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.json
@@ -0,0 +1,22 @@
+{
+    "repositories": [
+        {
+            "type": "vcs",
+            "url": "./.."
+        }
+    ],
+    "require": {
+        "wikimedia/composer-merge-plugin": "*@dev",
+        "monolog/monolog": "~1.0"
+    },
+    "require-dev": {
+        "foo": "1.0.0"
+    },
+    "extra": {
+        "merge-plugin": {
+            "include": [
+                "composer.local.json"
+            ]
+        }
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.local.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.local.json
new file mode 100644
index 0000000..c9ed6da
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/composer.local.json
@@ -0,0 +1,8 @@
+{
+    "require": {
+        "monolog/monolog": "1.10.0"
+    },
+    "require-dev": {
+        "xyzzy": "dev-master"
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/extensions/Foo/composer.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/extensions/Foo/composer.json
new file mode 100644
index 0000000..ac06e85
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testOneMergeWithConflicts/extensions/Foo/composer.json
@@ -0,0 +1,9 @@
+{
+    "require": {
+        "wikimedia/cdb": "~1.0.0",
+        "monolog/monolog": "1.10.0"
+    },
+    "dev-require": {
+        "foo": "1.0.0"
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.json
new file mode 100644
index 0000000..719cce6
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.json
@@ -0,0 +1,7 @@
+{
+    "extra": {
+        "merge-plugin": {
+            "include": "composer.local.json"
+        }
+    }
+}
diff --git 
a/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.local.json
 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.local.json
new file mode 100644
index 0000000..f7aa463
--- /dev/null
+++ 
b/wikimedia/composer-merge-plugin/tests/phpunit/fixtures/testUpdateStabilityFlags/composer.local.json
@@ -0,0 +1,8 @@
+{
+    "require": {
+        "test/foo": "dev-master",
+        "test/bar": "~1.0@beta",
+        "test/baz": "0.1@alpha",
+        "test/xyzzy": "1.0.0-rc1"
+    }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/186380
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I72f89c435d75fb8eb6ad77d10f83fe1cad8d9e5b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vendor
Gerrit-Branch: master
Gerrit-Owner: Legoktm <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to