Skip to content
This repository was archived by the owner on Feb 10, 2023. It is now read-only.

Commit cebd9eb

Browse files
Generate optimized classmap
1 parent 3ce04b6 commit cebd9eb

File tree

2 files changed

+140
-42
lines changed

2 files changed

+140
-42
lines changed

src/Internal/ComposerPlugin.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
use Composer\Json\JsonFile;
1818
use Composer\Json\JsonManipulator;
1919
use Composer\Package\Locker;
20+
use Composer\Package\Package;
2021
use Composer\Package\Version\VersionParser;
2122
use Composer\Package\Version\VersionSelector;
2223
use Composer\Plugin\PluginInterface;
2324
use Composer\Repository\InstalledRepositoryInterface;
2425
use Composer\Repository\RepositorySet;
2526
use Composer\Script\Event;
2627
use Composer\Script\ScriptEvents;
28+
use Composer\Util\Filesystem;
2729

2830
/**
2931
* @internal
@@ -83,6 +85,56 @@ public function uninstall(Composer $composer, IOInterface $io)
8385
{
8486
}
8587

88+
public function preAutoloadDump(Event $event)
89+
{
90+
$filesystem = new Filesystem();
91+
$vendor = $filesystem->normalizePath(realpath(realpath($event->getComposer()->getConfig()->get('vendor-dir'))));
92+
$filesystem->ensureDirectoryExists($vendor.'/composer');
93+
94+
$repo = $event->getComposer()->getRepositoryManager()->getLocalRepository();
95+
$vendors = self::initializeConcreteImplementation($repo);
96+
97+
$namespace = __NAMESPACE__;
98+
$psr7Vendor = str_replace(['NULL', '\\\\'], ['null', '\\'], var_export(PSR7_VENDOR, true));
99+
$psr18Vendor = str_replace(['NULL', '\\\\'], ['null', '\\'], var_export(PSR18_VENDOR, true));
100+
$httplugVendor = str_replace(['NULL', '\\\\'], ['null', '\\'], var_export(HTTPLUG_VENDOR, true));
101+
102+
$filesystem->filePutContentsIfModified($vendor.'/composer/WellKnownConcreteImplementation.php', <<<EOPHP
103+
<?php
104+
105+
namespace $namespace;
106+
107+
class ConcreteImplementation
108+
{
109+
public const PSR7_VENDOR = $psr7Vendor;
110+
public const PSR18_VENDOR = $psr18Vendor;
111+
public const HTTPLUG_VENDOR = $httplugVendor;
112+
}
113+
114+
EOPHP
115+
);
116+
117+
$rootPackage = $event->getComposer()->getPackage();
118+
$autoload = $rootPackage->getAutoload();
119+
$autoload['classmap'][] = $vendor.'/composer/WellKnownConcreteImplementation.php';
120+
$rootPackage->setAutoload($autoload);
121+
122+
unset($vendors[PSR7_VENDOR], $vendors[PSR18_VENDOR], $vendors[HTTPLUG_VENDOR]);
123+
124+
foreach ($repo->getPackages() as $package) {
125+
if ('friendsofphp/well-known-implementations' !== $package->getName() || !$package instanceof Package) {
126+
continue;
127+
}
128+
$autoload = $package->getAutoload();
129+
$autoload['exclude-from-classmap'][] = 'src/Internal/ComposerPlugin.php';
130+
$autoload['exclude-from-classmap'][] = 'src/Internal/ConcreteImplementation.php';
131+
foreach ($vendors as $vendor) {
132+
$autoload['exclude-from-classmap'][] = 'src/Internal/'.$vendor.'/';
133+
}
134+
$package->setAutoload($autoload);
135+
}
136+
}
137+
86138
public function postUpdate(Event $event)
87139
{
88140
$composer = $event->getComposer();
@@ -125,6 +177,7 @@ public function postUpdate(Event $event)
125177

126178
/** @var Installer $installer */
127179
$installer = clone $installer;
180+
$trace['object']->setAudit(false);
128181
$installer->__construct(
129182
$event->getIO(),
130183
$composer->getConfig(),
@@ -276,6 +329,7 @@ public function updateComposerJson(array $missingRequires, bool $sortPackages)
276329
public static function getSubscribedEvents(): array
277330
{
278331
return [
332+
ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump',
279333
ScriptEvents::POST_UPDATE_CMD => 'postUpdate',
280334
];
281335
}
@@ -290,4 +344,41 @@ private function updateComposerLock(Composer $composer, IOInterface $io)
290344
$lockData['content-hash'] = Locker::getContentHash($composerJson);
291345
$lockFile->write($lockData);
292346
}
347+
348+
private static function initializeConcreteImplementation(InstalledRepositoryInterface $repo): array
349+
{
350+
$vendors = [];
351+
352+
foreach (ConcreteImplementation::IMPLEMENTATIONS as $const => $packages) {
353+
$vendors += $packages;
354+
if (\defined(__NAMESPACE__."\\{$const}_VENDOR")) {
355+
continue;
356+
}
357+
foreach ([false, true] as $includeDevRequirements) {
358+
foreach ($packages as $namespace => $versions) {
359+
foreach ((array) $versions as $package => $version) {
360+
if (\is_int($package)) {
361+
$package = $version;
362+
$version = null;
363+
}
364+
if (!$includeDevRequirements && \in_array($package, $repo->getDevPackageNames(), true)) {
365+
continue 2;
366+
}
367+
if (!$repo->findPackage($package, null !== $version ? '>='.$version : '*')) {
368+
continue 2;
369+
}
370+
}
371+
\define(__NAMESPACE__."\\{$const}_VENDOR", $namespace);
372+
continue 3;
373+
}
374+
}
375+
\define(__NAMESPACE__."\\{$const}_VENDOR", null);
376+
}
377+
378+
foreach ($vendors as $vendor => $versions) {
379+
$vendors[$vendor] = $vendor;
380+
}
381+
382+
return $vendors;
383+
}
293384
}

src/Internal/ConcreteImplementation.php

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,6 @@
1111

1212
use Composer\InstalledVersions;
1313

14-
foreach ([
15-
'PSR7' => [
16-
'Nyholm' => 'nyholm/psr7',
17-
'Guzzle' => ['guzzlehttp/psr7' => '1.4'],
18-
'Slim' => 'slim/psr7',
19-
'Laminas' => 'laminas/laminas-diactoros',
20-
],
21-
'PSR18' => [
22-
'Symfony' => 'symfony/http-client',
23-
'Guzzle' => ['guzzlehttp/guzzle' => '7.0'],
24-
],
25-
'HTTPLUG' => [
26-
'Symfony' => ['symfony/http-client' => '4.4'],
27-
'PhpHttpGuzzle7' => 'php-http/guzzle7-adapter',
28-
'PhpHttpGuzzle6' => 'php-http/guzzle6-adapter',
29-
'PhpHttpCurl' => 'php-http/curl-client',
30-
'PhpHttpReact' => 'php-http/react-adapter',
31-
],
32-
] as $const => $packages) {
33-
if (\defined(__NAMESPACE__."\\{$const}_VENDOR")) {
34-
continue;
35-
}
36-
foreach ([false, true] as $includeDevRequirements) {
37-
foreach ($packages as $namespace => $versions) {
38-
foreach ((array) $versions as $package => $version) {
39-
if (\is_int($package)) {
40-
$package = $version;
41-
$version = null;
42-
}
43-
if (!InstalledVersions::isInstalled($package, $includeDevRequirements)) {
44-
continue 2;
45-
}
46-
if (null !== $version && version_compare($installed = InstalledVersions::getVersion($package) ?? $version, $version, '<') && 0 !== strpos($installed, 'dev-')) {
47-
continue 2;
48-
}
49-
}
50-
\define(__NAMESPACE__."\\{$const}_VENDOR", $namespace);
51-
continue 3;
52-
}
53-
}
54-
\define(__NAMESPACE__."\\{$const}_VENDOR", null);
55-
}
5614
/**
5715
* @internal
5816
*/
@@ -61,4 +19,53 @@ class ConcreteImplementation
6119
public const PSR7_VENDOR = PSR7_VENDOR;
6220
public const PSR18_VENDOR = PSR18_VENDOR;
6321
public const HTTPLUG_VENDOR = HTTPLUG_VENDOR;
22+
public const IMPLEMENTATIONS = [
23+
'PSR7' => [
24+
'Nyholm' => 'nyholm/psr7',
25+
'Guzzle' => ['guzzlehttp/psr7' => '1.4'],
26+
'Slim' => 'slim/psr7',
27+
'Laminas' => 'laminas/laminas-diactoros',
28+
],
29+
'PSR18' => [
30+
'Symfony' => 'symfony/http-client',
31+
'Guzzle' => ['guzzlehttp/guzzle' => '7.0'],
32+
],
33+
'HTTPLUG' => [
34+
'Symfony' => ['symfony/http-client' => '4.4'],
35+
'PhpHttpGuzzle7' => 'php-http/guzzle7-adapter',
36+
'PhpHttpGuzzle6' => 'php-http/guzzle6-adapter',
37+
'PhpHttpCurl' => 'php-http/curl-client',
38+
'PhpHttpReact' => 'php-http/react-adapter',
39+
],
40+
];
41+
42+
public static function initialize(): void
43+
{
44+
foreach (self::IMPLEMENTATIONS as $const => $packages) {
45+
if (\defined(__NAMESPACE__."\\{$const}_VENDOR")) {
46+
continue;
47+
}
48+
foreach ([false, true] as $includeDevRequirements) {
49+
foreach ($packages as $namespace => $versions) {
50+
foreach ((array) $versions as $package => $version) {
51+
if (\is_int($package)) {
52+
$package = $version;
53+
$version = null;
54+
}
55+
if (!InstalledVersions::isInstalled($package, $includeDevRequirements)) {
56+
continue 2;
57+
}
58+
if (null !== $version && version_compare($installed = InstalledVersions::getVersion($package) ?? $version, $version, '<') && 0 !== strpos($installed, 'dev-')) {
59+
continue 2;
60+
}
61+
}
62+
\define(__NAMESPACE__."\\{$const}_VENDOR", $namespace);
63+
continue 3;
64+
}
65+
}
66+
\define(__NAMESPACE__."\\{$const}_VENDOR", null);
67+
}
68+
}
6469
}
70+
71+
ConcreteImplementation::initialize();

0 commit comments

Comments
 (0)