1
0
Fork 0

Adding support for configurable vendor path in composer.json.

pull/110/head
Ant Cunningham 2011-11-15 15:46:41 -05:00
parent e060ead6c2
commit e0400773f7
6 changed files with 97 additions and 19 deletions

View File

@ -46,6 +46,21 @@ in a system wide way.
3. Change into a project directory `cd /path/to/my/project` 3. Change into a project directory `cd /path/to/my/project`
4. Use composer as you normally would `composer.phar install` 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 Contributing
------------ ------------

View File

@ -16,7 +16,27 @@ use Composer\Package;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Console\Application as ComposerApplication; 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 // initialize repository manager
$rm = new Repository\RepositoryManager(); $rm = new Repository\RepositoryManager();
@ -33,19 +53,12 @@ $dm->setDownloader('pear', new Downloader\PearDownloader());
$dm->setDownloader('zip', new Downloader\ZipDownloader()); $dm->setDownloader('zip', new Downloader\ZipDownloader());
// initialize installation manager // 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\LibraryInstaller($vendorPath, $dm, $rm->getLocalRepository(), null));
$im->addInstaller(new Installer\InstallerInstaller($vendorPath, $dm, $rm->getLocalRepository(), $im)); $im->addInstaller(new Installer\InstallerInstaller($vendorPath, $dm, $rm->getLocalRepository(), $im));
// load package // load package
$loader = new Package\Loader\ArrayLoader($rm); $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); $package = $loader->load($packageConfig);
// load default repository unless it's explicitly disabled // load default repository unless it's explicitly disabled

View File

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

View File

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

View File

@ -28,6 +28,27 @@ class InstallationManager
{ {
private $installers = array(); private $installers = array();
private $cache = 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 * Adds installer
@ -150,4 +171,19 @@ class InstallationManager
$installer = $this->getInstaller($package->getType()); $installer = $this->getInstaller($package->getType());
return $installer->getInstallPath($package); 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;
}
} }

View File

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