Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 399 | Ganze Datei anzeigen | Leerzeichen ignorieren | Details | Blame | Letzte Änderung | Log anzeigen | RSS feed

Revision 399 Revision 621
Zeile 6... Zeile 6...
6
use RuntimeException;
6
use RuntimeException;
7
use Symfony\Component\Process\Process;
7
use Symfony\Component\Process\Process;
Zeile 8... Zeile 8...
8
 
8
 
9
class InstallCommand extends Command
9
class InstallCommand extends Command
-
 
10
{
-
 
11
    use Concerns\InteractsWithDockerComposeServices;
10
{
12
 
11
    /**
13
    /**
12
     * The name and signature of the console command.
14
     * The name and signature of the console command.
13
     *
15
     *
14
     * @var string
16
     * @var string
Zeile 23... Zeile 25...
23
     * @var string
25
     * @var string
24
     */
26
     */
25
    protected $description = 'Install Laravel Sail\'s default Docker Compose file';
27
    protected $description = 'Install Laravel Sail\'s default Docker Compose file';
Zeile 26... Zeile 28...
26
 
28
 
27
    /**
-
 
28
     * The available services that may be installed.
-
 
29
     *
-
 
30
     * @var array<string>
-
 
31
     */
-
 
32
    protected $services = [
-
 
33
        'mysql',
-
 
34
        'pgsql',
-
 
35
        'mariadb',
-
 
36
        'redis',
-
 
37
        'memcached',
-
 
38
        'meilisearch',
-
 
39
        'minio',
-
 
40
        'mailpit',
-
 
41
        'selenium',
-
 
42
    ];
-
 
43
 
-
 
44
    /**
29
    /**
45
     * Execute the console command.
30
     * Execute the console command.
46
     *
31
     *
47
     * @return int|null
32
     * @return int|null
48
     */
33
     */
49
    public function handle()
34
    public function handle()
50
    {
35
    {
51
        if ($this->option('with')) {
36
        if ($this->option('with')) {
52
            $services = $this->option('with') == 'none' ? [] : explode(',', $this->option('with'));
37
            $services = $this->option('with') == 'none' ? [] : explode(',', $this->option('with'));
53
        } elseif ($this->option('no-interaction')) {
38
        } elseif ($this->option('no-interaction')) {
54
            $services = ['mysql', 'redis', 'selenium', 'mailpit'];
39
            $services = $this->defaultServices;
55
        } else {
40
        } else {
56
            $services = $this->gatherServicesWithSymfonyMenu();
41
            $services = $this->gatherServicesWithSymfonyMenu();
Zeile 57... Zeile 42...
57
        }
42
        }
Zeile 72... Zeile 57...
72
 
57
 
Zeile 73... Zeile 58...
73
        $this->info('Sail scaffolding installed successfully.');
58
        $this->info('Sail scaffolding installed successfully.');
74
 
59
 
75
        $this->prepareInstallation($services);
-
 
76
    }
-
 
77
 
-
 
78
    /**
-
 
79
     * Gather the desired Sail services using a Symfony menu.
-
 
80
     *
-
 
81
     * @return array
-
 
82
     */
-
 
83
    protected function gatherServicesWithSymfonyMenu()
-
 
84
    {
-
 
85
        return $this->choice('Which services would you like to install?', $this->services, 0, null, true);
-
 
86
    }
-
 
87
 
-
 
88
    /**
-
 
89
     * Build the Docker Compose file.
-
 
90
     *
-
 
91
     * @param  array  $services
-
 
92
     * @return void
-
 
93
     */
-
 
94
    protected function buildDockerCompose(array $services)
-
 
95
    {
-
 
96
        $depends = collect($services)
-
 
97
            ->map(function ($service) {
-
 
98
                return "            - {$service}";
-
 
99
            })->whenNotEmpty(function ($collection) {
-
 
100
                return $collection->prepend('depends_on:');
-
 
101
            })->implode("\n");
-
 
102
 
-
 
103
        $stubs = rtrim(collect($services)->map(function ($service) {
-
 
104
            return file_get_contents(__DIR__ . "/../../stubs/{$service}.stub");
-
 
105
        })->implode(''));
-
 
106
 
-
 
107
        $volumes = collect($services)
-
 
108
            ->filter(function ($service) {
-
 
109
                return in_array($service, ['mysql', 'pgsql', 'mariadb', 'redis', 'meilisearch', 'minio']);
-
 
110
            })->map(function ($service) {
-
 
111
                return "    sail-{$service}:\n        driver: local";
-
 
112
            })->whenNotEmpty(function ($collection) {
-
 
113
                return $collection->prepend('volumes:');
-
 
114
            })->implode("\n");
-
 
115
 
-
 
116
        $dockerCompose = file_get_contents(__DIR__ . '/../../stubs/docker-compose.stub');
-
 
117
 
-
 
118
        $dockerCompose = str_replace('{{depends}}', empty($depends) ? '' : '        '.$depends, $dockerCompose);
-
 
119
        $dockerCompose = str_replace('{{services}}', $stubs, $dockerCompose);
-
 
120
        $dockerCompose = str_replace('{{volumes}}', $volumes, $dockerCompose);
-
 
121
 
-
 
122
        // Replace Selenium with ARM base container on Apple Silicon...
-
 
123
        if (in_array('selenium', $services) && php_uname('m') === 'arm64') {
-
 
124
            $dockerCompose = str_replace('selenium/standalone-chrome', 'seleniarm/standalone-chromium', $dockerCompose);
-
 
125
        }
-
 
126
 
-
 
127
        // Remove empty lines...
-
 
128
        $dockerCompose = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $dockerCompose);
-
 
129
 
-
 
130
        file_put_contents($this->laravel->basePath('docker-compose.yml'), $dockerCompose);
-
 
131
    }
-
 
132
 
-
 
133
    /**
-
 
134
     * Replace the Host environment variables in the app's .env file.
-
 
135
     *
-
 
136
     * @param  array  $services
-
 
137
     * @return void
-
 
138
     */
-
 
139
    protected function replaceEnvVariables(array $services)
-
 
140
    {
-
 
141
        $environment = file_get_contents($this->laravel->basePath('.env'));
-
 
142
 
-
 
143
        if (in_array('pgsql', $services)) {
-
 
144
            $environment = str_replace('DB_CONNECTION=mysql', "DB_CONNECTION=pgsql", $environment);
-
 
145
            $environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=pgsql", $environment);
-
 
146
            $environment = str_replace('DB_PORT=3306', "DB_PORT=5432", $environment);
-
 
147
        } elseif (in_array('mariadb', $services)) {
-
 
148
            $environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=mariadb", $environment);
-
 
149
        } else {
-
 
150
            $environment = str_replace('DB_HOST=127.0.0.1', "DB_HOST=mysql", $environment);
-
 
151
        }
-
 
152
 
-
 
153
        $environment = str_replace('DB_USERNAME=root', "DB_USERNAME=sail", $environment);
-
 
154
        $environment = preg_replace("/DB_PASSWORD=(.*)/", "DB_PASSWORD=password", $environment);
-
 
155
 
-
 
156
        $environment = str_replace('MEMCACHED_HOST=127.0.0.1', 'MEMCACHED_HOST=memcached', $environment);
-
 
157
        $environment = str_replace('REDIS_HOST=127.0.0.1', 'REDIS_HOST=redis', $environment);
-
 
158
 
-
 
159
        if (in_array('meilisearch', $services)) {
-
 
160
            $environment .= "\nSCOUT_DRIVER=meilisearch";
-
 
161
            $environment .= "\nMEILISEARCH_HOST=http://meilisearch:7700\n";
-
 
162
        }
-
 
163
 
-
 
164
        file_put_contents($this->laravel->basePath('.env'), $environment);
-
 
165
    }
-
 
166
 
-
 
167
    /**
-
 
168
     * Configure PHPUnit to use the dedicated testing database.
-
 
169
     *
-
 
170
     * @return void
-
 
171
     */
-
 
172
    protected function configurePhpUnit()
-
 
173
    {
-
 
174
        if (! file_exists($path = $this->laravel->basePath('phpunit.xml'))) {
-
 
175
            $path = $this->laravel->basePath('phpunit.xml.dist');
-
 
176
        }
-
 
177
 
-
 
178
        $phpunit = file_get_contents($path);
-
 
179
 
-
 
180
        $phpunit = preg_replace('/^.*DB_CONNECTION.*\n/m', '', $phpunit);
-
 
181
        $phpunit = str_replace('<!-- <env name="DB_DATABASE" value=":memory:"/> -->', '<env name="DB_DATABASE" value="testing"/>', $phpunit);
-
 
182
 
-
 
183
        file_put_contents($this->laravel->basePath('phpunit.xml'), $phpunit);
-
 
184
    }
-
 
185
 
-
 
186
    /**
-
 
187
     * Install the devcontainer.json configuration file.
-
 
188
     *
-
 
189
     * @return void
-
 
190
     */
-
 
191
    protected function installDevContainer()
-
 
192
    {
-
 
193
        if (! is_dir($this->laravel->basePath('.devcontainer'))) {
-
 
194
            mkdir($this->laravel->basePath('.devcontainer'), 0755, true);
-
 
195
        }
-
 
196
 
-
 
197
        file_put_contents(
-
 
198
            $this->laravel->basePath('.devcontainer/devcontainer.json'),
-
 
199
            file_get_contents(__DIR__.'/../../stubs/devcontainer.stub')
-
 
200
        );
-
 
201
 
-
 
202
        $environment = file_get_contents($this->laravel->basePath('.env'));
-
 
203
 
-
 
204
        $environment .= "\nWWWGROUP=1000";
-
 
205
        $environment .= "\nWWWUSER=1000\n";
-
 
206
 
-
 
207
        file_put_contents($this->laravel->basePath('.env'), $environment);
-
 
208
    }
-
 
209
 
-
 
210
    /**
-
 
211
     * Prepare the installation by pulling and building any necessary images.
-
 
212
     *
-
 
213
     * @param  array  $services
-
 
214
     * @return void
-
 
215
     */
-
 
216
    protected function prepareInstallation($services)
-
 
217
    {
-
 
218
        // Ensure docker is installed...
-
 
219
        if ($this->runCommands(['docker info > /dev/null 2>&1']) !== 0) {
-
 
220
            return;
-
 
221
        }
-
 
222
 
-
 
223
        if (count($services) > 0) {
-
 
224
            $status = $this->runCommands([
-
 
225
                './vendor/bin/sail pull '.implode(' ', $services),
-
 
226
            ]);
-
 
227
 
-
 
228
            if ($status === 0) {
-
 
229
                $this->info('Sail images installed successfully.');
-
 
230
            }
-
 
231
        }
-
 
232
 
-
 
233
        $status = $this->runCommands([
-
 
234
            './vendor/bin/sail build',
-
 
235
        ]);
-
 
236
 
-
 
237
        if ($status === 0) {
-
 
238
            $this->info('Sail build successful.');
-
 
239
        }
-
 
240
    }
-
 
241
 
-
 
242
    /**
-
 
243
     * Run the given commands.
-
 
244
     *
-
 
245
     * @param  array  $commands
-
 
246
     * @return int
-
 
247
     */
-
 
248
    protected function runCommands($commands)
-
 
249
    {
-
 
250
        $process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null);
-
 
251
 
-
 
252
        if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
-
 
253
            try {
-
 
254
                $process->setTty(true);
-
 
255
            } catch (RuntimeException $e) {
-
 
256
                $this->output->writeln('  <bg=yellow;fg=black> WARN </> '.$e->getMessage().PHP_EOL);
-
 
257
            }
-
 
258
        }
-
 
259
 
-
 
260
        return $process->run(function ($type, $line) {
-
 
261
            $this->output->write('    '.$line);
-
 
262
        });
60
        $this->prepareInstallation($services);