Last active
February 3, 2022 07:36
-
-
Save forsvunnet/e472e03a23be75cc12f3f71e0dace7e3 to your computer and use it in GitHub Desktop.
Module loader script for composer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Support; | |
class ComposerModuleAutoLoader | |
{ | |
public static function load($event) | |
{ | |
$package = $event->getComposer()->getPackage(); | |
$base_path = dirname(__DIR__, 2).'/'; | |
$dirs = glob( | |
$base_path.'modules/*', | |
GLOB_ONLYDIR | |
); | |
$paths = array_map( | |
fn($dir) => str_replace($base_path, '', $dir), | |
$dirs | |
); | |
$autoload = $package->getAutoload(); | |
$autoload['psr-4'] = array_merge( | |
$autoload['psr-4'], | |
self::generatePsr4($paths, false) | |
); | |
$package->setAutoload($autoload); | |
$autoloadDev = $package->getDevAutoload(); | |
$autoloadDev['psr-4'] = array_merge( | |
$autoloadDev['psr-4'], | |
self::generatePsr4($paths, true) | |
); | |
$package->setDevAutoload($autoloadDev); | |
$configSource = $event->getComposer()->getConfig()->getConfigSource(); | |
self::updateComposerJson($configSource, 'autoload', $autoload); | |
self::updateComposerJson($configSource, 'autoload-dev', $autoloadDev); | |
self::reformatComposerJson($configSource->getName()); | |
} | |
private static function generatePsr4(array $paths, bool $dev): array | |
{ | |
$psr4 = []; | |
foreach ($paths as $path) { | |
$namespaces = self::getNamespacesFromPath($path, $dev); | |
$psr4 = array_merge( | |
$psr4, | |
$namespaces | |
); | |
} | |
return $psr4; | |
} | |
private static function getNamespacesFromPath(string $path, bool $dev): array | |
{ | |
// Get the relative path and the namespace name for each module directory. | |
$name = str_replace("modules/", '', $path); | |
if (!preg_match('/^[A-Z][\w]*$/', $name)) { | |
return []; | |
} | |
$namespaces = []; | |
if (! $dev && file_exists("$path/src") && is_dir("$path/src")) { | |
$namespaces["Modules\\$name\\"] = "$path/src"; | |
} | |
if ($dev && file_exists("$path/tests") && is_dir("$path/tests")) { | |
$namespaces["Modules\\$name\\Tests\\"] = "$path/tests"; | |
} | |
return $namespaces; | |
} | |
private static function updateComposerJson($configSource, string $key, array $autoload) | |
{ | |
// Add a placeholder so that the key "autoload" is not removed when removing psr-4. | |
$configSource->addLink($key, 'tmp', 'placeholder'); | |
$configSource->removeLink($key, 'psr-4'); | |
// Add back psr-4 after changes and remove the placeholder key. | |
$configSource->addLink($key, 'psr-4', $autoload['psr-4']); | |
$configSource->removeLink($key, 'tmp'); | |
} | |
private static function reformatComposerJson(string $filename) | |
{ | |
// Read the composer.json and re-format it to fix indentation. | |
$content = file_get_contents($filename); | |
$json = json_encode( | |
json_decode($content, true), | |
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | |
); | |
if (!$json) { | |
return; | |
} | |
file_put_contents( | |
$filename, | |
$json | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment