Browse Source

Re-install binaries on update/install

Binaries are re-installed after an update/install (ie: removed and then installed)
Jeremy Benoist 9 years ago
parent
commit
e9fc0e6548

+ 0 - 1
src/Composer/Factory.php

@@ -292,7 +292,6 @@ class Factory
         }
 
         $vendorDir = $config->get('vendor-dir');
-        $binDir = $config->get('bin-dir');
 
         // initialize composer
         $composer = new Composer();

+ 6 - 0
src/Composer/Installer.php

@@ -337,6 +337,12 @@ class Installer
                 $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
             }
 
+            // force binaries re-generation
+            $this->io->writeError('<info>Installing binaries files</info>');
+            foreach ($localRepo->getPackages() as $package) {
+               $this->installationManager->installBinary($package);
+            }
+
             $vendorDir = $this->config->get('vendor-dir');
             if (is_dir($vendorDir)) {
                 // suppress errors as this fails sometimes on OSX for no apparent reason

+ 16 - 0
src/Composer/Installer/InstallationManager.php

@@ -127,6 +127,22 @@ class InstallationManager
         return $this->getInstaller($package->getType())->isInstalled($repo, $package);
     }
 
+    /**
+     * Install binary for the given package.
+     * If the installer associated to this package doesn't handle that function, it'll do nothing.
+     *
+     * @param PackageInterface $package Package instance
+     */
+    public function installBinary(PackageInterface $package)
+    {
+        try {
+            $installer = $this->getInstaller($package->getType());
+            $installer->installBinary($package);
+        } catch (\InvalidArgumentException $e) {
+            // the given installer doesn't support installing binaries
+        }
+    }
+
     /**
      * Executes solver operation.
      *

+ 11 - 0
src/Composer/Installer/LibraryInstaller.php

@@ -149,6 +149,17 @@ class LibraryInstaller implements InstallerInterface
         return $basePath . ($targetDir ? '/'.$targetDir : '');
     }
 
+    /**
+     * Re-install binary by removing previous one
+     *
+     * @param PackageInterface $package Package instance
+     */
+    public function installBinary(PackageInterface $package)
+    {
+        $this->binaryInstaller->removeBinaries($package);
+        $this->binaryInstaller->installBinaries($package, $this->getInstallPath($package));
+    }
+
     /**
      * Returns the base path of the package without target-dir path
      *

+ 1 - 0
tests/Composer/Test/Fixtures/functional/create-project-command.test

@@ -11,3 +11,4 @@ Updating dependencies (including require-dev)
 Nothing to install or update
 Writing lock file
 Generating autoload files
+Installing binaries files

+ 1 - 0
tests/Composer/Test/Fixtures/installer/abandoned-listed.test

@@ -30,6 +30,7 @@ Updating dependencies (including require-dev)
 <warning>Package c/c is abandoned, you should avoid using it. Use b/b instead.</warning>
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Installing a/a (1.0.0)

+ 1 - 0
tests/Composer/Test/Fixtures/installer/github-issues-4795-2.test

@@ -38,6 +38,7 @@ Loading composer repositories with package information
 Updating dependencies (including require-dev)
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Updating a (1.0.0) to a (1.1.0)

+ 1 - 0
tests/Composer/Test/Fixtures/installer/github-issues-4795.test

@@ -40,5 +40,6 @@ Updating dependencies (including require-dev)
 Nothing to install or update
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--

+ 1 - 0
tests/Composer/Test/Fixtures/installer/suggest-installed.test

@@ -23,6 +23,7 @@ Loading composer repositories with package information
 Updating dependencies (including require-dev)
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Installing a/a (1.0.0)

+ 1 - 0
tests/Composer/Test/Fixtures/installer/suggest-prod.test

@@ -21,6 +21,7 @@ Loading composer repositories with package information
 Updating dependencies
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Installing a/a (1.0.0)

+ 1 - 0
tests/Composer/Test/Fixtures/installer/suggest-replaced.test

@@ -23,6 +23,7 @@ Loading composer repositories with package information
 Updating dependencies (including require-dev)
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Installing c/c (1.0.0)

+ 1 - 0
tests/Composer/Test/Fixtures/installer/suggest-uninstalled.test

@@ -22,6 +22,7 @@ Updating dependencies (including require-dev)
 a/a suggests installing b/b (an obscure reason)
 Writing lock file
 Generating autoload files
+Installing binaries files
 
 --EXPECT--
 Installing a/a (1.0.0)

+ 29 - 0
tests/Composer/Test/Installer/InstallationManagerTest.php

@@ -240,6 +240,35 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
         $manager->uninstall($this->repository, $operation);
     }
 
+    public function testInstallBinary()
+    {
+        $installer = $this->getMockBuilder('Composer\Installer\LibraryInstaller')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $manager   = new InstallationManager();
+        $manager->addInstaller($installer);
+
+        $package   = $this->createPackageMock();
+
+        $package
+            ->expects($this->once())
+            ->method('getType')
+            ->will($this->returnValue('library'));
+
+        $installer
+            ->expects($this->once())
+            ->method('supports')
+            ->with('library')
+            ->will($this->returnValue(true));
+
+        $installer
+            ->expects($this->once())
+            ->method('installBinary')
+            ->with($package);
+
+        $manager->installBinary($package);
+    }
+
     private function createInstallerMock()
     {
         return $this->getMockBuilder('Composer\Installer\InstallerInterface')

+ 26 - 0
tests/Composer/Test/Installer/LibraryInstallerTest.php

@@ -255,6 +255,32 @@ class LibraryInstallerTest extends TestCase
         $this->assertEquals($this->vendorDir.'/'.$package->getPrettyName().'/Some/Namespace', $library->getInstallPath($package));
     }
 
+    /**
+     * @depends testInstallerCreationShouldNotCreateVendorDirectory
+     * @depends testInstallerCreationShouldNotCreateBinDirectory
+     */
+    public function testInstallBinary()
+    {
+        $binaryInstallerMock = $this->getMockBuilder('Composer\Installer\BinaryInstaller')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $library = new LibraryInstaller($this->io, $this->composer, 'library', null, $binaryInstallerMock);
+        $package = $this->createPackageMock();
+
+        $binaryInstallerMock
+            ->expects($this->once())
+            ->method('removeBinaries')
+            ->with($package);
+
+        $binaryInstallerMock
+            ->expects($this->once())
+            ->method('installBinaries')
+            ->with($package, $library->getInstallPath($package));
+
+        $library->installBinary($package);
+    }
+
     protected function createPackageMock()
     {
         return $this->getMockBuilder('Composer\Package\Package')