From 817de1d148ce51ee5d1fa517b2d5ab4441d7e77c Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 15 Apr 2023 12:46:26 +0530 Subject: [PATCH 1/3] Add PSR-4 autoload paths for app plugins. This change avoids having to update the app's composer.json to add autoload paths for app plugins under the "plugins" folder. --- src/Plugin.php | 46 +++++++++++++++++++++++++++++ tests/TestCase/PluginTest.php | 55 ++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/Plugin.php b/src/Plugin.php index cf65fb9..23825d0 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -42,9 +42,55 @@ public static function getSubscribedEvents() { return [ 'post-autoload-dump' => 'postAutoloadDump', + 'pre-autoload-dump' => 'preAutoloadDump', ]; } + /** + * Add PSR-4 autoload paths for app plugins. + * + * @param \Composer\Script\Event $event + * @return void + */ + public function preAutoloadDump(Event $event): void + { + $package = $event->getComposer()->getPackage(); + $autoload = $package->getAutoload(); + $devAutoload = $package->getDevAutoload(); + + $extra = $package->getExtra(); + if (empty($extra['plugin-paths'])) { + $extra['plugin-paths'] = ['plugins']; + } + + $root = dirname(realpath($event->getComposer()->getConfig()->get('vendor-dir'))); + foreach ($extra['plugin-paths'] as $pluginsPath) { + foreach (new DirectoryIterator($root . '/' . $pluginsPath) as $fileInfo) { + if (!$fileInfo->isDir() || $fileInfo->isDot()) { + continue; + } + + $folderName = $fileInfo->getFilename(); + if ($folderName[0] === '.') { + continue; + } + + $pluginNamespace = $folderName . '\\'; + $pluginTestNamespace = $folderName . '\\Test\\'; + $path = $pluginsPath . '/' . $folderName . '/'; + if (!isset($autoload['psr-4'][$pluginNamespace])) { + $autoload['psr-4'][$pluginNamespace] = $path . 'src'; + } + if (!isset($devAutoload['psr-4'][$pluginTestNamespace])) { + $devAutoload['psr-4'][$pluginTestNamespace] = $path . 'tests'; + } + } + } + + $package->setAutoload($autoload); + $package->setDevAutoload($devAutoload); + } + /** * Called whenever composer (re)generates the autoloader. * diff --git a/tests/TestCase/PluginTest.php b/tests/TestCase/PluginTest.php index 766fb1b..ca56175 100644 --- a/tests/TestCase/PluginTest.php +++ b/tests/TestCase/PluginTest.php @@ -8,7 +8,9 @@ use Composer\Config; use Composer\IO\IOInterface; use Composer\Package\Package; +use Composer\Package\RootPackage; use Composer\Repository\RepositoryManager; +use Composer\Script\Event; use Composer\Util\HttpDownloader; use PHPUnit\Framework\TestCase; @@ -67,7 +69,9 @@ public function setUp(): void $this->composer = new Composer(); $config = new Config(); $config->merge([ - 'vendor-dir' => $this->path . '/vendor', + 'config' => [ + 'vendor-dir' => $this->path . '/vendor', + ], ]); $this->composer->setConfig($config); @@ -109,6 +113,7 @@ public function testGetSubscribedEvents() { $expected = [ 'post-autoload-dump' => 'postAutoloadDump', + 'pre-autoload-dump' => 'preAutoloadDump', ]; $this->assertSame($expected, $this->plugin->getSubscribedEvents()); @@ -120,6 +125,54 @@ public function testGetConfigFilePath() $this->assertFileExists(dirname($path)); } + public function testPreAutoloadDump() + { + $package = new RootPackage('App', '1.0.0', '1.0.0'); + $package->setExtra([ + 'plugin-paths' => [ + 'app_plugins', + 'plugins', + ], + ]); + $package->setAutoload([ + 'psr-4' => [ + 'Foo\\' => 'xyz/Foo/src', + ], + ]); + $package->setDevAutoload([ + 'psr-4' => [ + 'Foo\Test\\' => 'xyz/Foo/tests', + ], + ]); + $this->composer->setPackage($package); + + $event = new Event('', $this->composer, $this->io); + + $this->plugin->preAutoloadDump($event); + + $expected = [ + 'psr-4' => [ + 'Foo\\' => 'xyz/Foo/src', + 'Fee\\' => 'plugins/Fee/src', + 'Fum\\' => 'plugins/Fum/src', + 'Foe\\' => 'plugins/Foe/src', + 'Bar\\' => 'app_plugins/Bar/src', + ], + ]; + $this->assertEquals($expected, $package->getAutoload()); + + $expected = [ + 'psr-4' => [ + 'Foo\Test\\' => 'xyz/Foo/tests', + 'Fee\Test\\' => 'plugins/Fee/tests', + 'Fum\Test\\' => 'plugins/Fum/tests', + 'Foe\Test\\' => 'plugins/Foe/tests', + 'Bar\Test\\' => 'app_plugins/Bar/tests', + ], + ]; + $this->assertEquals($expected, $package->getDevAutoload()); + } + public function testGetPrimaryNamespace() { $autoload = [ From dc2b5b4fdb73e9b6b71ef946797d7994a0588fab Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 15 Apr 2023 12:55:48 +0530 Subject: [PATCH 2/3] Add phive config for CI --- .gitattributes | 1 + .phive/phars.xml | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 .phive/phars.xml diff --git a/.gitattributes b/.gitattributes index 371212d..47d8b0e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,6 +4,7 @@ * text eol=lf # Remove files for archives generated using `git archive` +.phive export-ignore .editorconfig export-ignore phpunit.xml.dist export-ignore phpcs.xml.dist export-ignore diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..31a09bc --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,5 @@ + + + + + From f9ea410f4561f52ffbf149926e102415faf97488 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 15 Apr 2023 21:15:37 +0530 Subject: [PATCH 3/3] Ensure directory exists when generating autload paths. --- src/Plugin.php | 8 ++++---- tests/TestCase/PluginTest.php | 30 ++++++++++-------------------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/Plugin.php b/src/Plugin.php index 23825d0..a7695c5 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -63,9 +63,9 @@ public function preAutoloadDump(Event $event): void $extra['plugin-paths'] = ['plugins']; } - $root = dirname(realpath($event->getComposer()->getConfig()->get('vendor-dir'))); + $root = dirname(realpath($event->getComposer()->getConfig()->get('vendor-dir'))) . '/'; foreach ($extra['plugin-paths'] as $pluginsPath) { - foreach (new DirectoryIterator($root . '/' . $pluginsPath) as $fileInfo) { + foreach (new DirectoryIterator($root . $pluginsPath) as $fileInfo) { if (!$fileInfo->isDir() || $fileInfo->isDot()) { continue; } @@ -78,10 +78,10 @@ public function preAutoloadDump(Event $event): void $pluginNamespace = $folderName . '\\'; $pluginTestNamespace = $folderName . '\\Test\\'; $path = $pluginsPath . '/' . $folderName . '/'; - if (!isset($autoload['psr-4'][$pluginNamespace])) { + if (!isset($autoload['psr-4'][$pluginNamespace]) && is_dir($root . $path . '/src')) { $autoload['psr-4'][$pluginNamespace] = $path . 'src'; } - if (!isset($devAutoload['psr-4'][$pluginTestNamespace])) { + if (!isset($devAutoload['psr-4'][$pluginTestNamespace]) && is_dir($root . $path . '/tests')) { $devAutoload['psr-4'][$pluginTestNamespace] = $path . 'tests'; } } diff --git a/tests/TestCase/PluginTest.php b/tests/TestCase/PluginTest.php index ca56175..4c46073 100644 --- a/tests/TestCase/PluginTest.php +++ b/tests/TestCase/PluginTest.php @@ -33,15 +33,14 @@ class PluginTest extends TestCase * @var array */ protected array $testDirs = [ - '', 'vendor', - 'plugins', 'plugins/Foo', - 'plugins/Fee', - 'plugins/Foe', + 'plugins/Fee/src', + 'plugins/Fee/tests', + 'plugins/Foe/src', 'plugins/Fum', - 'app_plugins', - 'app_plugins/Bar', + 'app_plugins/Bar/src', + 'app_plugins/Bar/tests', ]; protected string $path; @@ -62,7 +61,7 @@ public function setUp(): void foreach ($this->testDirs as $dir) { if (!is_dir($this->path . '/' . $dir)) { - mkdir($this->path . '/' . $dir); + mkdir($this->path . '/' . $dir, 0777, true); } } @@ -96,16 +95,10 @@ public function tearDown(): void { parent::tearDown(); - $dirs = array_reverse($this->testDirs); - - if (is_file($this->path . '/vendor/cakephp-plugins.php')) { - unlink($this->path . '/vendor/cakephp-plugins.php'); - } - - foreach ($dirs as $dir) { - if (is_dir($this->path . '/' . $dir)) { - rmdir($this->path . '/' . $dir); - } + if (PHP_OS === 'Windows') { + exec(sprintf('rd /s /q %s', escapeshellarg($this->path))); + } else { + exec(sprintf('rm -rf %s', escapeshellarg($this->path))); } } @@ -154,7 +147,6 @@ public function testPreAutoloadDump() 'psr-4' => [ 'Foo\\' => 'xyz/Foo/src', 'Fee\\' => 'plugins/Fee/src', - 'Fum\\' => 'plugins/Fum/src', 'Foe\\' => 'plugins/Foe/src', 'Bar\\' => 'app_plugins/Bar/src', ], @@ -165,8 +157,6 @@ public function testPreAutoloadDump() 'psr-4' => [ 'Foo\Test\\' => 'xyz/Foo/tests', 'Fee\Test\\' => 'plugins/Fee/tests', - 'Fum\Test\\' => 'plugins/Fum/tests', - 'Foe\Test\\' => 'plugins/Foe/tests', 'Bar\Test\\' => 'app_plugins/Bar/tests', ], ];