Skip to content

Commit

Permalink
[1.x] Build and pull images on install (#467)
Browse files Browse the repository at this point in the history
  • Loading branch information
jessarcher authored Aug 16, 2022
1 parent 4de7b22 commit 7e7222e
Showing 1 changed file with 75 additions and 15 deletions.
90 changes: 75 additions & 15 deletions src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Laravel\Sail\Console;

use Illuminate\Console\Command;
use RuntimeException;
use Symfony\Component\Process\Process;

class InstallCommand extends Command
{
Expand All @@ -22,10 +24,27 @@ class InstallCommand extends Command
*/
protected $description = 'Install Laravel Sail\'s default Docker Compose file';

/**
* The available services that may be installed.
*
* @var array<string>
*/
protected $services = [
'mysql',
'pgsql',
'mariadb',
'redis',
'memcached',
'meilisearch',
'minio',
'mailhog',
'selenium',
];

/**
* Execute the console command.
*
* @return void
* @return int|null
*/
public function handle()
{
Expand All @@ -37,6 +56,12 @@ public function handle()
$services = $this->gatherServicesWithSymfonyMenu();
}

if ($invalidServices = array_diff($services, $this->services)) {
$this->error('Invalid services ['.implode(',', $invalidServices).'].');

return 1;
}

$this->buildDockerCompose($services);
$this->replaceEnvVariables($services);
$this->configurePhpUnit();
Expand All @@ -46,6 +71,8 @@ public function handle()
}

$this->info('Sail scaffolding installed successfully.');

return $this->prepareInstallation($services);
}

/**
Expand All @@ -55,17 +82,7 @@ public function handle()
*/
protected function gatherServicesWithSymfonyMenu()
{
return $this->choice('Which services would you like to install?', [
'mysql',
'pgsql',
'mariadb',
'redis',
'memcached',
'meilisearch',
'minio',
'mailhog',
'selenium',
], 0, null, true);
return $this->choice('Which services would you like to install?', $this->services, 0, null, true);
}

/**
Expand All @@ -77,9 +94,7 @@ protected function gatherServicesWithSymfonyMenu()
protected function buildDockerCompose(array $services)
{
$depends = collect($services)
->filter(function ($service) {
return in_array($service, ['mysql', 'pgsql', 'mariadb', 'redis', 'meilisearch', 'minio', 'selenium']);
})->map(function ($service) {
->map(function ($service) {
return " - {$service}";
})->whenNotEmpty(function ($collection) {
return $collection->prepend('depends_on:');
Expand Down Expand Up @@ -191,4 +206,49 @@ protected function installDevContainer()

file_put_contents($this->laravel->basePath('.env'), $environment);
}

/**
* Prepare the installation by pulling and building any necessary images.
*
* @param array $services
* @return int|null
*/
protected function prepareInstallation($services)
{
$status = $this->runCommands([
'./vendor/bin/sail pull '.implode(' ', $services),
'./vendor/bin/sail build',
]);

if ($status !== 0) {
$this->warn('Unable to download and build your Sail images. Is Docker installed and running?');

return 1;
}

$this->info('Sail images installed successfully.');
}

/**
* Run the given commands.
*
* @param array $commands
* @return int
*/
protected function runCommands($commands)
{
$process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null);

if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
try {
$process->setTty(true);
} catch (RuntimeException $e) {
$this->output->writeln(' <bg=yellow;fg=black> WARN </> '.$e->getMessage().PHP_EOL);
}
}

return $process->run(function ($type, $line) {
$this->output->write(' '.$line);
});
}
}

1 comment on commit 7e7222e

@jf-prevost
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    $status = $this->runCommands([
         './vendor/bin/sail pull '.implode(' ', $services),
         './vendor/bin/sail build',
     ]);

when $services is empty (because of sail:install --with=none) pulling images fails.

Please sign in to comment.