12
12
namespace Symfony \Flex \Command ;
13
13
14
14
use Composer \Command \RequireCommand as BaseRequireCommand ;
15
+ use Composer \DependencyResolver \Pool ;
16
+ use Composer \Factory ;
17
+ use Composer \Json \JsonFile ;
18
+ use Composer \Json \JsonManipulator ;
19
+ use Composer \Package \Link ;
20
+ use Composer \Package \Package ;
21
+ use Composer \Package \Version \VersionParser ;
15
22
use Symfony \Component \Console \Input \InputInterface ;
23
+ use Symfony \Component \Console \Input \InputOption ;
16
24
use Symfony \Component \Console \Output \OutputInterface ;
17
25
use Symfony \Flex \PackageResolver ;
18
26
19
27
class RequireCommand extends BaseRequireCommand
20
28
{
21
29
private $ resolver ;
30
+ private $ composer ;
31
+ private $ manipulator ;
22
32
23
33
public function __construct (PackageResolver $ resolver )
24
34
{
@@ -27,14 +37,81 @@ public function __construct(PackageResolver $resolver)
27
37
parent ::__construct ();
28
38
}
29
39
40
+ protected function configure ()
41
+ {
42
+ parent ::configure ();
43
+ $ this ->addOption ('unpack ' , null , InputOption::VALUE_NONE , 'Unpack Symfony packs in composer.json. ' );
44
+ }
45
+
30
46
protected function execute (InputInterface $ input , OutputInterface $ output )
31
47
{
32
- $ input ->setArgument ('packages ' , $ this ->resolver ->resolve ($ input ->getArgument ('packages ' ), true ));
48
+ $ packages = $ this ->resolver ->resolve ($ input ->getArgument ('packages ' ), true );
49
+ $ packages = $ this ->unpack ($ packages , $ input ->getOption ('unpack ' ), $ input ->getOption ('sort-packages ' ), $ input ->getOption ('dev ' ));
50
+ if (!$ packages ) {
51
+ // we need at least one package for the command to work properly
52
+ $ packages = ['symfony/flex ' ];
53
+ }
54
+
55
+ $ input ->setArgument ('packages ' , $ packages );
33
56
34
57
if ($ input ->hasOption ('no-suggest ' )) {
35
58
$ input ->setOption ('no-suggest ' , true );
36
59
}
37
60
38
61
return parent ::execute ($ input , $ output );
39
62
}
63
+
64
+ private function unpack (array $ packages , bool $ unpack , bool $ sortPackages , bool $ dev ): array
65
+ {
66
+ $ versionParser = new VersionParser ();
67
+ $ this ->composer = $ this ->getComposer ();
68
+ $ json = new JsonFile (Factory::getComposerFile ());
69
+ $ this ->manipulator = new JsonManipulator (file_get_contents ($ json ->getPath ()));
70
+ $ sortPackages = $ sortPackages || $ this ->composer ->getConfig ()->get ('sort-packages ' );
71
+ $ pkgs = [];
72
+
73
+ foreach ($ versionParser ->parseNameVersionPairs ($ packages ) as $ package ) {
74
+ if (!$ this ->addDep ($ package ['name ' ], $ package ['version ' ] ?? '* ' , $ unpack , $ sortPackages , $ dev )) {
75
+ $ pkgs [] = $ package ['name ' ].(isset ($ package ['version ' ]) ? ': ' .$ package ['version ' ] : '' );
76
+ }
77
+ }
78
+
79
+ file_put_contents ($ json ->getPath (), $ this ->manipulator ->getContents ());
80
+
81
+ return $ pkgs ;
82
+ }
83
+
84
+ private function addDep (string $ name , string $ version , bool $ unpack , bool $ sortPackages , bool $ dev )
85
+ {
86
+ $ pkg = $ this ->composer ->getRepositoryManager ()->findPackage ($ name , $ version ?? '* ' );
87
+ if ('symfony-profile ' !== $ pkg ->getType () && ($ pkg ->getType () !== 'symfony-pack ' || !$ unpack )) {
88
+ return false ;
89
+ }
90
+ if (0 === count ($ pkg ->getRequires ()) + count ($ pkg ->getDevRequires ())) {
91
+ // don't unpack empty packs, they are markers we need to keep
92
+ return false ;
93
+ }
94
+
95
+ foreach ($ pkg ->getRequires () as $ link ) {
96
+ if ('php ' === $ link ->getTarget ()) {
97
+ continue ;
98
+ }
99
+ if (!$ this ->addDep ($ link ->getTarget (), '* ' , true , $ sortPackages , $ dev )) {
100
+ if (!$ this ->manipulator ->addLink ($ dev ? 'require-dev ' : 'require ' , $ link ->getTarget (), $ link ->getPrettyConstraint (), $ sortPackages )) {
101
+ throw new \RuntimeException (sprintf ('Unable to unpack package "%s". ' , $ link ->getTarget ()));
102
+ }
103
+ }
104
+ }
105
+ if ('symfony-profile ' === $ pkg ->getType ()) {
106
+ foreach ($ pkg ->getDevRequires () as $ link ) {
107
+ if (!$ this ->addDep ($ link ->getTarget (), '* ' , true , $ sortPackages , true )) {
108
+ if (!$ this ->manipulator ->addLink ('require-dev ' , $ link ->getTarget (), $ link ->getPrettyConstraint (), $ sortPackages )) {
109
+ throw new \RuntimeException (sprintf ('Unable to unpack package "%s". ' , $ link ->getTarget ()));
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return true ;
116
+ }
40
117
}
0 commit comments