24
24
use Composer \Installer ;
25
25
use Composer \Installer \InstallerEvent ;
26
26
use Composer \Installer \InstallerEvents ;
27
- use Composer \Installer \NoopInstaller ;
28
27
use Composer \Installer \PackageEvent ;
29
28
use Composer \Installer \PackageEvents ;
30
29
use Composer \Installer \SuggestedPackagesReporter ;
@@ -71,6 +70,10 @@ class Flex implements PluginInterface, EventSubscriberInterface
71
70
private $ options ;
72
71
private $ configurator ;
73
72
private $ downloader ;
73
+
74
+ /**
75
+ * @var Installer
76
+ */
74
77
private $ installer ;
75
78
private $ postInstallOutput = ['' ];
76
79
private $ operations = [];
@@ -293,8 +296,7 @@ public function configureInstaller()
293
296
$ backtrace = debug_backtrace ();
294
297
foreach ($ backtrace as $ trace ) {
295
298
if (isset ($ trace ['object ' ]) && $ trace ['object ' ] instanceof Installer) {
296
- $ this ->installer = \Closure::bind (function () { return $ this ->update ? $ this : null ; }, $ trace ['object ' ], $ trace ['object ' ])();
297
- $ trace ['object ' ]->setSuggestedPackagesReporter (new SuggestedPackagesReporter (new NullIO ()));
299
+ $ this ->installer = $ trace ['object ' ]->setSuggestedPackagesReporter (new SuggestedPackagesReporter (new NullIO ()));
298
300
}
299
301
300
302
if (isset ($ trace ['object ' ]) && $ trace ['object ' ] instanceof GlobalCommand) {
@@ -328,33 +330,21 @@ public function configureProject(Event $event)
328
330
@unlink ('LICENSE ' );
329
331
330
332
// Update composer.json (project is proprietary by default)
331
- $ json = new JsonFile ( Factory::getComposerFile () );
332
- $ contents = file_get_contents ($ json -> getPath () );
333
+ $ file = Factory::getComposerFile ();
334
+ $ contents = file_get_contents ($ file );
333
335
$ manipulator = new JsonManipulator ($ contents );
336
+ $ json = JsonFile::parseJson ($ contents );
334
337
335
338
// new projects are most of the time proprietary
336
339
$ manipulator ->addMainKey ('license ' , 'proprietary ' );
337
340
338
341
// extra.branch-alias doesn't apply to the project
339
342
$ manipulator ->removeSubNode ('extra ' , 'branch-alias ' );
340
343
341
- // replace unbounded constraints for symfony/* packages by extra.symfony.require
342
- $ config = json_decode ($ contents , true );
343
- if ($ symfonyVersion = $ config ['extra ' ]['symfony ' ]['require ' ] ?? null ) {
344
- $ versions = $ this ->downloader ->getVersions ();
345
- foreach (['require ' , 'require-dev ' ] as $ type ) {
346
- foreach ($ config [$ type ] ?? [] as $ package => $ version ) {
347
- if ('* ' === $ version && isset ($ versions ['splits ' ][$ package ])) {
348
- $ manipulator ->addLink ($ type , $ package , $ symfonyVersion );
349
- }
350
- }
351
- }
352
- }
353
-
354
344
// 'name' and 'description' are only required for public packages
355
345
// don't use $manipulator->removeProperty() for BC with Composer 1.0
356
346
$ contents = preg_replace (['{^\s*+"name":.*,$\n}m ' , '{^\s*+"description":.*,$\n}m ' ], '' , $ manipulator ->getContents (), 1 );
357
- file_put_contents ($ json -> getPath () , $ contents );
347
+ file_put_contents ($ file , $ contents );
358
348
359
349
$ this ->updateComposerLock ();
360
350
}
@@ -366,106 +356,49 @@ public function record(PackageEvent $event)
366
356
}
367
357
}
368
358
369
- public function checkForUpdate (PackageEvent $ event )
370
- {
371
- if (null === $ this ->installer || $ this ->cacheDirPopulated || 'symfony/flex ' !== $ event ->getOperation ()->getPackage ()->getName ()) {
372
- return ;
373
- }
374
-
375
- $ this ->update ();
376
- $ this ->cacheDirPopulated = true ;
377
- $ this ->composer ->getInstallationManager ()->addInstaller (new NoopInstaller ());
378
-
379
- \Closure::bind (function () {
380
- $ this ->io = new NullIO ();
381
- $ this ->writeLock = false ;
382
- $ this ->executeOperations = false ;
383
- $ this ->dumpAutoloader = false ;
384
- $ this ->runScripts = false ;
385
- }, $ this ->installer , $ this ->installer )();
386
- }
387
-
388
- public function update (Event $ event = null , $ operations = [])
359
+ public function update (Event $ event , $ operations = [])
389
360
{
390
361
if ($ operations ) {
391
362
$ this ->operations = $ operations ;
392
363
}
393
364
394
365
$ this ->install ($ event );
395
366
396
- $ jsonPath = Factory::getComposerFile ();
397
- $ json = file_get_contents ($ jsonPath );
398
- $ manipulator = new JsonManipulator ($ json );
399
- $ json = json_decode ($ json , true );
367
+ $ file = Factory::getComposerFile ();
368
+ $ contents = file_get_contents ($ file );
369
+ $ json = JsonFile::parseJson ($ contents );
370
+
371
+ if (!isset ($ json ['flex-require ' ]) && !isset ($ json ['flex-require ' ])) {
372
+ $ this ->unpack ($ event );
400
373
401
- if (null === $ event ) {
402
- // called from checkForUpdate()
403
- } elseif (null === $ this ->installer || (!isset ($ json ['flex-require ' ]) && !isset ($ json ['flex-require-dev ' ]))) {
404
374
return ;
405
- } else {
406
- $ event ->stopPropagation ();
407
375
}
408
376
377
+ // merge "flex-require" with "require"
378
+ $ manipulator = new JsonManipulator ($ contents );
409
379
$ sortPackages = $ this ->composer ->getConfig ()->get ('sort-packages ' );
410
- $ unpackOp = new Operation ( true , $ sortPackages ) ;
411
-
380
+ $ symfonyVersion = $ json [ ' extra ' ][ ' symfony ' ][ ' require ' ] ?? null ;
381
+ $ versions = $ symfonyVersion ? $ this -> downloader -> getVersions () : null ;
412
382
foreach (['require ' , 'require-dev ' ] as $ type ) {
413
383
if (isset ($ json ['flex- ' .$ type ])) {
414
384
foreach ($ json ['flex- ' .$ type ] as $ package => $ constraint ) {
415
- $ unpackOp ->addPackage ($ package , $ constraint , 'require-dev ' === $ type );
385
+ if ($ symfonyVersion && '* ' === $ constraint && isset ($ versions ['splits ' ][$ package ])) {
386
+ // replace unbounded constraints for symfony/* packages by extra.symfony.require
387
+ $ constraint = $ symfonyVersion ;
388
+ }
416
389
$ manipulator ->addLink ($ type , $ package , $ constraint , $ sortPackages );
417
390
}
418
391
419
392
$ manipulator ->removeMainKey ('flex- ' .$ type );
420
393
}
421
394
}
422
395
423
- file_put_contents ($ jsonPath , $ manipulator ->getContents ());
424
-
425
- $ this ->cacheDirPopulated = false ;
426
- $ rm = $ this ->composer ->getRepositoryManager ();
427
- $ package = Factory::create ($ this ->io )->getPackage ();
428
- $ this ->composer ->setPackage ($ package );
429
- \Closure::bind (function () use ($ package , $ rm ) {
430
- $ this ->package = $ package ;
431
- $ this ->repositoryManager = $ rm ;
432
- }, $ this ->installer , $ this ->installer )();
433
- $ this ->composer ->getEventDispatcher ()->__construct ($ this ->composer , $ this ->io );
434
-
435
- $ status = $ this ->installer ->run ();
436
- if (0 !== $ status ) {
437
- exit ($ status );
438
- }
439
-
440
- $ unpacker = new Unpacker ($ this ->composer , new PackageResolver ($ this ->downloader ), $ this ->dryRun );
441
- $ result = $ unpacker ->unpack ($ unpackOp );
442
- $ unpacker ->updateLock ($ result , $ this ->io );
443
-
444
- $ io = new NullIO ();
445
- $ composer = Factory::create ($ io , null , true );
446
- $ installer = Installer::create ($ io , $ composer );
447
- $ installer
448
- ->setDevMode ($ this ->dryRun )
449
- ->setDumpAutoloader (false )
450
- ->setIgnorePlatformRequirements (true )
451
- ->setUpdate (true )
452
- ->setUpdateAllowList (['php ' ])
453
- ;
454
-
455
- if (method_exists ($ composer ->getEventDispatcher (), 'setRunScripts ' )) {
456
- $ composer ->getEventDispatcher ()->setRunScripts (false );
457
- } else {
458
- $ installer ->setRunScripts (false );
459
- }
460
-
461
- if (method_exists ($ installer , 'setSkipSuggest ' )) {
462
- $ installer ->setSkipSuggest (true );
463
- }
396
+ file_put_contents ($ file , $ manipulator ->getContents ());
464
397
465
- $ installer -> run ( );
398
+ $ this -> reinstall ( $ event , true );
466
399
}
467
400
468
- public function install (Event $ event = null )
401
+ public function install (Event $ event )
469
402
{
470
403
$ rootDir = $ this ->options ->get ('root-dir ' );
471
404
@@ -813,7 +746,7 @@ public function fetchRecipes(array $operations): array
813
746
];
814
747
$ packRecipes = [];
815
748
816
- foreach ($ operations as $ i => $ operation ) {
749
+ foreach ($ operations as $ operation ) {
817
750
if ($ operation instanceof UpdateOperation) {
818
751
$ package = $ operation ->getTargetPackage ();
819
752
} else {
@@ -992,14 +925,73 @@ private function updateComposerLock()
992
925
$ lockFile ->write ($ lockData );
993
926
}
994
927
928
+ private function unpack (Event $ event )
929
+ {
930
+ $ jsonPath = Factory::getComposerFile ();
931
+ $ json = JsonFile::parseJson (file_get_contents ($ jsonPath ));
932
+ $ sortPackages = $ this ->composer ->getConfig ()->get ('sort-packages ' );
933
+ $ unpackOp = new Operation (true , $ sortPackages );
934
+
935
+ foreach (['require ' , 'require-dev ' ] as $ type ) {
936
+ foreach ($ json [$ type ] ?? [] as $ package => $ constraint ) {
937
+ $ unpackOp ->addPackage ($ package , $ constraint , 'require-dev ' === $ type );
938
+ }
939
+ }
940
+
941
+ $ unpacker = new Unpacker ($ this ->composer , new PackageResolver ($ this ->downloader ), $ this ->dryRun );
942
+ $ result = $ unpacker ->unpack ($ unpackOp );
943
+
944
+ if (!$ result ->getUnpacked ()) {
945
+ return ;
946
+ }
947
+
948
+ $ this ->io ->writeError ('<info>Unpacking Symfony packs</> ' );
949
+ foreach ($ result ->getUnpacked () as $ pkg ) {
950
+ $ this ->io ->writeError (sprintf (' - Unpacked <info>%s</> ' , $ pkg ->getName ()));
951
+ }
952
+
953
+ $ unpacker ->updateLock ($ result , $ this ->io );
954
+
955
+ $ this ->reinstall ($ event , false );
956
+ }
957
+
958
+ private function reinstall (Event $ event , bool $ update )
959
+ {
960
+ $ event ->stopPropagation ();
961
+ $ composer = Factory::create ($ this ->io );
962
+
963
+ $ installer = clone $ this ->installer ;
964
+ $ installer ->__construct (
965
+ $ this ->io ,
966
+ $ composer ->getConfig (),
967
+ $ composer ->getPackage (),
968
+ $ composer ->getDownloadManager (),
969
+ $ composer ->getRepositoryManager (),
970
+ $ composer ->getLocker (),
971
+ $ composer ->getInstallationManager (),
972
+ $ composer ->getEventDispatcher (),
973
+ $ composer ->getAutoloadGenerator ()
974
+ );
975
+
976
+ if (!$ update ) {
977
+ $ installer ->setUpdateAllowList (['php ' ]);
978
+ }
979
+
980
+ if (method_exists ($ installer , 'setSkipSuggest ' )) {
981
+ $ installer ->setSkipSuggest (true );
982
+ }
983
+
984
+ $ installer ->run ();
985
+ }
986
+
995
987
public static function getSubscribedEvents (): array
996
988
{
997
989
if (!self ::$ activated ) {
998
990
return [];
999
991
}
1000
992
1001
993
$ events = [
1002
- PackageEvents::POST_PACKAGE_INSTALL => __CLASS__ === self ::class ? [[ ' record ' ], [ ' checkForUpdate ' ]] : 'record ' ,
994
+ PackageEvents::POST_PACKAGE_INSTALL => 'record ' ,
1003
995
PackageEvents::POST_PACKAGE_UPDATE => [['record ' ], ['enableThanksReminder ' ]],
1004
996
PackageEvents::POST_PACKAGE_UNINSTALL => 'record ' ,
1005
997
ScriptEvents::POST_CREATE_PROJECT_CMD => 'configureProject ' ,
0 commit comments