Browse Source

Expand normalization feature and adjust tests

Jordi Boggiano 13 years ago
parent
commit
2e10b5c17e

+ 40 - 15
src/Composer/Package/Version/VersionParser.php

@@ -22,6 +22,8 @@ use Composer\Package\LinkConstraint\VersionConstraint;
  */
 class VersionParser
 {
+    private $modifierRegex = '[.-]?(?:(beta|RC|alpha|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?';
+
     /**
      * Normalizes a version string to be able to perform comparisons on it
      *
@@ -33,24 +35,42 @@ class VersionParser
         $version = trim($version);
 
         // match classical versioning
-        if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?-?((?:beta|RC|alpha)\d*)?(-?dev)?$}i', $version, $matches)) {
-            return $matches[1]
+        if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.$this->modifierRegex.'$}i', $version, $matches)) {
+            $version = $matches[1]
                 .(!empty($matches[2]) ? $matches[2] : '.0')
                 .(!empty($matches[3]) ? $matches[3] : '.0')
-                .(!empty($matches[4]) ? '-'.strtolower($matches[4]) : '')
-                .(!empty($matches[5]) ? '-dev' : '');
+                .(!empty($matches[4]) ? $matches[4] : '.0');
+            $index = 5;
+        } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.$this->modifierRegex.'$}i', $version, $matches)) { // match date-based versioning
+            $version = preg_replace('{\D}', '-', $matches[1]);
+            $index = 2;
         }
 
-        // match date-based versioning
-        if (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1})?)((?:beta|RC|alpha)\d*)?(-?dev)?$}i', $version, $matches)) {
-            return preg_replace('{\D}', '-', $matches[1])
-                .(!empty($matches[2]) ? '-'.strtolower($matches[2]) : '')
-                .(!empty($matches[3]) ? '-dev' : '');
+        // add version modifiers if a version was matched
+        if (isset($index)) {
+            if (!empty($matches[$index])) {
+                $mod = array('p', 'pl', 'rc');
+                $modNormalized = array('patch', 'patch', 'RC');
+                $version .= '-'.str_replace($mod, $modNormalized, strtolower($matches[$index]))
+                    . (!empty($matches[$index+1]) ? $matches[$index+1] : '');
+            }
+
+            if (!empty($matches[$index+2])) {
+                $version .= '-dev';
+            }
+
+            return $version;
         }
 
         throw new \UnexpectedValueException('Invalid version string '.$version);
     }
 
+    /**
+     * Parses as constraint string into LinkConstraint objects
+     *
+     * @param string $constraints
+     * @return \Composer\Package\LinkConstraint\LinkConstraintInterface
+     */
     public function parseConstraints($constraints)
     {
         $constraints = preg_split('{\s*,\s*}', trim($constraints));
@@ -78,12 +98,17 @@ class VersionParser
         }
 
         // match wildcard constraints
-        if (preg_match('{^(\d+)(?:\.(\d+))?\.\*$}', $constraint, $matches)) {
-            $lowVersion = $matches[1] . '.' . (isset($matches[2]) ? $matches[2] : '0') . '.0';
-            $highVersion = (isset($matches[2])
-                ? $matches[1] . '.' . ($matches[2]+1)
-                : ($matches[1]+1) . '.0')
-                . '.0';
+        if (preg_match('{^(\d+)(?:\.(\d+))?(?:\.(\d+))?\.\*$}', $constraint, $matches)) {
+            if (isset($matches[3])) {
+                $lowVersion = $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.0';
+                $highVersion = $matches[1] . '.' . $matches[2] . '.' . ($matches[3]+1) . '.0';
+            } elseif (isset($matches[2])) {
+                $lowVersion = $matches[1] . '.' . $matches[2] . '.0.0';
+                $highVersion = $matches[1] . '.' . ($matches[2]+1) . '.0.0';
+            } else {
+                $lowVersion = $matches[1] . '.0.0.0';
+                $highVersion = ($matches[1]+1) . '.0.0.0';
+            }
 
             return array(
                 new VersionConstraint('>=', $lowVersion),

+ 1 - 1
src/Composer/Repository/PlatformRepository.php

@@ -53,7 +53,7 @@ class PlatformRepository extends ArrayRepository implements WritableRepositoryIn
             try {
                 $version = $versionParser->normalize($reflExt->getVersion());
             } catch (\UnexpectedValueException $e) {
-                $version = '0.0.0';
+                $version = $versionParser->normalize('0');
             }
 
             $ext = new MemoryPackage('ext/'.strtolower($ext), $version);

+ 35 - 21
tests/Composer/Test/Package/Version/VersionParserTest.php

@@ -30,19 +30,23 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
     public function successfulNormalizedVersions()
     {
         return array(
-            'none'              => array('1.0.0',               '1.0.0'),
-            'parses state'      => array('1.0.0RC1dev',         '1.0.0-rc1-dev'),
-            'CI parsing'        => array('1.0.0-rC15-dev',      '1.0.0-rc15-dev'),
-            'forces x.y.z'      => array('1.0-dev',             '1.0.0-dev'),
-            'forces x.y.z'      => array('0',                   '0.0.0'),
-            'parses long'       => array('10.4.13-beta',        '10.4.13-beta'),
+            'none'              => array('1.0.0',               '1.0.0.0'),
+            'none'              => array('1.2.3.4',             '1.2.3.4'),
+            'parses state'      => array('1.0.0RC1dev',         '1.0.0.0-RC1-dev'),
+            'CI parsing'        => array('1.0.0-rC15-dev',      '1.0.0.0-RC15-dev'),
+            'delimiters'        => array('1.0.0.RC.15-dev',     '1.0.0.0-RC15-dev'),
+            'forces w.x.y.z'    => array('1.0-dev',             '1.0.0.0-dev'),
+            'forces w.x.y.z'    => array('0',                   '0.0.0.0'),
+            'parses long'       => array('10.4.13-beta',        '10.4.13.0-beta'),
             'strips leading v'  => array('v1.0.0',              '1.0.0'),
             'strips leading v'  => array('v20100102',           '20100102'),
+            'parses dates y-m'  => array('2010.01',             '2010-01'),
             'parses dates w/ .' => array('2010.01.02',          '2010-01-02'),
             'parses dates w/ -' => array('2010-01-02',          '2010-01-02'),
             'parses numbers'    => array('2010-01-02.5',        '2010-01-02-5'),
             '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'),
         );
     }
 
@@ -62,7 +66,7 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
             'empty '            => array(''),
             'invalid chars'     => array('a'),
             'invalid type'      => array('1.0.0-meh'),
-            'too many bits'     => array('1.0.0.0'),
+            'too many bits'     => array('1.0.0.0.0'),
         );
     }
 
@@ -78,15 +82,15 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
     public function simpleConstraints()
     {
         return array(
-            'greater than'      => array('>1.0.0',      new VersionConstraint('>', '1.0.0')),
-            'lesser than'       => array('<1.2.3',      new VersionConstraint('<', '1.2.3')),
-            'less/eq than'      => array('<=1.2.3',     new VersionConstraint('<=', '1.2.3')),
-            'great/eq than'     => array('>=1.2.3',     new VersionConstraint('>=', '1.2.3')),
-            'equals'            => array('=1.2.3',      new VersionConstraint('=', '1.2.3')),
-            'double equals'     => array('==1.2.3',     new VersionConstraint('=', '1.2.3')),
-            'no op means eq'    => array('1.2.3',       new VersionConstraint('=', '1.2.3')),
-            'completes version' => array('=1.0',        new VersionConstraint('=', '1.0.0')),
-            'accepts spaces'    => array('>= 1.2.3',    new VersionConstraint('>=', '1.2.3')),
+            'greater than'      => array('>1.0.0',      new VersionConstraint('>', '1.0.0.0')),
+            'lesser than'       => array('<1.2.3.4',    new VersionConstraint('<', '1.2.3.4')),
+            'less/eq than'      => array('<=1.2.3',     new VersionConstraint('<=', '1.2.3.0')),
+            'great/eq than'     => array('>=1.2.3',     new VersionConstraint('>=', '1.2.3.0')),
+            'equals'            => array('=1.2.3',      new VersionConstraint('=', '1.2.3.0')),
+            'double equals'     => array('==1.2.3',     new VersionConstraint('=', '1.2.3.0')),
+            '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')),
         );
     }
 
@@ -104,14 +108,24 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
     public function wildcardConstraints()
     {
         return array(
-            array('2.*',     new VersionConstraint('>=', '2.0.0'), new VersionConstraint('<', '3.0.0')),
-            array('20.*',    new VersionConstraint('>=', '20.0.0'), new VersionConstraint('<', '21.0.0')),
-            array('2.0.*',   new VersionConstraint('>=', '2.0.0'), new VersionConstraint('<', '2.1.0')),
-            array('2.2.*',   new VersionConstraint('>=', '2.2.0'), new VersionConstraint('<', '2.3.0')),
-            array('2.10.*',  new VersionConstraint('>=', '2.10.0'), new VersionConstraint('<', '2.11.0')),
+            array('2.*',     new VersionConstraint('>=', '2.0.0.0'), new VersionConstraint('<', '3.0.0.0')),
+            array('20.*',    new VersionConstraint('>=', '20.0.0.0'), new VersionConstraint('<', '21.0.0.0')),
+            array('2.0.*',   new VersionConstraint('>=', '2.0.0.0'), new VersionConstraint('<', '2.1.0.0')),
+            array('2.2.*',   new VersionConstraint('>=', '2.2.0.0'), new VersionConstraint('<', '2.3.0.0')),
+            array('2.10.*',  new VersionConstraint('>=', '2.10.0.0'), new VersionConstraint('<', '2.11.0.0')),
+            array('2.1.3.*', new VersionConstraint('>=', '2.1.3.0'), new VersionConstraint('<', '2.1.4.0')),
         );
     }
 
+    public function testParseConstraintsMulti()
+    {
+        $parser = new VersionParser;
+        $first = new VersionConstraint('>', '2.0.0.0');
+        $second = new VersionConstraint('<=', '3.0.0.0');
+        $multi = new MultiConstraint(array($first, $second));
+        $this->assertEquals((string) $multi, (string) $parser->parseConstraints('>2.0,<=3.0'));
+    }
+
     /**
      * @dataProvider failingConstraints
      * @expectedException UnexpectedValueException

+ 1 - 1
tests/Composer/Test/Repository/FilesystemRepositoryTest.php

@@ -49,7 +49,7 @@ class FilesystemRepositoryTest extends \PHPUnit_Framework_TestCase
 
         $data = json_decode(file_get_contents($this->repositoryFile), true);
         $this->assertEquals(array(
-            array('name' => 'package1', 'type' => 'vendor', 'version' => '1.0.0-beta', 'names' => array('package1'))
+            array('name' => 'package1', 'type' => 'vendor', 'version' => '1.0.0.0-beta', 'names' => array('package1'))
         ), $data);
     }
 }