11
11
use BlameButton \LaravelDockerBuilder \Detector \NodePackageManagerDetector ;
12
12
use BlameButton \LaravelDockerBuilder \Detector \PhpExtensionsDetector ;
13
13
use BlameButton \LaravelDockerBuilder \Detector \PhpVersionDetector ;
14
+ use BlameButton \LaravelDockerBuilder \Exceptions \InvalidOptionValueException ;
14
15
use BlameButton \LaravelDockerBuilder \Traits \InteractsWithTwig ;
15
- use Illuminate \Support \Collection ;
16
16
use Symfony \Component \Console \Input \InputOption ;
17
17
18
18
class DockerGenerateCommand extends BaseCommand
@@ -25,63 +25,77 @@ class DockerGenerateCommand extends BaseCommand
25
25
26
26
public function handle (): int
27
27
{
28
- $ phpVersion = $ this ->getPhpVersion ();
29
- $ phpExtensions = $ this ->getPhpExtensions ($ phpVersion );
30
- $ artisanOptimize = $ this ->getArtisanOptimize ();
31
- $ nodePackageManager = $ this ->getNodePackageManager ();
32
- $ nodeBuildTool = $ nodePackageManager ? $ this ->getNodeBuildTool () : false ;
33
-
34
- if ($ this ->option ('detect ' )) {
35
- $ this ->info ('Detected Configuration ' );
28
+ try {
29
+ $ phpVersion = $ this ->getPhpVersion ();
30
+ $ phpExtensions = $ this ->getPhpExtensions ($ phpVersion );
31
+ $ artisanOptimize = $ this ->getArtisanOptimize ();
32
+ $ nodePackageManager = $ this ->getNodePackageManager ();
33
+ $ nodeBuildTool = $ nodePackageManager ? $ this ->getNodeBuildTool () : false ;
34
+ } catch (InvalidOptionValueException $ exception ) {
35
+ $ this ->error ($ exception ->getMessage ());
36
+
37
+ return self ::INVALID ;
36
38
}
37
39
40
+ $ this ->info ('Configuration: ' );
38
41
$ this ->table (['Key ' , 'Value ' ], [
39
42
['PHP version ' , "<comment> $ phpVersion</comment> " ],
40
43
['PHP extensions ' , implode (', ' , $ phpExtensions )],
41
44
['Artisan Optimize ' , '<comment> ' .json_encode ($ artisanOptimize ).'</comment> ' ],
42
45
['Node Package Manager ' , NodePackageManager::name ($ nodePackageManager )],
43
46
['Node Build Tool ' , $ nodePackageManager ? NodeBuildTool::name ($ nodeBuildTool ) : 'None ' ],
44
47
]);
48
+ $ this ->newLine ();
45
49
46
- $ dockerfiles = collect ([
47
- 'php.dockerfile ' => $ this ->render ('php.dockerfile.twig ' , [
48
- 'php_version ' => $ phpVersion ,
49
- 'php_extensions ' => $ phpExtensions ,
50
- 'artisan_optimize ' => $ artisanOptimize ,
51
- 'node_package_manager ' => $ nodePackageManager ,
52
- 'node_build_tool ' => $ nodeBuildTool ,
53
- ]),
54
- 'nginx.dockerfile ' => $ this ->render ('nginx.dockerfile.twig ' , [
55
- 'node_package_manager ' => $ nodePackageManager ,
56
- 'node_build_tool ' => $ nodeBuildTool ,
57
- ]),
58
- ]);
50
+ if (! $ this ->option ('no-interaction ' ) && ! $ this ->confirm ('Does this look correct? ' , true )) {
51
+ $ this ->comment ('Exiting. ' );
59
52
60
- if (! is_dir ($ dir = base_path ('.docker ' ))) {
61
- mkdir ($ dir );
53
+ return self ::SUCCESS ;
62
54
}
63
55
64
- foreach ($ dockerfiles as $ file => $ content ) {
65
- // Example: $PWD/.docker/{php,nginx}.dockerfile
66
- $ dockerfile = sprintf ('%s/%s ' , $ dir , $ file );
56
+ $ context = [
57
+ 'php_version ' => $ phpVersion ,
58
+ 'php_extensions ' => $ phpExtensions ,
59
+ 'artisan_optimize ' => $ artisanOptimize ,
60
+ 'node_package_manager ' => $ nodePackageManager ,
61
+ 'node_build_tool ' => $ nodeBuildTool ,
62
+ ];
67
63
68
- // Save Dockerfile contents
69
- file_put_contents ($ dockerfile , $ content );
64
+ $ this ->saveDockerfiles ($ context );
65
+ $ this ->newLine ();
66
+
67
+ $ command = array_filter ([
68
+ 'php ' ,
69
+ 'artisan ' ,
70
+ 'docker:generate ' ,
71
+ '-n ' , // --no-interaction
72
+ '-p ' .$ phpVersion , // --php-version
73
+ '-e ' .implode (', ' , $ phpExtensions ), // --php-extensions
74
+ $ artisanOptimize ? '-o ' : null , // --optimize
75
+ $ nodePackageManager ? '-m ' .$ nodePackageManager : null , // --node-package-manager
76
+ $ nodePackageManager ? '-b ' .$ nodeBuildTool : null , // --node-build-tool
77
+ ]);
70
78
71
- // Output saved Dockerfile location
72
- $ filename = str ($ dockerfile )->after (base_path ())->trim ('/ ' );
73
- $ this ->info (sprintf ('Saved: %s ' , $ filename ));
74
- }
79
+ $ this ->info ('Command to generate above configuration: ' );
80
+ $ this ->comment (sprintf (' %s ' , implode (' ' , $ command )));
75
81
76
82
return self ::SUCCESS ;
77
83
}
78
84
85
+ /**
86
+ * Get the PHP version, either by detecting it from the "composer.json",
87
+ * from the "php-version" option, or asking the user.
88
+ *
89
+ * @return string
90
+ *
91
+ * @throws InvalidOptionValueException when an unsupported PHP version is passed
92
+ */
79
93
private function getPhpVersion (): string
80
94
{
81
95
if ($ option = $ this ->option ('php-version ' )) {
82
96
return in_array ($ option , PhpVersion::values ())
83
97
? $ option
84
- : throw new \ InvalidArgumentException ("Invalid value [ $ option] for option [php-version] " );
98
+ : throw new InvalidOptionValueException ("Invalid value [ $ option] for option [php-version] " );
85
99
}
86
100
87
101
$ detected = app (PhpVersionDetector::class)->detect ();
@@ -97,14 +111,31 @@ private function getPhpVersion(): string
97
111
);
98
112
}
99
113
114
+ /**
115
+ * Get the PHP extensions, either by detecting them from the application's configuration,
116
+ * from the "php-extensions" option, or asking the user.
117
+ *
118
+ * @param string $phpVersion
119
+ * @return array
120
+ *
121
+ * @throws InvalidOptionValueException when an unsupported extension is passed
122
+ */
100
123
private function getPhpExtensions (string $ phpVersion ): array
101
124
{
102
125
$ supportedExtensions = PhpExtensions::values ($ phpVersion );
103
126
104
127
if ($ option = $ this ->option ('php-extensions ' )) {
105
- return Collection::make (explode (', ' , $ option ))
106
- ->intersect ($ supportedExtensions )
107
- ->toArray ();
128
+ $ extensions = explode (', ' , $ option );
129
+
130
+ foreach ($ extensions as $ extension ) {
131
+ if (in_array ($ extension , $ supportedExtensions )) {
132
+ continue ;
133
+ }
134
+
135
+ throw new InvalidOptionValueException ("Extension [ $ extension] is not supported. " );
136
+ }
137
+
138
+ return array_intersect ($ extensions , $ supportedExtensions );
108
139
}
109
140
110
141
$ detected = app (PhpExtensionsDetector::class, ['supportedExtensions ' => $ supportedExtensions ])->detect ();
@@ -142,12 +173,20 @@ public function getArtisanOptimize(): bool
142
173
return ArtisanOptimize::YES === $ choice ;
143
174
}
144
175
176
+ /**
177
+ * Get the Node Package Manager, either by detecting it from files present (package-lock.json, yarn.lock),
178
+ * from the "node-package-manager" option, or asking the user.
179
+ *
180
+ * @return string|false
181
+ *
182
+ * @throws InvalidOptionValueException
183
+ */
145
184
private function getNodePackageManager (): string |false
146
185
{
147
186
if ($ option = $ this ->option ('node-package-manager ' )) {
148
187
return in_array ($ option , NodePackageManager::values ())
149
188
? $ option
150
- : throw new \ InvalidArgumentException ("Invalid value [ $ option] for option [node-package-manager] " );
189
+ : throw new InvalidOptionValueException ("Invalid value [ $ option] for option [node-package-manager] " );
151
190
}
152
191
153
192
$ detected = app (NodePackageManagerDetector::class)->detect ();
@@ -163,12 +202,20 @@ private function getNodePackageManager(): string|false
163
202
);
164
203
}
165
204
205
+ /**
206
+ * Get the Node Build Tool, either by detecting it from files present (vite.config.js, webpack.mix.js),
207
+ * from the "node-build-tool" option, or asking the user.
208
+ *
209
+ * @return string
210
+ *
211
+ * @throws InvalidOptionValueException
212
+ */
166
213
private function getNodeBuildTool (): string
167
214
{
168
215
if ($ option = $ this ->option ('node-build-tool ' )) {
169
216
return in_array ($ option , NodeBuildTool::values ())
170
217
? $ option
171
- : throw new \ InvalidArgumentException ("Invalid value [ $ option] for option [node-build-tool] " );
218
+ : throw new InvalidOptionValueException ("Invalid value [ $ option] for option [node-build-tool] " );
172
219
}
173
220
174
221
$ detected = app (NodeBuildToolDetector::class)->detect ();
@@ -184,6 +231,32 @@ private function getNodeBuildTool(): string
184
231
);
185
232
}
186
233
234
+ private function saveDockerfiles (array $ context ): void
235
+ {
236
+ if (! is_dir ($ dir = base_path ('.docker ' ))) {
237
+ mkdir ($ dir );
238
+ }
239
+
240
+ $ this ->info ('Saving Dockerfiles: ' );
241
+
242
+ $ dockerfiles = [
243
+ 'php.dockerfile ' => $ this ->render ('php.dockerfile.twig ' , $ context ),
244
+ 'nginx.dockerfile ' => $ this ->render ('nginx.dockerfile.twig ' , $ context ),
245
+ ];
246
+
247
+ foreach ($ dockerfiles as $ file => $ content ) {
248
+ // Example: $PWD/.docker/{php,nginx}.dockerfile
249
+ $ dockerfile = sprintf ('%s/%s ' , $ dir , $ file );
250
+
251
+ // Save Dockerfile contents
252
+ file_put_contents ($ dockerfile , $ content );
253
+
254
+ // Output saved Dockerfile location
255
+ $ filename = str ($ dockerfile )->after (base_path ())->trim ('/ ' );
256
+ $ this ->comment (sprintf (' Saved: %s ' , $ filename ));
257
+ }
258
+ }
259
+
187
260
protected function getOptions (): array
188
261
{
189
262
return [
0 commit comments