Skip to content

Commit 904454a

Browse files
committed
Extract questions to separate file
1 parent 2cf6409 commit 904454a

17 files changed

+254
-182
lines changed

docker/template/php.dockerfile.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ WORKDIR /app
1717

1818
# install required extensions
1919
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
20-
RUN install-php-extensions {{ php_extensions|join(' ') }}
20+
RUN install-php-extensions {{ php_extensions }}
2121

2222
# copy application source code
2323
COPY / /app

src/Commands/BaseCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ abstract class BaseCommand extends Command
88
{
99
private const NONE = 'none';
1010

11-
protected function optionalChoice(string $question, array $choices, $default = null): string|false
11+
public function optionalChoice(string $question, array $choices, $default = null): string|false
1212
{
1313
$choice = $this->choice(
1414
question: $question,

src/Commands/DockerGenerateCommand.php

Lines changed: 31 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
namespace BlameButton\LaravelDockerBuilder\Commands;
44

5-
use BlameButton\LaravelDockerBuilder\Commands\Choices\ArtisanOptimize;
6-
use BlameButton\LaravelDockerBuilder\Commands\Choices\NodeBuildTool;
7-
use BlameButton\LaravelDockerBuilder\Commands\Choices\NodePackageManager;
8-
use BlameButton\LaravelDockerBuilder\Commands\Choices\PhpExtensions;
9-
use BlameButton\LaravelDockerBuilder\Commands\Choices\PhpVersion;
10-
use BlameButton\LaravelDockerBuilder\Detector\NodeBuildToolDetector;
11-
use BlameButton\LaravelDockerBuilder\Detector\NodePackageManagerDetector;
12-
use BlameButton\LaravelDockerBuilder\Detector\PhpExtensionsDetector;
13-
use BlameButton\LaravelDockerBuilder\Detector\PhpVersionDetector;
5+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\ArtisanOptimizeQuestion;
6+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\NodeBuildTool;
7+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\NodePackageManager;
8+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\PhpExtensions;
9+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\PhpVersion;
10+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\NodeBuildToolQuestion;
11+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\NodePackageManagerQuestion;
12+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\PhpExtensionsQuestion;
13+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\PhpVersionQuestion;
1414
use BlameButton\LaravelDockerBuilder\Exceptions\InvalidOptionValueException;
1515
use BlameButton\LaravelDockerBuilder\Traits\InteractsWithTwig;
1616
use Symfony\Component\Console\Input\InputOption;
@@ -26,11 +26,11 @@ class DockerGenerateCommand extends BaseCommand
2626
public function handle(): int
2727
{
2828
try {
29-
$phpVersion = $this->getPhpVersion();
30-
$phpExtensions = $this->getPhpExtensions($phpVersion);
31-
$artisanOptimize = $this->getArtisanOptimize();
32-
$nodePackageManager = $this->getNodePackageManager();
33-
$nodeBuildTool = $nodePackageManager ? $this->getNodeBuildTool() : false;
29+
$phpVersion = app(PhpVersionQuestion::class)->getAnswer($this);
30+
$phpExtensions = app(PhpExtensionsQuestion::class)->getAnswer($this, $phpVersion);
31+
$artisanOptimize = app(ArtisanOptimizeQuestion::class)->getAnswer($this);
32+
$nodePackageManager = app(NodePackageManagerQuestion::class)->getAnswer($this);
33+
$nodeBuildTool = $nodePackageManager ? app(NodeBuildToolQuestion::class)->getAnswer($this) : false;
3434
} catch (InvalidOptionValueException $exception) {
3535
$this->error($exception->getMessage());
3636

@@ -53,21 +53,17 @@ public function handle(): int
5353
return self::SUCCESS;
5454
}
5555

56-
$context = [
56+
$this->saveDockerfiles([
5757
'php_version' => $phpVersion,
58-
'php_extensions' => $phpExtensions,
58+
'php_extensions' => implode(' ', $phpExtensions),
5959
'artisan_optimize' => $artisanOptimize,
6060
'node_package_manager' => $nodePackageManager,
6161
'node_build_tool' => $nodeBuildTool,
62-
];
63-
64-
$this->saveDockerfiles($context);
62+
]);
6563
$this->newLine();
6664

6765
$command = array_filter([
68-
'php',
69-
'artisan',
70-
'docker:generate',
66+
'php', 'artisan', 'docker:generate',
7167
'-n', // --no-interaction
7268
'-p '.$phpVersion, // --php-version
7369
'-e '.implode(',', $phpExtensions), // --php-extensions
@@ -82,155 +78,6 @@ public function handle(): int
8278
return self::SUCCESS;
8379
}
8480

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-
*/
93-
private function getPhpVersion(): string
94-
{
95-
if ($option = $this->option('php-version')) {
96-
return in_array($option, PhpVersion::values())
97-
? $option
98-
: throw new InvalidOptionValueException("Invalid value [$option] for option [php-version]");
99-
}
100-
101-
$detected = app(PhpVersionDetector::class)->detect();
102-
103-
if ($this->option('detect')) {
104-
return $detected;
105-
}
106-
107-
return $this->choice(
108-
question: 'PHP version',
109-
choices: PhpVersion::values(),
110-
default: $detected ?: PhpVersion::v8_2,
111-
);
112-
}
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-
*/
123-
private function getPhpExtensions(string $phpVersion): array
124-
{
125-
$supportedExtensions = PhpExtensions::values($phpVersion);
126-
127-
if ($option = $this->option('php-extensions')) {
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);
139-
}
140-
141-
$detected = app(PhpExtensionsDetector::class, ['supportedExtensions' => $supportedExtensions])->detect();
142-
143-
if ($this->option('detect')) {
144-
$detected = explode(',', $detected);
145-
146-
foreach ($detected as $key => $value) {
147-
$detected[$key] = $supportedExtensions[$value];
148-
}
149-
150-
return $detected;
151-
}
152-
153-
return $this->choice(
154-
question: 'PHP extensions',
155-
choices: $supportedExtensions,
156-
default: $detected,
157-
multiple: true,
158-
);
159-
}
160-
161-
public function getArtisanOptimize(): bool
162-
{
163-
if ($this->option('optimize') || $this->option('detect')) {
164-
return true;
165-
}
166-
167-
$choice = $this->choice(
168-
question: 'Do you want to run "php artisan optimize" when the image boots?',
169-
choices: ArtisanOptimize::values(),
170-
default: ArtisanOptimize::YES,
171-
);
172-
173-
return ArtisanOptimize::YES === $choice;
174-
}
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-
*/
184-
private function getNodePackageManager(): string|false
185-
{
186-
if ($option = $this->option('node-package-manager')) {
187-
return in_array($option, NodePackageManager::values())
188-
? $option
189-
: throw new InvalidOptionValueException("Invalid value [$option] for option [node-package-manager]");
190-
}
191-
192-
$detected = app(NodePackageManagerDetector::class)->detect();
193-
194-
if ($this->option('detect')) {
195-
return $detected;
196-
}
197-
198-
return $this->optionalChoice(
199-
question: 'Which Node package manager do you use?',
200-
choices: NodePackageManager::values(),
201-
default: $detected ?: NodePackageManager::NPM,
202-
);
203-
}
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-
*/
213-
private function getNodeBuildTool(): string
214-
{
215-
if ($option = $this->option('node-build-tool')) {
216-
return in_array($option, NodeBuildTool::values())
217-
? $option
218-
: throw new InvalidOptionValueException("Invalid value [$option] for option [node-build-tool]");
219-
}
220-
221-
$detected = app(NodeBuildToolDetector::class)->detect();
222-
223-
if ($this->option('detect')) {
224-
return $detected;
225-
}
226-
227-
return $this->choice(
228-
question: 'Which Node build tool do you use?',
229-
choices: NodeBuildTool::values(),
230-
default: $detected ?: NodeBuildTool::VITE,
231-
);
232-
}
233-
23481
private function saveDockerfiles(array $context): void
23582
{
23683
if (! is_dir($dir = base_path('.docker'))) {
@@ -281,9 +128,21 @@ protected function getOptions(): array
281128
new InputOption(
282129
name: 'optimize',
283130
shortcut: 'o',
284-
mode: InputOption::VALUE_NONE,
131+
mode: InputOption::VALUE_NEGATABLE,
285132
description: 'Add "php artisan optimize" to entrypoint',
286133
),
134+
new InputOption(
135+
name: 'opcache',
136+
mode: InputOption::VALUE_NEGATABLE,
137+
description: 'Add "opcache" extension and configure it',
138+
default: true,
139+
),
140+
new InputOption(
141+
name: 'alpine',
142+
mode: InputOption::VALUE_NEGATABLE,
143+
description: 'Use Alpine Linux based images',
144+
default: true,
145+
),
287146
new InputOption(
288147
name: 'node-package-manager',
289148
shortcut: 'm',
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions;
4+
5+
use BlameButton\LaravelDockerBuilder\Commands\BaseCommand;
6+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\ArtisanOptimize;
7+
8+
class ArtisanOptimizeQuestion extends BaseQuestion
9+
{
10+
public function getAnswer(BaseCommand $command): bool
11+
{
12+
if ($command->option('optimize') || $command->option('detect')) {
13+
return true;
14+
}
15+
16+
$choice = $command->choice(
17+
question: 'Do you want to run "php artisan optimize" when the image boots?',
18+
choices: ArtisanOptimize::values(),
19+
default: ArtisanOptimize::YES,
20+
);
21+
22+
return ArtisanOptimize::YES === $choice;
23+
}
24+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions;
4+
5+
abstract class BaseQuestion
6+
{
7+
}

src/Commands/Choices/ArtisanOptimize.php renamed to src/Commands/GenerateQuestions/Choices/ArtisanOptimize.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace BlameButton\LaravelDockerBuilder\Commands\Choices;
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices;
44

55
class ArtisanOptimize
66
{

src/Commands/Choices/NodeBuildTool.php renamed to src/Commands/GenerateQuestions/Choices/NodeBuildTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace BlameButton\LaravelDockerBuilder\Commands\Choices;
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices;
44

55
class NodeBuildTool
66
{

src/Commands/Choices/NodePackageManager.php renamed to src/Commands/GenerateQuestions/Choices/NodePackageManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace BlameButton\LaravelDockerBuilder\Commands\Choices;
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices;
44

55
class NodePackageManager
66
{

src/Commands/Choices/PhpExtensions.php renamed to src/Commands/GenerateQuestions/Choices/PhpExtensions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace BlameButton\LaravelDockerBuilder\Commands\Choices;
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices;
44

55
class PhpExtensions
66
{

src/Commands/Choices/PhpVersion.php renamed to src/Commands/GenerateQuestions/Choices/PhpVersion.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace BlameButton\LaravelDockerBuilder\Commands\Choices;
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices;
44

55
class PhpVersion
66
{
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions;
4+
5+
use BlameButton\LaravelDockerBuilder\Commands\BaseCommand;
6+
use BlameButton\LaravelDockerBuilder\Commands\GenerateQuestions\Choices\NodeBuildTool;
7+
use BlameButton\LaravelDockerBuilder\Detector\NodeBuildToolDetector;
8+
use BlameButton\LaravelDockerBuilder\Exceptions\InvalidOptionValueException;
9+
10+
class NodeBuildToolQuestion extends BaseQuestion
11+
{
12+
/**
13+
* Get the Node Build Tool, either by detecting it from files present (vite.config.js, webpack.mix.js),
14+
* from the "node-build-tool" option, or asking the user.
15+
*
16+
* @param BaseCommand $command
17+
* @return string
18+
*
19+
* @throws InvalidOptionValueException
20+
*/
21+
public function getAnswer(BaseCommand $command): string
22+
{
23+
if ($option = $command->option('node-build-tool')) {
24+
return in_array($option, NodeBuildTool::values())
25+
? $option
26+
: throw new InvalidOptionValueException("Invalid value [$option] for option [node-build-tool]");
27+
}
28+
29+
$detected = app(NodeBuildToolDetector::class)->detect();
30+
31+
if ($command->option('detect')) {
32+
return $detected;
33+
}
34+
35+
return $command->choice(
36+
question: 'Which Node build tool do you use?',
37+
choices: NodeBuildTool::values(),
38+
default: $detected ?: NodeBuildTool::VITE,
39+
);
40+
}
41+
}

0 commit comments

Comments
 (0)