Quellcode durchsuchen

Adding support for configurable vendor path in composer.json.

Ant Cunningham vor 13 Jahren
Ursprung
Commit
e0400773f7

+ 16 - 1
README.md

@@ -20,7 +20,7 @@ themselves. To create libraries/packages please read the [guidelines](http://pac
         }
     }
     ```
-
+    
 3. Run Composer: `php composer.phar install`
 4. Browse for more packages on [Packagist](http://packagist.org).
 
@@ -46,6 +46,21 @@ in a system wide way.
 3. Change into a project directory `cd /path/to/my/project`
 4. Use composer as you normally would `composer.phar install`
 
+Configuration
+-------------
+
+Additional options for composer can be configured in `composer.json` by using the `config` section. 
+
+``` json
+{
+    "config": {
+        "vendor-dir": "custom/path/for/vendor"
+    }
+}
+```
+
+* `vendor-dir`: The location to install vendor packages. The location can be supplied as an absolute or relative path but **must** be within the current working directory.
+
 Contributing
 ------------
 

+ 22 - 9
bin/composer

@@ -16,7 +16,27 @@ use Composer\Package;
 use Composer\Json\JsonFile;
 use Composer\Console\Application as ComposerApplication;
 
-$vendorPath = 'vendor';
+// load Composer configuration
+$file = new JsonFile('composer.json');
+if (!$file->exists()) {
+    echo 'Composer could not find a composer.json file in '.getcwd().PHP_EOL;
+    echo 'To initialize a project, please create a composer.json file as described on the http://packagist.org/ "Getting Started" section'.PHP_EOL;
+    exit(1);
+}
+
+// Configuration defaults
+$composerConfig = array('vendor-dir' => 'vendor');
+
+$packageConfig = $file->read();
+
+if (isset($packageConfig['config']) && is_array($packageConfig['config'])) {
+    $packageConfig['config'] = array_merge($composerConfig, $packageConfig['config']);
+} else {
+    $packageConfig['config'] = $composerConfig;
+}
+
+// easy local access
+$vendorPath = $packageConfig['config']['vendor-dir'];
 
 // initialize repository manager
 $rm = new Repository\RepositoryManager();
@@ -33,19 +53,12 @@ $dm->setDownloader('pear', new Downloader\PearDownloader());
 $dm->setDownloader('zip',  new Downloader\ZipDownloader());
 
 // initialize installation manager
-$im = new Installer\InstallationManager();
+$im = new Installer\InstallationManager($vendorPath);
 $im->addInstaller(new Installer\LibraryInstaller($vendorPath, $dm, $rm->getLocalRepository(), null));
 $im->addInstaller(new Installer\InstallerInstaller($vendorPath, $dm, $rm->getLocalRepository(), $im));
 
 // load package
 $loader  = new Package\Loader\ArrayLoader($rm);
-$file = new JsonFile('composer.json');
-if (!$file->exists()) {
-    echo 'Composer could not find a composer.json file in '.getcwd().PHP_EOL;
-    echo 'To initialize a project, please create a composer.json file as described on the http://packagist.org/ "Getting Started" section'.PHP_EOL;
-    exit(1);
-}
-$packageConfig = $file->read();
 $package = $loader->load($packageConfig);
 
 // load default repository unless it's explicitly disabled

+ 3 - 2
src/Composer/Autoload/AutoloadGenerator.php

@@ -71,12 +71,13 @@ EOF;
         $packageMap[] = array($mainPackage, '');
 
         $autoloads = $this->parseAutoloads($packageMap);
+        $vendorPath = $installationManager->getVendorPath();
 
         if (isset($autoloads['psr-0'])) {
             foreach ($autoloads['psr-0'] as $def) {
                 if (!$this->isAbsolutePath($def['path'])) {
-                    $baseDir = 'dirname(dirname(__DIR__)).';
-                    $def['path'] = '/'.$def['path'];
+                    $def['path'] = substr($def['path'], strlen($vendorPath));
+                    $baseDir = "dirname(__DIR__).";
                 } else {
                     $baseDir = '';
                 }

+ 1 - 1
src/Composer/Command/InstallCommand.php

@@ -154,7 +154,7 @@ EOT
 
         $output->writeln('> Generating autoload files');
         $generator = new AutoloadGenerator;
-        $generator->dump($localRepo, $composer->getPackage(), $installationManager, 'vendor/.composer/');
+        $generator->dump($localRepo, $composer->getPackage(), $installationManager, $installationManager->getVendorPath().'/.composer');
 
         $output->writeln('> Done');
     }

+ 37 - 1
src/Composer/Installer/InstallationManager.php

@@ -28,6 +28,27 @@ class InstallationManager
 {
     private $installers = array();
     private $cache = array();
+    private $vendorPath;
+
+    /**
+     * Creates an instance of InstallationManager
+     * 
+     * @param    string    $vendorPath    Relative path to the vendor directory
+     * @throws   \InvalidArgumentException
+     */
+    public function __construct($vendorPath = 'vendor')
+    {
+        if (substr($vendorPath, 0, 1) === '/' || substr($vendorPath, 1, 1) === ':') {
+            $basePath = getcwd();
+            if (0 !== strpos($vendorPath, $basePath)) {
+                throw new \InvalidArgumentException("Vendor path ($vendorPath) must be within the current working directory ($basePath).");
+            }
+            // convert to relative path
+            $this->vendorPath = substr($vendorPath, strlen($basePath)+1);
+        } else {
+            $this->vendorPath = $vendorPath;
+        }
+    }
 
     /**
      * Adds installer
@@ -150,4 +171,19 @@ class InstallationManager
         $installer = $this->getInstaller($package->getType());
         return $installer->getInstallPath($package);
     }
-}
+
+    /**
+     * Returns the vendor path
+     * 
+     * @param   boolean  $absolute  Whether or not to return an absolute path
+     * @return  string path
+     */
+    public function getVendorPath($absolute = false)
+    {
+        if (!$absolute) {
+            return $this->vendorPath;
+        }
+
+        return getcwd().DIRECTORY_SEPARATOR.$this->vendorPath;
+    }
+}

+ 18 - 5
tests/Composer/Test/Installer/InstallationManagerTest.php

@@ -30,7 +30,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
                 return $arg === 'vendor';
             }));
 
-        $manager   = new InstallationManager();
+        $manager   = new InstallationManager('vendor');
 
         $manager->addInstaller($installer);
         $this->assertSame($installer, $manager->getInstaller('vendor'));
@@ -43,6 +43,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     {
         $manager = $this->getMockBuilder('Composer\Installer\InstallationManager')
             ->setMethods(array('install', 'update', 'uninstall'))
+            ->setConstructorArgs(array('vendor'))
             ->getMock();
 
         $installOperation = new InstallOperation($this->createPackageMock());
@@ -72,7 +73,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     public function testInstall()
     {
         $installer = $this->createInstallerMock();
-        $manager   = new InstallationManager();
+        $manager   = new InstallationManager('vendor');
         $manager->addInstaller($installer);
 
         $package   = $this->createPackageMock();
@@ -100,7 +101,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     public function testUpdateWithEqualTypes()
     {
         $installer = $this->createInstallerMock();
-        $manager   = new InstallationManager();
+        $manager   = new InstallationManager('vendor');
         $manager->addInstaller($installer);
 
         $initial   = $this->createPackageMock();
@@ -134,7 +135,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     {
         $libInstaller = $this->createInstallerMock();
         $bundleInstaller = $this->createInstallerMock();
-        $manager    = new InstallationManager();
+        $manager    = new InstallationManager('vendor');
         $manager->addInstaller($libInstaller);
         $manager->addInstaller($bundleInstaller);
 
@@ -180,7 +181,7 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
     public function testUninstall()
     {
         $installer = $this->createInstallerMock();
-        $manager   = new InstallationManager();
+        $manager   = new InstallationManager('vendor');
         $manager->addInstaller($installer);
 
         $package   = $this->createPackageMock();
@@ -205,6 +206,18 @@ class InstallationManagerTest extends \PHPUnit_Framework_TestCase
         $manager->uninstall($operation);
     }
 
+    public function testGetVendorPathAbsolute()
+    {
+        $manager = new InstallationManager('vendor');
+        $this->assertEquals(realpath('').DIRECTORY_SEPARATOR.'vendor', $manager->getVendorPath(true));
+    }
+
+    public function testGetVendorPathRelative()
+    {
+        $manager = new InstallationManager('vendor');
+        $this->assertEquals('vendor', $manager->getVendorPath());
+    }
+
     private function createInstallerMock()
     {
         return $this->getMockBuilder('Composer\Installer\InstallerInterface')