From 19f89069a4dddf65888f6779774b540244e0ffbf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 11 Oct 2011 09:30:10 +0200 Subject: [PATCH 1/4] Add some more version normalization and support for branch names --- .../Package/Version/VersionParser.php | 31 ++++++++++++++++++- .../Package/Version/VersionParserTest.php | 26 ++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index d91bbb5f6..59d6f5382 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -34,6 +34,10 @@ class VersionParser { $version = trim($version); + if (in_array($version, array('master', 'trunk'))) { + return '9999999-dev'; + } + // match classical versioning if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.$this->modifierRegex.'$}i', $version, $matches)) { $version = $matches[1] @@ -65,6 +69,31 @@ class VersionParser throw new \UnexpectedValueException('Invalid version string '.$version); } + /** + * Normalizes a branch name to be able to perform comparisons on it + * + * @param string $version + * @return array + */ + public function normalizeBranch($name) + { + $name = trim($name); + + if (in_array($name, array('master', 'trunk'))) { + return $this->normalize($name); + } + + if (preg_match('#^v?(\d+)(\.(?:\d+|[x*]))?(\.(?:\d+|[x*]))?(\.(?:\d+|[x*]))?$#i', $name, $matches)) { + $version = ''; + for ($i = 1; $i < 5; $i++) { + $version .= isset($matches[$i]) ? str_replace('*', 'x', $matches[$i]) : '.x'; + } + return str_replace('x', '9999999', $version).'-dev'; + } + + throw new \UnexpectedValueException('Invalid branch name '.$branch); + } + /** * Parses as constraint string into LinkConstraint objects * @@ -93,7 +122,7 @@ class VersionParser private function parseConstraint($constraint) { - if ('*' === $constraint || '*.*' === $constraint || '*.*.*' === $constraint) { + if ('*' === $constraint || '*.*' === $constraint || '*.*.*' === $constraint || '*.*.*.*' === $constraint) { return array(); } diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index 09789d5e6..4a6909e23 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -49,6 +49,8 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'parses datetime' => array('20100102-203040', '20100102-203040'), 'parses dt+number' => array('20100102203040-10', '20100102203040-10'), 'parses dt+patch' => array('20100102-203040-p1', '20100102-203040-patch1'), + 'parses master' => array('master', '9999999-dev'), + 'parses trunk' => array('trunk', '9999999-dev'), ); } @@ -72,6 +74,30 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase ); } + /** + * @dataProvider successfulNormalizedBranches + */ + public function testNormalizeBranch($input, $expected) + { + $parser = new VersionParser; + $this->assertSame((string) $expected, (string) $parser->normalizeBranch($input)); + } + + public function successfulNormalizedBranches() + { + return array( + 'parses x' => array('v1.x', '1.9999999.9999999.9999999-dev'), + 'parses *' => array('v1.*', '1.9999999.9999999.9999999-dev'), + 'parses digits' => array('v1.0', '1.0.9999999.9999999-dev'), + 'parses long x' => array('v1.0.x', '1.0.9999999.9999999-dev'), + 'parses long *' => array('v1.0.3.*', '1.0.3.9999999-dev'), + 'parses long digits' => array('v2.4.0', '2.4.0.9999999-dev'), + 'parses long digits/2' => array('2.4.4', '2.4.4.9999999-dev'), + 'parses master' => array('master', '9999999-dev'), + 'parses trunk' => array('trunk', '9999999-dev'), + ); + } + /** * @dataProvider simpleConstraints */ From e09f6900da44697e0b2afd296a66105014549da7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 11 Oct 2011 11:49:32 +0200 Subject: [PATCH 2/4] Fix up version parsing --- src/Composer/Package/Version/VersionParser.php | 17 ++++++++++++----- .../Test/Package/Version/VersionParserTest.php | 3 +++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index 59d6f5382..725ee7d7f 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -34,7 +34,7 @@ class VersionParser { $version = trim($version); - if (in_array($version, array('master', 'trunk'))) { + if (preg_match('{^(?:master|trunk)(?:[.-]?dev)?$}i', $version)) { return '9999999-dev'; } @@ -66,6 +66,12 @@ class VersionParser return $version; } + if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) { + try { + return $this->normalizeBranch($match[1]); + } catch (\Exception $e) {} + } + throw new \UnexpectedValueException('Invalid version string '.$version); } @@ -146,10 +152,11 @@ class VersionParser } // match operators constraints - if (preg_match('{^(>=?|<=?|==?)?\s*(\d+.*)}', $constraint, $matches)) { - $version = $this->normalize($matches[2]); - - return array(new VersionConstraint($matches[1] ?: '=', $version)); + if (preg_match('{^(>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) { + try { + $version = $this->normalize($matches[2]); + return array(new VersionConstraint($matches[1] ?: '=', $version)); + } catch (\Exception $e) {} } throw new \UnexpectedValueException('Could not parse version constraint '.$constraint); diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index 4a6909e23..e6d731dc9 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -51,6 +51,7 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'parses dt+patch' => array('20100102-203040-p1', '20100102-203040-patch1'), 'parses master' => array('master', '9999999-dev'), 'parses trunk' => array('trunk', '9999999-dev'), + 'parses trunk/2' => array('trunk-dev', '9999999-dev'), ); } @@ -119,6 +120,8 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'no op means eq' => array('1.2.3', new VersionConstraint('=', '1.2.3.0')), 'completes version' => array('=1.0', new VersionConstraint('=', '1.0.0.0')), 'accepts spaces' => array('>= 1.2.3', new VersionConstraint('>=', '1.2.3.0')), + 'accepts master' => array('>=master-dev', new VersionConstraint('>=', '9999999-dev')), + 'accepts master/2' => array('master-dev', new VersionConstraint('=', '9999999-dev')), ); } From 74d7fdfcef43b1f8ec83fab2917bafea32489339 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Sat, 15 Oct 2011 14:34:16 +0200 Subject: [PATCH 3/4] Fix missing support for the symfony-bundle package type. Using Composer\Installer\LibraryInstaller to handle the installation of packages that specify the "symfony-bundle" type is just a temporary solution while waiting to better define how packages shipping Symfony bundles should be treated. --- bin/composer | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/composer b/bin/composer index e2d36b3c9..4cf1eec23 100755 --- a/bin/composer +++ b/bin/composer @@ -27,6 +27,7 @@ $dm->setDownloader('zip', new Downloader\ZipDownloader()); // initialize installation manager $im = new Installer\InstallationManager(); $im->setInstaller('library', new Installer\LibraryInstaller('vendor', $dm, $rm->getLocalRepository())); +$im->setInstaller('symfony-bundle', new Installer\LibraryInstaller('vendor/bundles', $dm, $rm->getLocalRepository())); // load package $loader = new Package\Loader\JsonLoader(); From 40cc5fea1df813ffafdb365a20956ca92ff749bb Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 15 Oct 2011 20:03:55 +0200 Subject: [PATCH 4/4] Add a few solver tests regarding "replace" --- .../Test/DependencyResolver/SolverTest.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index cd2e0b8a7..ad9291055 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -231,6 +231,60 @@ class SolverTest extends \PHPUnit_Framework_TestCase )); } + public function testSkipReplacerOfExistingPackage() + { + $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); + $this->repo->addPackage($packageQ = new MemoryPackage('Q', '1.0')); + $this->repo->addPackage($packageB = new MemoryPackage('B', '1.0')); + $packageA->setRequires(array(new Link('A', 'B', new VersionConstraint('>=', '1.0'), 'requires'))); + $packageQ->setReplaces(array(new Link('Q', 'B', new VersionConstraint('>=', '1.0'), 'replaces'))); + + $this->reposComplete(); + + $this->request->install('A'); + + $this->checkSolverResult(array( + array('job' => 'install', 'package' => $packageB), + array('job' => 'install', 'package' => $packageA), + )); + } + + public function testInstallReplacerOfMissingPackage() + { + $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); + $this->repo->addPackage($packageQ = new MemoryPackage('Q', '1.0')); + $packageA->setRequires(array(new Link('A', 'B', new VersionConstraint('>=', '1.0'), 'requires'))); + $packageQ->setReplaces(array(new Link('Q', 'B', new VersionConstraint('>=', '1.0'), 'replaces'))); + + $this->reposComplete(); + + $this->request->install('A'); + + $this->checkSolverResult(array( + array('job' => 'install', 'package' => $packageQ), + array('job' => 'install', 'package' => $packageA), + )); + } + + public function testSkipReplacedPackageIfReplacerIsSelected() + { + $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0')); + $this->repo->addPackage($packageQ = new MemoryPackage('Q', '1.0')); + $this->repo->addPackage($packageB = new MemoryPackage('B', '1.0')); + $packageA->setRequires(array(new Link('A', 'B', new VersionConstraint('>=', '1.0'), 'requires'))); + $packageQ->setReplaces(array(new Link('Q', 'B', new VersionConstraint('>=', '1.0'), 'replaces'))); + + $this->reposComplete(); + + $this->request->install('A'); + $this->request->install('Q'); + + $this->checkSolverResult(array( + array('job' => 'install', 'package' => $packageQ), + array('job' => 'install', 'package' => $packageA), + )); + } + public function testInstallCircularRequire() { $this->repo->addPackage($packageA = new MemoryPackage('A', '1.0'));