diff --git a/CHANGELOG.md b/CHANGELOG.md index f84df19..9c422d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## Release 1.28.0 +* Add support for composer's `vendor-dir` setting when building autoloader based on composer.json and custom vendor directory location + ## Release 1.27.2 * Fix/Avoid deprecation notices in PHP 8.2 diff --git a/composer/bin/phpab b/composer/bin/phpab index 617aa38..0f931c4 100755 --- a/composer/bin/phpab +++ b/composer/bin/phpab @@ -59,5 +59,5 @@ foreach ($files as $file) { require __DIR__ . '/../../src/autoload.php'; $factory = new \TheSeer\Autoload\Factory(); -$factory->getCLI()->run(); +$factory->getCLI()->run($_SERVER); exit(0); diff --git a/phpab.php b/phpab.php index 35a5aad..2e2bdbd 100755 --- a/phpab.php +++ b/phpab.php @@ -51,5 +51,5 @@ require __DIR__ . '/src/autoload.php'; $factory = new \TheSeer\Autoload\Factory(); -$factory->getCLI()->run(); +$factory->getCLI()->run($_SERVER); exit(0); diff --git a/src/CLI.php b/src/CLI.php index f043876..343b2e7 100644 --- a/src/CLI.php +++ b/src/CLI.php @@ -73,7 +73,7 @@ public function __construct(Factory $factory) { * * @return void */ - public function run() { + public function run(array $env) { try { @@ -93,7 +93,7 @@ public function run() { exit(CLI::RC_OK); } - $config = $this->configure($input); + $config = $this->configure($env, $input); $this->factory->setConfig($config); if (!$config->isQuietMode()) { $this->showVersion(); @@ -140,7 +140,7 @@ public function run() { * * @return \TheSeer\Autoload\Config */ - private function configure(\ezcConsoleInput $input) { + private function configure(array $env, \ezcConsoleInput $input) { $config = new Config($input->getArguments()); if ($input->getOption('quiet')->value) { $config->setQuietMode(TRUE); @@ -262,6 +262,14 @@ private function configure(\ezcConsoleInput $input) { $config->setTrusting(FALSE); } + if (isset($env['HOME'])) { + $config->setHomeDirectory($env['HOME']); + } elseif (isset($env['HOMEDRIVE']) && isset($env['HOMEPATH'])) { + $config->setHomeDirectory($env['HOMEDRIVE'] . $env['HOMEPATH']); + } else { + $config->setHomeDirectory('/'); + } + return $config; } diff --git a/src/ComposerIterator.php b/src/ComposerIterator.php index d543500..5975c3d 100644 --- a/src/ComposerIterator.php +++ b/src/ComposerIterator.php @@ -12,7 +12,7 @@ class ComposerIterator implements \Iterator { private $pos = 0; - public function __construct(\SplFileInfo $composerFile) { + public function __construct(\SplFileInfo $composerFile, $homeDirectory) { if (!$composerFile->isFile() || !$composerFile->isReadable()) { throw new ComposerIteratorException( sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()), @@ -21,12 +21,22 @@ public function __construct(\SplFileInfo $composerFile) { } $composerDir = dirname($composerFile->getRealPath()); $composerData = json_decode(file_get_contents($composerFile->getRealPath()), true); + + $vendorDir = $composerDir . '/vendor'; + if (isset($composerData['config']['vendor-dir'])) { + $vendorDir = preg_replace( + '/($HOME|~)/', + $homeDirectory, + $composerData['config']['vendor-dir'] + ); + } + if (isset($composerData['require'])) { foreach($composerData['require'] as $require => $version) { if ($require === 'php' || strpos($require, 'ext-') === 0) { continue; } - $this->processRequire($composerDir, $require); + $this->processRequire($vendorDir, $require); } } if (isset($composerData['autoload'])) { @@ -66,7 +76,8 @@ private function processRequire($basedir, $require) { } $this->seen[$require] = true; - $requireDir = $basedir . '/vendor/' . $require; + $requireDir = $basedir . '/' . $require; + $jsonFile = $this->findComposerJson($requireDir); if ($jsonFile === null) { return; @@ -168,7 +179,6 @@ public function valid() { public function rewind() { $this->pos = 0; } - } class ComposerIteratorException extends \Exception { diff --git a/src/Config.php b/src/Config.php index c0b41cb..61d935b 100644 --- a/src/Config.php +++ b/src/Config.php @@ -73,6 +73,8 @@ class Config { private $prepend = false; private $exceptions = true; + private $homeDirectory = ''; + public function __construct(Array $directories) { $this->directories = $directories; $this->php = (PHP_OS === 'WIN' ? 'C:\php\php.exe' : '/usr/bin/php'); @@ -82,6 +84,14 @@ public function setBaseDirectory($baseDirectory) { $this->baseDirectory = $baseDirectory; } + public function setHomeDirectory($homeDir) { + $this->homeDirectory = $homeDir; + } + + public function getHomeDirectory(): string { + return $this->homeDirectory; + } + public function getBaseDirectory() { if ($this->baseDirectory !== NULL) { return realpath($this->baseDirectory); @@ -391,7 +401,7 @@ public function getDirectories() { $list = array(); foreach($this->directories as $dir) { if (is_file($dir) && basename($dir) == 'composer.json') { - foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) { + foreach(new ComposerIterator(new \SplFileInfo($dir), $this->getHomeDirectory()) as $d) { $list[] = $d; } } else { diff --git a/tests/ComposerIteratorTest.php b/tests/ComposerIteratorTest.php index deee126..c9728a3 100644 --- a/tests/ComposerIteratorTest.php +++ b/tests/ComposerIteratorTest.php @@ -6,7 +6,7 @@ class ComposerIteratorTest extends TestCase { public function testRecursionIsHandledProperly() { - $iterator = new ComposerIterator(new \SplFileInfo(__DIR__ . '/_data/recursion/composer.json')); + $iterator = new ComposerIterator(new \SplFileInfo(__DIR__ . '/_data/recursion/composer.json'), array()); $expected = array( __DIR__ . '/_data/recursion/vendor/foo/bar', __DIR__ . '/_data/recursion/vendor/bar/foo' @@ -17,7 +17,7 @@ public function testRecursionIsHandledProperly() { } public function testPSR14ArrayIsSupported() { - $iterator = new ComposerIterator(new \SplFileInfo(__DIR__ . '/_data/composer-array-issue-98/composer.json')); + $iterator = new ComposerIterator(new \SplFileInfo(__DIR__ . '/_data/composer-array-issue-98/composer.json'), array()); $expected = array( __DIR__ . '/_data/composer-array-issue-98/../src', __DIR__ . '/_data/composer-array-issue-98/modules',