Prechádzať zdrojové kódy

Merge pull request #1108 from Seldaek/newlock

Update lock file to contain the complete package info, fixes #890
Nils Adermann 12 rokov pred
rodič
commit
cf029cab86

+ 186 - 10
composer.lock

@@ -2,24 +2,200 @@
     "hash": "1023850095295cc1307c2219a0382930",
     "packages": [
         {
-            "package": "justinrainbow/json-schema",
-            "version": "1.1.0"
+            "name": "justinrainbow/json-schema",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "git://github.com/justinrainbow/json-schema.git",
+                "reference": "v1.1.0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/justinrainbow/json-schema/zipball/v1.1.0",
+                "reference": "v1.1.0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2012-01-02 22:33:17",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "JsonSchema": "src/"
+                }
+            }
         },
         {
-            "package": "seld/jsonlint",
-            "version": "1.0.0"
+            "name": "seld/jsonlint",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "http://github.com/Seldaek/jsonlint",
+                "reference": "1.0.0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/Seldaek/jsonlint/zipball/1.0.0",
+                "reference": "1.0.0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2012-03-12 05:52:32",
+            "bin": [
+                "bin/jsonlint"
+            ],
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Seld\\JsonLint": "src/"
+                }
+            }
         },
         {
-            "package": "symfony/console",
-            "version": "v2.1.0"
+            "name": "symfony/console",
+            "version": "v2.1.1",
+            "target-dir": "Symfony/Component/Console",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Console",
+                "reference": "v2.1.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/symfony/Console/zipball/v2.1.1",
+                "reference": "v2.1.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "time": "2012-08-22 11:48:41",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Console": ""
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Console Component",
+            "homepage": "http://symfony.com"
         },
         {
-            "package": "symfony/finder",
-            "version": "v2.1.0"
+            "name": "symfony/finder",
+            "version": "v2.1.1",
+            "target-dir": "Symfony/Component/Finder",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Finder",
+                "reference": "v2.1.0-RC2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/symfony/Finder/zipball/v2.1.0-RC2",
+                "reference": "v2.1.0-RC2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "time": "2012-08-22 11:48:41",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Finder": ""
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Finder Component",
+            "homepage": "http://symfony.com"
         },
         {
-            "package": "symfony/process",
-            "version": "v2.1.0"
+            "name": "symfony/process",
+            "version": "v2.1.1",
+            "target-dir": "Symfony/Component/Process",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Process",
+                "reference": "v2.1.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/symfony/Process/zipball/v2.1.1",
+                "reference": "v2.1.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "time": "2012-08-30 10:49:05",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Process": ""
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Process Component",
+            "homepage": "http://symfony.com"
         }
     ],
     "packages-dev": null,

+ 21 - 37
src/Composer/Installer.php

@@ -234,8 +234,10 @@ class Installer
         $stabilityFlags = $this->package->getStabilityFlags();
 
         // initialize locker to create aliased packages
+        $installFromLock = false;
         if (!$this->update && $this->locker->isLocked($devMode)) {
-            $lockedPackages = $this->locker->getLockedPackages($devMode);
+            $installFromLock = true;
+            $lockedRepository = $this->locker->getLockedRepository($devMode);
             $minimumStability = $this->locker->getMinimumStability();
             $stabilityFlags = $this->locker->getStabilityFlags();
         }
@@ -252,13 +254,15 @@ class Installer
         // creating repository pool
         $pool = new Pool($minimumStability, $stabilityFlags);
         $pool->addRepository($installedRepo, $aliases);
+        if ($installFromLock) {
+            $pool->addRepository($lockedRepository);
+        }
         $repositories = $this->repositoryManager->getRepositories();
         foreach ($repositories as $repository) {
             $pool->addRepository($repository, $aliases);
         }
 
         // creating requirements request
-        $installFromLock = false;
         $request = new Request($pool);
 
         $constraint = new VersionConstraint('=', $this->package->getVersion());
@@ -274,15 +278,14 @@ class Installer
             foreach ($links as $link) {
                 $request->install($link->getTarget(), $link->getConstraint());
             }
-        } elseif ($this->locker->isLocked($devMode)) {
-            $installFromLock = true;
+        } elseif ($installFromLock) {
             $this->io->write('<info>Installing '.($devMode ? 'dev ': '').'dependencies from lock file</info>');
 
             if (!$this->locker->isFresh() && !$devMode) {
                 $this->io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
             }
 
-            foreach ($lockedPackages as $package) {
+            foreach ($lockedRepository->getPackages() as $package) {
                 $version = $package->getVersion();
                 if (isset($aliases[$package->getName()][$version])) {
                     $version = $aliases[$package->getName()][$version]['alias_normalized'];
@@ -316,7 +319,7 @@ class Installer
         // to the version specified in the lock, or their currently installed version
         if ($this->update && $this->updateWhitelist) {
             if ($this->locker->isLocked($devMode)) {
-                $currentPackages = $this->locker->getLockedPackages($devMode);
+                $currentPackages = $this->locker->getLockedRepository($devMode)->getPackages();
             } else {
                 $currentPackages = $installedRepo->getPackages();
             }
@@ -381,18 +384,20 @@ class Installer
 
             // force update to locked version if it does not match the installed version
             if ($installFromLock) {
-                $lockData = $this->locker->getLockData();
                 unset($lockedReference);
-                foreach ($lockData['packages'] as $lockedPackage) {
-                    if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
-                        $lockedReference = $lockedPackage['source-reference'];
+                foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) {
+                    if (
+                        $lockedPackage->isDev()
+                        && $lockedPackage->getSourceReference()
+                        && $lockedPackage->getSourceReference() !== $package->getSourceReference()
+                    ) {
+                        $newPackage = clone $package;
+                        $newPackage->setSourceReference($lockedPackage->getSourceReference());
+                        $operations[] = new UpdateOperation($package, $newPackage);
+
                         break;
                     }
                 }
-                if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) {
-                    // changing the source ref to update to will be handled in the operations loop below
-                    $operations[] = new UpdateOperation($package, clone $package);
-                }
             } else {
                 // force update to latest on update
                 if ($this->update) {
@@ -455,29 +460,8 @@ class Installer
                 $this->eventDispatcher->dispatchPackageEvent(constant($event), $operation);
             }
 
-            // if installing from lock, restore dev packages' references to their locked state
-            if ($installFromLock) {
-                $package = null;
-                if ('update' === $operation->getJobType()) {
-                    $package = $operation->getTargetPackage();
-                } elseif ('install' === $operation->getJobType()) {
-                    $package = $operation->getPackage();
-                }
-                if ($package && $package->isDev()) {
-                    $lockData = $this->locker->getLockData();
-                    foreach ($lockData['packages'] as $lockedPackage) {
-                        if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
-                            // update commit date to allow recovery in case the commit disappeared
-                            if (!empty($lockedPackage['commit-date'])) {
-                                $package->setReleaseDate(new \DateTime('@'.$lockedPackage['commit-date']));
-                            }
-                            $package->setSourceReference($lockedPackage['source-reference']);
-                            break;
-                        }
-                    }
-                }
-            } else {
-                // not installing from lock, force dev packages' references if they're in root package refs
+            // not installing from lock, force dev packages' references if they're in root package refs
+            if (!$installFromLock) {
                 $package = null;
                 if ('update' === $operation->getJobType()) {
                     $package = $operation->getTargetPackage();

+ 32 - 23
src/Composer/Package/Locker.php

@@ -17,6 +17,9 @@ use Composer\Installer\InstallationManager;
 use Composer\Repository\RepositoryManager;
 use Composer\Util\ProcessExecutor;
 use Composer\Package\AliasPackage;
+use Composer\Repository\ArrayRepository;
+use Composer\Package\Dumper\ArrayDumper;
+use Composer\Package\Loader\ArrayLoader;
 
 /**
  * Reads/writes project lockfile (composer.lock).
@@ -30,6 +33,8 @@ class Locker
     private $repositoryManager;
     private $installationManager;
     private $hash;
+    private $loader;
+    private $dumper;
     private $lockDataCache;
 
     /**
@@ -46,6 +51,8 @@ class Locker
         $this->repositoryManager = $repositoryManager;
         $this->installationManager = $installationManager;
         $this->hash = $hash;
+        $this->loader = new ArrayLoader();
+        $this->dumper = new ArrayDumper();
     }
 
     /**
@@ -84,16 +91,29 @@ class Locker
      * Searches and returns an array of locked packages, retrieved from registered repositories.
      *
      * @param  bool  $dev true to retrieve the locked dev packages
-     * @return array
+     * @return \Composer\Repository\RepositoryInterface
      */
-    public function getLockedPackages($dev = false)
+    public function getLockedRepository($dev = false)
     {
         $lockData = $this->getLockData();
-        $packages = array();
+        $packages = new ArrayRepository();
 
         $lockedPackages = $dev ? $lockData['packages-dev'] : $lockData['packages'];
-        $repo = $dev ? $this->repositoryManager->getLocalDevRepository() : $this->repositoryManager->getLocalRepository();
 
+        if (empty($lockedPackages)) {
+            return $packages;
+        }
+
+        if (isset($lockedPackages[0]['name'])) {
+            foreach ($lockedPackages as $info) {
+                $packages->addPackage($this->loader->load($info));
+            }
+
+            return $packages;
+        }
+
+        // legacy lock file support
+        $repo = $dev ? $this->repositoryManager->getLocalDevRepository() : $this->repositoryManager->getLocalRepository();
         foreach ($lockedPackages as $info) {
             $resolvedVersion = !empty($info['alias-version']) ? $info['alias-version'] : $info['version'];
 
@@ -122,7 +142,7 @@ class Locker
                 ));
             }
 
-            $packages[] = $package;
+            $packages->addPackage(clone $package);
         }
 
         return $packages;
@@ -221,11 +241,8 @@ class Locker
         $locked = array();
 
         foreach ($packages as $package) {
-            $alias = null;
-
             if ($package instanceof AliasPackage) {
-                $alias = $package;
-                $package = $package->getAliasOf();
+                continue;
             }
 
             $name    = $package->getPrettyName();
@@ -237,38 +254,30 @@ class Locker
                 ));
             }
 
-            $spec = array('package' => $name, 'version' => $version);
+            $spec = $this->dumper->dump($package);
+            unset($spec['version_normalized']);
 
-            if ($package->isDev() && !$alias) {
-                $spec['source-reference'] = $package->getSourceReference();
+            if ($package->isDev()) {
                 if ('git' === $package->getSourceType() && $path = $this->installationManager->getInstallPath($package)) {
                     $process = new ProcessExecutor();
                     if (0 === $process->execute('git log -n1 --pretty=%ct '.escapeshellarg($package->getSourceReference()), $output, $path)) {
-                        $spec['commit-date'] = trim($output);
+                        $spec['time'] = trim($output);
                     }
                 }
             }
 
-            if ($alias) {
-                $spec['alias-pretty-version'] = $alias->getPrettyVersion();
-                $spec['alias-version'] = $alias->getVersion();
-            }
-
             $locked[] = $spec;
         }
 
         usort($locked, function ($a, $b) {
-            $comparison = strcmp($a['package'], $b['package']);
+            $comparison = strcmp($a['name'], $b['name']);
 
             if (0 !== $comparison) {
                 return $comparison;
             }
 
             // If it is the same package, compare the versions to make the order deterministic
-            $aVersion = isset($a['alias-version']) ? $a['alias-version'] : $a['version'];
-            $bVersion = isset($b['alias-version']) ? $b['alias-version'] : $b['version'];
-
-            return strcmp($aVersion, $bVersion);
+            return strcmp($a['version'], $b['version']);
         });
 
         return $locked;

+ 6 - 2
tests/Composer/Test/Fixtures/installer/update-alias-lock.test

@@ -53,8 +53,12 @@ update
 --EXPECT-LOCK--
 {
     "packages": [
-        { "package": "a/a", "version": "dev-master", "alias-pretty-version": "1.0.x-dev", "alias-version": "1.0.9999999.9999999-dev" },
-        { "package": "a/a", "version": "dev-master", "source-reference": "master" }
+        {
+            "name": "a/a", "version": "dev-master",
+            "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } },
+            "source": { "reference": "master", "type": "git", "url": "" },
+            "type": "library"
+        }
     ],
     "packages-dev": null,
     "aliases": [],

+ 17 - 9
tests/Composer/Test/Package/LockerTest.php

@@ -48,7 +48,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
 
         $this->setExpectedException('LogicException');
 
-        $locker->getLockedPackages();
+        $locker->getLockedRepository();
     }
 
     public function testGetLockedPackages()
@@ -82,7 +82,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
             ->with($this->logicalOr('pkg1', 'pkg2'), $this->logicalOr('1.0.0-beta', '0.1.10'))
             ->will($this->onConsecutiveCalls($package1, $package2));
 
-        $this->assertEquals(array($package1, $package2), $locker->getLockedPackages());
+        $this->assertEquals(array($package1, $package2), $locker->getLockedRepository()->getPackages());
     }
 
     public function testGetPackagesWithoutRepo()
@@ -118,7 +118,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
 
         $this->setExpectedException('LogicException');
 
-        $locker->getLockedPackages();
+        $locker->getLockedRepository();
     }
 
     public function testSetLockData()
@@ -133,22 +133,30 @@ class LockerTest extends \PHPUnit_Framework_TestCase
         $package2 = $this->createPackageMock();
 
         $package1
-            ->expects($this->once())
+            ->expects($this->atLeastOnce())
             ->method('getPrettyName')
             ->will($this->returnValue('pkg1'));
         $package1
-            ->expects($this->once())
+            ->expects($this->atLeastOnce())
             ->method('getPrettyVersion')
             ->will($this->returnValue('1.0.0-beta'));
+        $package1
+            ->expects($this->atLeastOnce())
+            ->method('getVersion')
+            ->will($this->returnValue('1.0.0.0-beta'));
 
         $package2
-            ->expects($this->once())
+            ->expects($this->atLeastOnce())
             ->method('getPrettyName')
             ->will($this->returnValue('pkg2'));
         $package2
-            ->expects($this->once())
+            ->expects($this->atLeastOnce())
             ->method('getPrettyVersion')
             ->will($this->returnValue('0.1.10'));
+        $package2
+            ->expects($this->atLeastOnce())
+            ->method('getVersion')
+            ->will($this->returnValue('0.1.10.0'));
 
         $json
             ->expects($this->once())
@@ -156,8 +164,8 @@ class LockerTest extends \PHPUnit_Framework_TestCase
             ->with(array(
                 'hash' => 'md5',
                 'packages' => array(
-                    array('package' => 'pkg1', 'version' => '1.0.0-beta'),
-                    array('package' => 'pkg2', 'version' => '0.1.10')
+                    array('name' => 'pkg1', 'version' => '1.0.0-beta'),
+                    array('name' => 'pkg2', 'version' => '0.1.10')
                 ),
                 'packages-dev' => array(),
                 'aliases' => array(),