Skip to content

Commit 2cf6409

Browse files
committed
Add InvalidOptionValueException.php
1 parent bcfa8cd commit 2cf6409

File tree

2 files changed

+121
-39
lines changed

2 files changed

+121
-39
lines changed

src/Commands/DockerGenerateCommand.php

Lines changed: 112 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
use BlameButton\LaravelDockerBuilder\Detector\NodePackageManagerDetector;
1212
use BlameButton\LaravelDockerBuilder\Detector\PhpExtensionsDetector;
1313
use BlameButton\LaravelDockerBuilder\Detector\PhpVersionDetector;
14+
use BlameButton\LaravelDockerBuilder\Exceptions\InvalidOptionValueException;
1415
use BlameButton\LaravelDockerBuilder\Traits\InteractsWithTwig;
15-
use Illuminate\Support\Collection;
1616
use Symfony\Component\Console\Input\InputOption;
1717

1818
class DockerGenerateCommand extends BaseCommand
@@ -25,63 +25,77 @@ class DockerGenerateCommand extends BaseCommand
2525

2626
public function handle(): int
2727
{
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;
3638
}
3739

40+
$this->info('Configuration:');
3841
$this->table(['Key', 'Value'], [
3942
['PHP version', "<comment>$phpVersion</comment>"],
4043
['PHP extensions', implode(', ', $phpExtensions)],
4144
['Artisan Optimize', '<comment>'.json_encode($artisanOptimize).'</comment>'],
4245
['Node Package Manager', NodePackageManager::name($nodePackageManager)],
4346
['Node Build Tool', $nodePackageManager ? NodeBuildTool::name($nodeBuildTool) : 'None'],
4447
]);
48+
$this->newLine();
4549

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.');
5952

60-
if (! is_dir($dir = base_path('.docker'))) {
61-
mkdir($dir);
53+
return self::SUCCESS;
6254
}
6355

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+
];
6763

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+
]);
7078

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)));
7581

7682
return self::SUCCESS;
7783
}
7884

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+
*/
7993
private function getPhpVersion(): string
8094
{
8195
if ($option = $this->option('php-version')) {
8296
return in_array($option, PhpVersion::values())
8397
? $option
84-
: throw new \InvalidArgumentException("Invalid value [$option] for option [php-version]");
98+
: throw new InvalidOptionValueException("Invalid value [$option] for option [php-version]");
8599
}
86100

87101
$detected = app(PhpVersionDetector::class)->detect();
@@ -97,14 +111,31 @@ private function getPhpVersion(): string
97111
);
98112
}
99113

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+
*/
100123
private function getPhpExtensions(string $phpVersion): array
101124
{
102125
$supportedExtensions = PhpExtensions::values($phpVersion);
103126

104127
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);
108139
}
109140

110141
$detected = app(PhpExtensionsDetector::class, ['supportedExtensions' => $supportedExtensions])->detect();
@@ -142,12 +173,20 @@ public function getArtisanOptimize(): bool
142173
return ArtisanOptimize::YES === $choice;
143174
}
144175

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+
*/
145184
private function getNodePackageManager(): string|false
146185
{
147186
if ($option = $this->option('node-package-manager')) {
148187
return in_array($option, NodePackageManager::values())
149188
? $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]");
151190
}
152191

153192
$detected = app(NodePackageManagerDetector::class)->detect();
@@ -163,12 +202,20 @@ private function getNodePackageManager(): string|false
163202
);
164203
}
165204

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+
*/
166213
private function getNodeBuildTool(): string
167214
{
168215
if ($option = $this->option('node-build-tool')) {
169216
return in_array($option, NodeBuildTool::values())
170217
? $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]");
172219
}
173220

174221
$detected = app(NodeBuildToolDetector::class)->detect();
@@ -184,6 +231,32 @@ private function getNodeBuildTool(): string
184231
);
185232
}
186233

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+
187260
protected function getOptions(): array
188261
{
189262
return [
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace BlameButton\LaravelDockerBuilder\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidOptionValueException extends Exception
8+
{
9+
}

0 commit comments

Comments
 (0)