@@ -45,13 +45,15 @@ class Plugin implements PluginInterface, EventSubscriberInterface
4545 */
4646 private const PROVIDE_RULES = [
4747 'php-http/async-client-implementation ' => [
48+ 'symfony/http-client:>=6.3 ' => ['guzzlehttp/promises ' , 'psr/http-factory-implementation ' ],
4849 'symfony/http-client ' => ['guzzlehttp/promises ' , 'php-http/message-factory ' , 'psr/http-factory-implementation ' ],
4950 'php-http/guzzle7-adapter ' => [],
5051 'php-http/guzzle6-adapter ' => [],
5152 'php-http/curl-client ' => [],
5253 'php-http/react-adapter ' => [],
5354 ],
5455 'php-http/client-implementation ' => [
56+ 'symfony/http-client:>=6.3 ' => ['psr/http-factory-implementation ' ],
5557 'symfony/http-client ' => ['php-http/message-factory ' , 'psr/http-factory-implementation ' ],
5658 'php-http/guzzle7-adapter ' => [],
5759 'php-http/guzzle6-adapter ' => [],
@@ -147,8 +149,18 @@ public function postUpdate(Event $event)
147149 $ composer ->getPackage ()->getRequires (),
148150 $ composer ->getPackage ()->getDevRequires (),
149151 ];
152+ $ pinnedAbstractions = [];
153+ $ pinned = $ composer ->getPackage ()->getExtra ()['discovery ' ] ?? [];
154+ foreach (self ::INTERFACE_MAP as $ abstraction => $ interfaces ) {
155+ foreach (isset ($ pinned [$ abstraction ]) ? [] : $ interfaces as $ interface ) {
156+ if (!isset ($ pinned [$ interface ])) {
157+ continue 2 ;
158+ }
159+ }
160+ $ pinnedAbstractions [$ abstraction ] = true ;
161+ }
150162
151- $ missingRequires = $ this ->getMissingRequires ($ repo , $ requires , 'project ' === $ composer ->getPackage ()->getType ());
163+ $ missingRequires = $ this ->getMissingRequires ($ repo , $ requires , 'project ' === $ composer ->getPackage ()->getType (), $ pinnedAbstractions );
152164 $ missingRequires = [
153165 'require ' => array_fill_keys (array_merge ([], ...array_values ($ missingRequires [0 ])), '* ' ),
154166 'require-dev ' => array_fill_keys (array_merge ([], ...array_values ($ missingRequires [1 ])), '* ' ),
@@ -227,7 +239,7 @@ public function postUpdate(Event $event)
227239 }
228240 }
229241
230- public function getMissingRequires (InstalledRepositoryInterface $ repo , array $ requires , bool $ isProject ): array
242+ public function getMissingRequires (InstalledRepositoryInterface $ repo , array $ requires , bool $ isProject, array $ pinnedAbstractions ): array
231243 {
232244 $ allPackages = [];
233245 $ devPackages = method_exists ($ repo , 'getDevPackageNames ' ) ? array_fill_keys ($ repo ->getDevPackageNames (), true ) : [];
@@ -267,7 +279,14 @@ public function getMissingRequires(InstalledRepositoryInterface $repo, array $re
267279 $ rules = array_intersect_key (self ::PROVIDE_RULES , $ rules );
268280
269281 while ($ rules ) {
270- $ abstractions [] = $ abstraction = key ($ rules );
282+ $ abstraction = key ($ rules );
283+
284+ if (isset ($ pinnedAbstractions [$ abstraction ])) {
285+ unset($ rules [$ abstraction ]);
286+ continue ;
287+ }
288+
289+ $ abstractions [] = $ abstraction ;
271290
272291 foreach (array_shift ($ rules ) as $ candidate => $ deps ) {
273292 [$ candidate , $ version ] = explode (': ' , $ candidate , 2 ) + [1 => null ];
@@ -332,22 +351,12 @@ public function getMissingRequires(InstalledRepositoryInterface $repo, array $re
332351 }
333352
334353 $ dep = key ($ candidates );
354+ [$ dep ] = explode (': ' , $ dep , 2 );
335355 $ missingRequires [$ dev ][$ abstraction ] = [$ dep ];
336356
337357 if ($ isProject && !$ dev && isset ($ devPackages [$ dep ])) {
338358 $ missingRequires [2 ][$ abstraction ][] = $ dep ;
339359 }
340-
341- foreach (current ($ candidates ) as $ dep ) {
342- if (isset (self ::PROVIDE_RULES [$ dep ])) {
343- $ abstractions [] = $ dep ;
344- } elseif (!isset ($ allPackages [$ dep ])) {
345- $ missingRequires [$ dev ][$ abstraction ][] = $ dep ;
346- } elseif ($ isProject && !$ dev && isset ($ devPackages [$ dep ])) {
347- $ missingRequires [0 ][$ abstraction ][] = $ dep ;
348- $ missingRequires [2 ][$ abstraction ][] = $ dep ;
349- }
350- }
351360 }
352361 }
353362
0 commit comments