Browse Source

refactored PackageLock to Locker and stabilized it

everzet 13 years ago
parent
commit
21191ffa00

+ 102 - 0
src/Composer/Package/Locker.php

@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Package;
+
+use Composer\Json\JsonFile;
+use Composer\Repository\RepositoryManager;
+
+/**
+ * Reads/writes project lockfile (composer.lock).
+ *
+ * @author Konstantin Kudryashiv <ever.zet@gmail.com>
+ */
+class Locker
+{
+    private $lockFile;
+    private $repositoryManager;
+
+    /**
+     * Initializes packages locker.
+     *
+     * @param   JsonFile            $lockFile           lockfile loader
+     * @param   RepositoryManager   $repositoryManager  repository manager instance
+     */
+    public function __construct(JsonFile $lockFile, RepositoryManager $repositoryManager)
+    {
+        $this->lockFile          = $lockFile;
+        $this->repositoryManager = $repositoryManager;
+    }
+
+    /**
+     * Checks whether locker were been locked (lockfile found).
+     *
+     * @return  Boolean
+     */
+    public function isLocked()
+    {
+        return $this->lockFile->exists();
+    }
+
+    /**
+     * Searches and returns an array of locked packages, retrieved from registered repositories.
+     *
+     * @return  array
+     */
+    public function getLockedPackages()
+    {
+        if (!$this->isLocked()) {
+            throw new \LogicException('No lockfile found. Unable to read locked packages');
+        }
+
+        $lockList = $this->lockFile->read();
+        $packages = array();
+        foreach ($lockList as $info) {
+            $package = $this->repositoryManager->findPackage($info['package'], $info['version']);
+
+            if (!$package) {
+                throw new \LogicException(sprintf(
+                    'Can not find "%s-%s" package in registered repositories',
+                    $info['package'], $info['version']
+                ));
+            }
+
+            $packages[] = $package;
+        }
+
+        return $packages;
+    }
+
+    /**
+     * Locks provided packages into lockfile.
+     *
+     * @param   array   $packages   array of packages
+     */
+    public function lockPackages(array $packages)
+    {
+        $hash = array();
+        foreach ($packages as $package) {
+            $name    = $package->getName();
+            $version = $package->getVersion();
+
+            if (!$name || !$version) {
+                throw new \LogicException(sprintf(
+                    'Package "%s" has no version or name and can not be locked', $package
+                ));
+            }
+
+            $hash[] = array('package' => $name, 'version' => $version);
+        }
+
+        $this->lockFile->write($hash);
+    }
+}

+ 0 - 91
src/Composer/Package/PackageLock.php

@@ -1,91 +0,0 @@
-<?php
-
-/*
- * This file is part of Composer.
- *
- * (c) Nils Adermann <naderman@naderman.de>
- *     Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Composer\Package;
-
-use Composer\Package\MemoryPackage;
-use Composer\Package\Version\VersionParser;
-
-/**
- * @author Konstantin Kudryashiv <ever.zet@gmail.com>
- */
-class PackageLock
-{
-    private $file;
-    private $isLocked = false;
-
-    public function __construct($file = 'composer.lock')
-    {
-        if (file_exists($file)) {
-            $this->file     = $file;
-            $this->isLocked = true;
-        }
-    }
-
-    public function isLocked()
-    {
-        return $this->isLocked;
-    }
-
-    public function getLockedPackages()
-    {
-        $lockList = $this->loadJsonConfig($this->file);
-
-        $versionParser = new VersionParser();
-        $packages      = array();
-        foreach ($lockList as $info) {
-            $version    = $versionParser->normalize($info['version']);
-            $packages[] = new MemoryPackage($info['package'], $version);
-        }
-
-        return $packages;
-    }
-
-    public function lock(array $packages)
-    {
-        // TODO: write installed packages info into $this->file
-    }
-
-    private function loadJsonConfig($json)
-    {
-        if (is_file($json)) {
-            $json = file_get_contents($json);
-        }
-
-        $config = json_decode($json, true);
-        if (!$config) {
-            switch (json_last_error()) {
-            case JSON_ERROR_NONE:
-                $msg = 'No error has occurred, is your composer.json file empty?';
-                break;
-            case JSON_ERROR_DEPTH:
-                $msg = 'The maximum stack depth has been exceeded';
-                break;
-            case JSON_ERROR_STATE_MISMATCH:
-                $msg = 'Invalid or malformed JSON';
-                break;
-            case JSON_ERROR_CTRL_CHAR:
-                $msg = 'Control character error, possibly incorrectly encoded';
-                break;
-            case JSON_ERROR_SYNTAX:
-                $msg = 'Syntax error';
-                break;
-            case JSON_ERROR_UTF8:
-                $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
-                break;
-            }
-            throw new \UnexpectedValueException('Incorrect composer.json file: '.$msg);
-        }
-
-        return $config;
-    }
-}

+ 189 - 0
tests/Composer/Test/Package/LockerTest.php

@@ -0,0 +1,189 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Test\Package;
+
+use Composer\Package\Locker;
+
+class LockerTest extends \PHPUnit_Framework_TestCase
+{
+    public function testIsLocked()
+    {
+        $json   = $this->createJsonFileMock();
+        $locker = new Locker($json, $this->createRepositoryManagerMock());
+
+        $json
+            ->expects($this->once())
+            ->method('exists')
+            ->will($this->returnValue(true));
+
+        $this->assertTrue($locker->isLocked());
+    }
+
+    public function testGetNotLockedPackages()
+    {
+        $json = $this->createJsonFileMock();
+        $repo = $this->createRepositoryManagerMock();
+
+        $locker = new Locker($json, $repo);
+
+        $json
+            ->expects($this->once())
+            ->method('exists')
+            ->will($this->returnValue(false));
+
+        $this->setExpectedException('LogicException');
+
+        $locker->getLockedPackages();
+    }
+
+    public function testGetLockedPackages()
+    {
+        $json = $this->createJsonFileMock();
+        $repo = $this->createRepositoryManagerMock();
+
+        $locker = new Locker($json, $repo);
+
+        $json
+            ->expects($this->once())
+            ->method('exists')
+            ->will($this->returnValue(true));
+        $json
+            ->expects($this->once())
+            ->method('read')
+            ->will($this->returnValue(array(
+                array('package' => 'pkg1', 'version' => '1.0.0-beta'),
+                array('package' => 'pkg2', 'version' => '0.1.10')
+            )));
+
+        $package1 = $this->createPackageMock();
+        $package2 = $this->createPackageMock();
+
+        $repo
+            ->expects($this->exactly(2))
+            ->method('findPackage')
+            ->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());
+    }
+
+    public function testGetPackagesWithoutRepo()
+    {
+        $json = $this->createJsonFileMock();
+        $repo = $this->createRepositoryManagerMock();
+
+        $locker = new Locker($json, $repo);
+
+        $json
+            ->expects($this->once())
+            ->method('exists')
+            ->will($this->returnValue(true));
+        $json
+            ->expects($this->once())
+            ->method('read')
+            ->will($this->returnValue(array(
+                array('package' => 'pkg1', 'version' => '1.0.0-beta'),
+                array('package' => 'pkg2', 'version' => '0.1.10')
+            )));
+
+        $package1 = $this->createPackageMock();
+        $package2 = $this->createPackageMock();
+
+        $repo
+            ->expects($this->exactly(2))
+            ->method('findPackage')
+            ->with($this->logicalOr('pkg1', 'pkg2'), $this->logicalOr('1.0.0-beta', '0.1.10'))
+            ->will($this->onConsecutiveCalls($package1, null));
+
+        $this->setExpectedException('LogicException');
+
+        $locker->getLockedPackages();
+    }
+
+    public function testLockPackages()
+    {
+        $json = $this->createJsonFileMock();
+        $repo = $this->createRepositoryManagerMock();
+
+        $locker = new Locker($json, $repo);
+
+        $package1 = $this->createPackageMock();
+        $package2 = $this->createPackageMock();
+
+        $package1
+            ->expects($this->once())
+            ->method('getName')
+            ->will($this->returnValue('pkg1'));
+        $package1
+            ->expects($this->once())
+            ->method('getVersion')
+            ->will($this->returnValue('1.0.0-beta'));
+
+        $package2
+            ->expects($this->once())
+            ->method('getName')
+            ->will($this->returnValue('pkg2'));
+        $package2
+            ->expects($this->once())
+            ->method('getVersion')
+            ->will($this->returnValue('0.1.10'));
+
+        $json
+            ->expects($this->once())
+            ->method('write')
+            ->with(array(
+                array('package' => 'pkg1', 'version' => '1.0.0-beta'),
+                array('package' => 'pkg2', 'version' => '0.1.10')
+            ));
+
+        $locker->lockPackages(array($package1, $package2));
+    }
+
+    public function testLockBadPackages()
+    {
+        $json = $this->createJsonFileMock();
+        $repo = $this->createRepositoryManagerMock();
+
+        $locker = new Locker($json, $repo);
+
+        $package1 = $this->createPackageMock();
+        $package1
+            ->expects($this->once())
+            ->method('getName')
+            ->will($this->returnValue('pkg1'));
+
+        $this->setExpectedException('LogicException');
+
+        $locker->lockPackages(array($package1));
+    }
+
+    private function createJsonFileMock()
+    {
+        return $this->getMockBuilder('Composer\Json\JsonFile')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    private function createRepositoryManagerMock()
+    {
+        return $this->getMockBuilder('Composer\Repository\RepositoryManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    private function createPackageMock()
+    {
+        return $this->getMockBuilder('Composer\Package\PackageInterface')
+            ->getMock();
+    }
+}