From d51ef83a43de7703054a08da69dc7f7e9bb0bd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20Mu=CC=88nnich?= Date: Mon, 3 Jul 2017 12:11:24 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20case=20insensitivity=20of=20=E2=80=98requ?= =?UTF-8?q?ire=E2=80=99=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When currently executing the `require` command for a package that is already listed in `require(-dev)`, one must use the exact same, case matching package name as written in `composer.json`. That is, if one changes the case of a character in the package name, the `require` command will add a new entry to `require(-dev)`, instead of updating the existing one. This commit fixes the described behaviour to make it consistent with other commands like `update` that are already case insensitive. --- src/Composer/Json/JsonManipulator.php | 12 ++++-- .../Test/Json/JsonManipulatorTest.php | 42 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) 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(