diff --git a/src/Composer/Json/JsonManipulator.php b/src/Composer/Json/JsonManipulator.php index f69d72db6..f11dfac08 100644 --- a/src/Composer/Json/JsonManipulator.php +++ b/src/Composer/Json/JsonManipulator.php @@ -69,11 +69,15 @@ class JsonManipulator $links = $matches['value']; - if (isset($decoded[$type][$package])) { + // try to find existing link + $packageRegex = str_replace('/', '\\\\?/', preg_quote($package)); + $regex = '{'.self::$DEFINES.'"(?P'.$packageRegex.')"(\s*:\s*)(?&string)}ix'; + if ($this->pregMatch($regex, $links, $packageMatches)) { // update existing link - $packageRegex = str_replace('/', '\\\\?/', preg_quote($package)); - $links = preg_replace_callback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P\s*:\s*)(?&string)}ix', function ($m) use ($package, $constraint) { - return JsonFile::encode($package) . $m['separator'] . '"' . $constraint . '"'; + $existingPackage = $packageMatches['package']; + $packageRegex = str_replace('/', '\\\\?/', preg_quote($existingPackage)); + $links = preg_replace_callback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P\s*:\s*)(?&string)}ix', function ($m) use ($existingPackage, $constraint) { + return JsonFile::encode(str_replace('\\/', '/', $existingPackage)) . $m['separator'] . '"' . $constraint . '"'; }, $links); } else { if ($this->pregMatch('#^\s*\{\s*\S+.*?(\s*\}\s*)$#s', $links, $match)) { diff --git a/tests/Composer/Test/Json/JsonManipulatorTest.php b/tests/Composer/Test/Json/JsonManipulatorTest.php index 12080da2e..097d7d9f4 100644 --- a/tests/Composer/Test/Json/JsonManipulatorTest.php +++ b/tests/Composer/Test/Json/JsonManipulatorTest.php @@ -107,6 +107,28 @@ class JsonManipulatorTest extends \PHPUnit_Framework_TestCase "vendor/baz": "qux" } } +', + ), + + + array( + '{ + "require": + { + "foo": "bar", + "vendor/baz": "baz" + } +}', + 'require', + 'vEnDoR/bAz', + 'qux', + '{ + "require": + { + "foo": "bar", + "vendor/baz": "qux" + } +} ', ), array( @@ -127,6 +149,26 @@ class JsonManipulatorTest extends \PHPUnit_Framework_TestCase "vendor/baz": "qux" } } +', + ), + array( + '{ + "require": + { + "foo": "bar", + "vendor\/baz": "baz" + } +}', + 'require', + 'vEnDoR/bAz', + 'qux', + '{ + "require": + { + "foo": "bar", + "vendor/baz": "qux" + } +} ', ), array(