From 6294854ad3da4b183af2ec0cbe4fc0938ee47ace Mon Sep 17 00:00:00 2001 From: Giorgio Balduzzi Date: Tue, 23 May 2023 13:03:00 +0200 Subject: [PATCH] Emoji support --- composer.json | 2 +- src/Commands/InitCmd.php | 7 +++++-- src/Commands/ListCmd.php | 2 +- src/Commands/ManCmd.php | 15 ++++++--------- src/Commands/ProjectCmds/BackupCmd.php | 9 +++++++-- src/Commands/ProjectCmds/DockCmd.php | 4 ++-- src/Commands/ProjectCmds/RestoreCmd.php | 9 +++++---- src/Commands/ProjectCmds/RmCmd.php | 5 ----- src/Commands/ProjectCmds/SailCmd.php | 7 +++++-- src/Commands/ProjectCmds/SyncCmd.php | 10 ++++++++++ src/Commands/ProxyCmd/CertsCmd.php | 12 +++++++----- src/Commands/ProxyCmd/ConfigCmd.php | 6 +++--- src/Commands/ProxyCmd/DownCmd.php | 4 +++- src/Commands/ProxyCmd/ShowCmd.php | 2 +- src/Commands/ShutdownCmd.php | 6 ++++-- src/Commands/WithProject.php | 20 ++++++++++++++++++++ src/Config/Project.php | 2 +- src/Utils/DockerBase.php | 6 ++++-- src/Utils/Execute.php | 2 +- src/Utils/HostFile.php | 13 +++++++------ src/index.php | 2 +- 21 files changed, 94 insertions(+), 51 deletions(-) diff --git a/composer.json b/composer.json index 194d550..948171f 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "keywords": [ "laravel", "docker", "cli" ], "type": "library", "license": "MIT", - "version": "0.1.0", + "version": "0.1.1", "bin": [ "bin/skipper" ], diff --git a/src/Commands/InitCmd.php b/src/Commands/InitCmd.php index a5a5ee0..3867750 100644 --- a/src/Commands/InitCmd.php +++ b/src/Commands/InitCmd.php @@ -137,8 +137,8 @@ protected function handle(): int $this->io->success("$name has been created successfully."); - $this->io->writeln('Use command sail to start the project containers'); - $this->io->writeln('Use command check to validate your project compose file'); + $this->io->writeln('â›ĩī¸ Use command skipper sail to start the project containers'); + $this->io->writeln('✓ Use command skipper check to validate your project compose file'); return Command::SUCCESS; } @@ -185,6 +185,9 @@ private function preparePath(): void if ($dockerBase) { DockerBase::install(getcwd(), 'docker'); + + $this->io->writeln('Resuming the skipper init operation'); + $this->io->newLine(); } } diff --git a/src/Commands/ListCmd.php b/src/Commands/ListCmd.php index 8c69416..e9d71f4 100644 --- a/src/Commands/ListCmd.php +++ b/src/Commands/ListCmd.php @@ -10,7 +10,7 @@ class ListCmd extends BaseCommand { protected function handle(): int { - $data = array_map(fn ($p) => [$p->isRunning() ? 'Yes' : 'No', $p->name, $p->host, $p->path], $this->configRepo->config->projects); + $data = array_map(fn ($p) => [$p->isRunning() ? 'đŸŸĸ' : '🔴', $p->name, $p->host, $p->path], $this->configRepo->config->projects); $this->io->table(['Running', 'Name', 'Host', 'Path'], $data); diff --git a/src/Commands/ManCmd.php b/src/Commands/ManCmd.php index edf3ba7..53b0976 100644 --- a/src/Commands/ManCmd.php +++ b/src/Commands/ManCmd.php @@ -14,9 +14,7 @@ protected function handle(): int { $app = $this->getApplication(); - $all = $app->all(); - - $this->io->writeln("{$app->getName()} {$app->getVersion()}"); + $this->io->writeln("{$app->getName()}{$app->getVersion()}"); $this->io->newLine(); $this->io->writeln('Usage'); @@ -25,8 +23,7 @@ protected function handle(): int $this->io->newLine(); - $this->io->writeln('Default options'); - $this->io->writeln('Available for all commands'); + $this->io->writeln('Default options Available for all commands'); $this->io->definitionList( ['-h, --help' => 'Display help for the given command'], ['-q, --quiet' => 'Do not output any message'], @@ -38,13 +35,13 @@ protected function handle(): int $this->io->writeln(' Proxy'); $this->io->definitionList( - ['proxy:certs' => ' Install proxy local root certificate'], + ['proxy:certs' => 'Install proxy local root certificate'], ['proxy:up' => 'Launch the proxy docker compose instance'], ['proxy:down' => 'Stop the proxy docker compose instance'], ['proxy:restart' => 'Restart the proxy container instance'], ['proxy:show' => 'Print the current Caddyfile configuration'], ['proxy:config' => 'Regenerate the proxy configuration file'], - ['proxy:update' => ' Update the proxy deployment after a skipper upgrade'], + ['proxy:update' => 'Update the proxy deployment after a skipper upgrade'], ); $this->io->writeln(' Helpers'); @@ -78,8 +75,8 @@ protected function handle(): int ['restore' => 'Restore a MySQL backup'], ); - $this->io->writeln('Refer to https://github.com/tiknil/skipper for additional documentation'); - $this->io->writeln('Use skipper help [command] or skipper [command] --help for details about a specific command'); + $this->io->writeln('📖 Refer to https://github.com/tiknil/skipper for additional documentation'); + $this->io->writeln('❔ Use skipper help [command] or skipper [command] --help for details about a specific command'); return Command::SUCCESS; } diff --git a/src/Commands/ProjectCmds/BackupCmd.php b/src/Commands/ProjectCmds/BackupCmd.php index 77f4365..16c4e8a 100644 --- a/src/Commands/ProjectCmds/BackupCmd.php +++ b/src/Commands/ProjectCmds/BackupCmd.php @@ -129,13 +129,18 @@ protected function handle(): int fclose($fileStream); if ($dumpResult === Command::SUCCESS) { - $this->io->success("Backup $outputFile created successfully"); + $this->io->writeln('✅ Backup created successfully'); + $this->io->writeln("đŸ“Ļ $outputFile"); } $uncompressedFile = rtrim($outputFile, '.gz'); + $this->io->newLine(); $this->io->writeln(['You can uncompress it using']); - $this->io->writeln("gunzip < $outputFile > $uncompressedFile"); + $this->io->writeln("gunzip < $outputFile > $uncompressedFile"); + + $this->io->newLine(); + $this->io->writeln("Use skipper restore --file $outputFile to restore"); return $dumpResult; diff --git a/src/Commands/ProjectCmds/DockCmd.php b/src/Commands/ProjectCmds/DockCmd.php index 0643b44..6a03321 100644 --- a/src/Commands/ProjectCmds/DockCmd.php +++ b/src/Commands/ProjectCmds/DockCmd.php @@ -23,8 +23,8 @@ protected function handle(): int $result = Execute::onShell($cmd); if ($result === Command::SUCCESS) { - $this->io->writeln('Use command caddy stop to stop the reverse proxy'); - $this->io->writeln('Use command shutdown to stop all running projects and the reverse proxy'); + $this->io->writeln('⏚ī¸ Use command skipper caddy stop to stop the reverse proxy'); + $this->io->writeln('🔌 Use command skipper shutdown to stop all running projects and the reverse proxy'); } return $result; diff --git a/src/Commands/ProjectCmds/RestoreCmd.php b/src/Commands/ProjectCmds/RestoreCmd.php index 8569910..e7407fe 100644 --- a/src/Commands/ProjectCmds/RestoreCmd.php +++ b/src/Commands/ProjectCmds/RestoreCmd.php @@ -100,8 +100,9 @@ protected function handle(): int mkdir(dirname($file), 0777, true); } - $this->io->warning('Restoring the DB is a risky operation. You may lose your data'); - $this->io->text('Input file: '.$file); + $this->io->writeln('⚠ī¸ Restoring the DB is a risky operation. You may lose your data ⚠ī¸'); + $this->io->newLine(); + $this->io->writeln("Input file: $file"); $confirm = $this->io->confirm('Proceed anyway?'); @@ -144,7 +145,7 @@ protected function handle(): int $sqlStream->close(); $result = $process->wait(); - } catch (Exception $e) { + } catch (\Exception $e) { $this->io->error($e->getMessage()); $gunResult = Command::FAILURE; @@ -152,7 +153,7 @@ protected function handle(): int } if ($gunResult === Command::SUCCESS && $result === Command::SUCCESS) { - $this->io->success("Backup $file restored successfully"); + $this->io->success("✅ Backup $file restored successfully"); } else { $this->io->error('An error occurred'); diff --git a/src/Commands/ProjectCmds/RmCmd.php b/src/Commands/ProjectCmds/RmCmd.php index 07602e1..09b8a08 100644 --- a/src/Commands/ProjectCmds/RmCmd.php +++ b/src/Commands/ProjectCmds/RmCmd.php @@ -14,11 +14,6 @@ class RmCmd extends BaseCommand { use WithProject; - protected function prepare() - { - $this->io->infoText('Removing the skipper project'); - } - protected function handle(): int { Execute::onShell($this->project->composeCommand('down')); diff --git a/src/Commands/ProjectCmds/SailCmd.php b/src/Commands/ProjectCmds/SailCmd.php index 2158513..401c0e7 100644 --- a/src/Commands/ProjectCmds/SailCmd.php +++ b/src/Commands/ProjectCmds/SailCmd.php @@ -37,6 +37,7 @@ protected function handle(): int ...$this->project->definitionList() ); + $this->io->writeln('Performing docker compose validity checks'); $result = $this->checkComposeFile(); if (!$result) { @@ -45,6 +46,8 @@ protected function handle(): int if (!$confirm) { return Command::SUCCESS; } + } else { + $this->io->newLine(); } $shouldBuild = $this->input->getOption('build'); @@ -67,7 +70,7 @@ protected function handle(): int if (!HostFile::for($this->project->host)->check()) { $this->io->writeln([ - "Host {$this->project->host} is not registered inside your /etc/hosts file.", + "❕ Host {$this->project->host} is not registered inside your /etc/hosts file.", "Use command skipper host {$this->project->host}", ]); @@ -75,7 +78,7 @@ protected function handle(): int } $this->io->writeln([ - "{$this->project->name} is up and running at https://{$this->project->host}", + "🚀 {$this->project->name} is up and running at https://{$this->project->host} 🚀", ]); return Command::SUCCESS; diff --git a/src/Commands/ProjectCmds/SyncCmd.php b/src/Commands/ProjectCmds/SyncCmd.php index 0bbdfc8..b23a47d 100644 --- a/src/Commands/ProjectCmds/SyncCmd.php +++ b/src/Commands/ProjectCmds/SyncCmd.php @@ -15,6 +15,7 @@ class SyncCmd extends BaseCommand protected function handle(): int { + $this->io->writeln('Install composer dependencies'); Execute::onShell($this->project->composeCommand([ 'exec', $this->project->phpContainer, @@ -22,6 +23,9 @@ protected function handle(): int 'install', ])); + $this->io->writeln('-------------------'); + $this->io->writeln('Migrate database'); + Execute::onShell($this->project->composeCommand([ 'exec', $this->project->phpContainer, @@ -32,8 +36,14 @@ protected function handle(): int Execute::hideOutput(['cd', $this->project->path], false); + $this->io->writeln('-------------------'); + $this->io->writeln('Install js dependencies'); + Execute::onShell(['yarn', 'install']); + $this->io->writeln('-------------------'); + $this->io->writeln('Build frontend files'); + Execute::onShell(['yarn', 'build']); return Command::SUCCESS; diff --git a/src/Commands/ProxyCmd/CertsCmd.php b/src/Commands/ProxyCmd/CertsCmd.php index 4ccb8c1..2668a69 100644 --- a/src/Commands/ProxyCmd/CertsCmd.php +++ b/src/Commands/ProxyCmd/CertsCmd.php @@ -14,12 +14,14 @@ protected function handle(): int { $caddy = $this->configRepo->caddy; - $this->io->writeln('The proxy (Caddy) creates a local root certificate to sign its https certificates'); + $this->io->writeln('📝 The proxy (Caddy) creates a local root certificate to sign its https certificates'); $this->io->writeln("The OS normally doesn't trust this root certificate, but we can install it on our system"); + $this->io->newLine(); + $uid = posix_getuid(); - $this->io->writeln('Looking for root certificate in '.$caddy->certPath().''); + $this->io->writeln('🧐 Looking for root certificate in '.$caddy->certPath().''); if (!file_exists($caddy->certPath())) { $this->io->note([ @@ -35,7 +37,7 @@ protected function handle(): int $cmd = []; - $this->io->writeln('Mac OS X will prompt for your Touch ID or password'); + $this->io->writeln('🔐 Mac OS X will prompt for your Touch ID or password'); if ($uid !== 0) { $cmd[] = 'sudo'; @@ -51,10 +53,10 @@ protected function handle(): int $result = Execute::onShell($cmd); if ($result === Command::SUCCESS) { - $this->io->success('Cert installed correctly'); + $this->io->success('✅ Cert installed correctly'); $this->io->writeln([ - 'The browser may need some time to refresh its cache and recognize the certificate as valid', + 'âŗ The browser may need some time to refresh its cache and recognize the certificate as valid', ]); } diff --git a/src/Commands/ProxyCmd/ConfigCmd.php b/src/Commands/ProxyCmd/ConfigCmd.php index 08c80c7..5c8e3eb 100644 --- a/src/Commands/ProxyCmd/ConfigCmd.php +++ b/src/Commands/ProxyCmd/ConfigCmd.php @@ -15,10 +15,10 @@ protected function handle(): int $caddy->writeCaddyfile($this->configRepo->config); - $this->io->success('Configuration updated'); + $this->io->success('✅ Configuration updated'); - $this->io->writeln('Use skipper proxy:show to see the updated file'); - $this->io->writeln('Use skipper proxy:restart to see the new configuration in action'); + $this->io->writeln('📄 Use skipper proxy:show to see the updated file'); + $this->io->writeln('â–ļī¸ Use skipper proxy:restart to see the new configuration in action'); return Command::SUCCESS; } diff --git a/src/Commands/ProxyCmd/DownCmd.php b/src/Commands/ProxyCmd/DownCmd.php index 21735e9..0f04484 100644 --- a/src/Commands/ProxyCmd/DownCmd.php +++ b/src/Commands/ProxyCmd/DownCmd.php @@ -11,7 +11,9 @@ class DownCmd extends BaseCommand protected function handle(): int { - $this->io->info(['If you have at least one project running, docker will not be able to dismiss the skipper network']); + $this->io->writeln(['❕ If you have at least one project running, docker will not be able to dismiss the skipper network']); + $this->io->newLine(); + $caddy = $this->configRepo->caddy; return $caddy->stop(); diff --git a/src/Commands/ProxyCmd/ShowCmd.php b/src/Commands/ProxyCmd/ShowCmd.php index 670e37c..65247c8 100644 --- a/src/Commands/ProxyCmd/ShowCmd.php +++ b/src/Commands/ProxyCmd/ShowCmd.php @@ -13,6 +13,6 @@ protected function handle(): int { $caddy = $this->configRepo->caddy; - return Execute::onOutput(['cat', $caddy->caddyfilePath()]); + return Execute::onShell(['less', $caddy->caddyfilePath()]); } } diff --git a/src/Commands/ShutdownCmd.php b/src/Commands/ShutdownCmd.php index 2afcb76..19ea874 100644 --- a/src/Commands/ShutdownCmd.php +++ b/src/Commands/ShutdownCmd.php @@ -14,16 +14,18 @@ protected function handle(): int foreach ($this->configRepo->config->projects as $project) { if (!$project->isRunning()) { - $this->io->writeln("Skipping {$project->name}, not currently running"); + $this->io->writeln("⏭ī¸ Skipping {$project->name}, not currently running"); continue; } - $this->io->writeln("Stopping {$project->name}"); + $this->io->writeln("⏚ī¸ Stopping {$project->name}"); Execute::onShell($project->composeCommand('down')); } + $this->io->newLine(); + $this->io->writeln('⏚ī¸ Stopping the reverse proxy'); $this->configRepo->caddy->stop(); return Command::SUCCESS; diff --git a/src/Commands/WithProject.php b/src/Commands/WithProject.php index 5e02eb0..b1ccf88 100644 --- a/src/Commands/WithProject.php +++ b/src/Commands/WithProject.php @@ -36,15 +36,19 @@ protected function validateProjectDir(): void protected function checkComposeFile(): bool { + $this->io->write('Checking docker-compose file presence...'); if (!file_exists($this->project->composeFilePath())) { $this->io->warning('Compose file not found at path '.$this->project->composeFilePath()); return false; + } else { + $this->io->write(' ✅'."\n"); } $warnings = 0; // Load file + $this->io->writeln('Loading docker-compose file'); try { $data = Yaml::parseFile($this->project->composeFilePath()); } catch (\Exception $e) { @@ -54,6 +58,8 @@ protected function checkComposeFile(): bool return false; } + $this->io->write('Checking network configuration...'); + $network = $data['networks'][$this->configRepo->config->network] ?? []; if ( empty($network) @@ -75,10 +81,13 @@ protected function checkComposeFile(): bool ); $warnings++; + } else { + $this->io->write(' ✅'."\n"); } $services = $data['services'] ?? []; + $this->io->write('Checking http container...'); if (!isset($services[$this->project->httpContainer])) { $this->io->warning([ "{$this->project->httpContainer} container is missing from your compose file", @@ -86,10 +95,13 @@ protected function checkComposeFile(): bool ]); $warnings++; + } else { + $this->io->write(' ✅'."\n"); } $nginxNetworks = $services[$this->project->httpContainer]['networks'] ?? []; + $this->io->write('Checking http networks...'); if (!empty(array_diff(['default', $this->configRepo->config->network], $nginxNetworks))) { $this->io->warning([ "{$this->project->httpContainer} container should be attached to two networks", @@ -97,8 +109,11 @@ protected function checkComposeFile(): bool ]); $warnings++; + } else { + $this->io->write(' ✅'."\n"); } + $this->io->write('Checking php container...'); if (!isset($services[$this->project->phpContainer])) { $this->io->warning([ "{$this->project->phpContainer} container is missing from your compose file", @@ -106,10 +121,13 @@ protected function checkComposeFile(): bool ]); $warnings++; + } else { + $this->io->write(' ✅'."\n"); } $override = rtrim(dirname($this->project->composeFilePath()), '/').'/docker-compose.override.yml'; + $this->io->write('Checking override file...'); if (file_exists($override)) { $this->io->warning([ "Found override file at $override", @@ -119,6 +137,8 @@ protected function checkComposeFile(): bool ]); $warnings++; + } else { + $this->io->write(' ✅'."\n"); } return $warnings === 0; diff --git a/src/Config/Project.php b/src/Config/Project.php index b542415..f5d1139 100644 --- a/src/Config/Project.php +++ b/src/Config/Project.php @@ -84,7 +84,7 @@ public function envFilePath(): string return $this->envFile; } - if (rtrim(getcwd(), '/') === rtrim($this->envFile, '/')) { + if (rtrim(getcwd(), '/') === rtrim($this->path, '/')) { return $this->envFile; } diff --git a/src/Utils/DockerBase.php b/src/Utils/DockerBase.php index 59a5c83..535694d 100644 --- a/src/Utils/DockerBase.php +++ b/src/Utils/DockerBase.php @@ -27,17 +27,19 @@ public static function install(string $path, string $folder = 'docker'): void public function performInstall() { $filePath = "$this->path/$this->folder"; - $this->io->writeln(["Installing base docker configuration into {$this->folder}/"]); + $this->io->writeln(["🚧 Installing base docker configuration into {$this->folder}/"]); if (file_exists($filePath.'/')) { - $this->io->note(["Folder {$this->folder} already exists.", 'All its content will be deleted and replaced']); + $this->io->warning(["Folder {$this->folder} already exists.", 'All its content will be deleted and replaced']); if ($this->io->confirm('Proceed anyway?')) { Execute::onOutput(['rm', '-r', $filePath]); } else { $this->io->writeln('Operation canceled. The base docker configuration will not be installed'); + + return; } } diff --git a/src/Utils/Execute.php b/src/Utils/Execute.php index 88d4d84..3fe78ea 100644 --- a/src/Utils/Execute.php +++ b/src/Utils/Execute.php @@ -56,6 +56,6 @@ public static function hideOutput(array $cmd, bool $log = true): int public static function logCmd(array $cmd): void { - Globals::$output->writeln(' >>> '.implode(' ', $cmd)."\n"); + Globals::$output->writeln(' đŸ’ģ '.implode(' ', $cmd)."\n"); } } diff --git a/src/Utils/HostFile.php b/src/Utils/HostFile.php index 4f7902c..aba0908 100644 --- a/src/Utils/HostFile.php +++ b/src/Utils/HostFile.php @@ -28,7 +28,7 @@ public function check(): bool public function requestAdd(): void { if (!$this->add()) { - $this->io->writeln('You can add the record manually to your /etc/hosts'. + $this->io->writeln('📝 You can add the record manually to your /etc/hosts '. "file or try again with command skipper host $this->host --ip $this->ip" ); } @@ -36,14 +36,15 @@ public function requestAdd(): void public function add(): bool { - $this->io->writeln("Mapping $this->host to $this->ip"); + $this->io->writeln("🔀 Mapping $this->host to $this->ip"); $lines = $this->readFile(); $hostLine = $this->findHostLine($lines); if ($hostLine !== null) { - $this->io->writeln("$this->host already found on your hosts file at line $hostLine:"); + $this->io->newLine(); + $this->io->writeln("🧐 $this->host already found on your hosts file at line $hostLine:"); $this->io->newLine(); $this->io->writeln($lines[$hostLine]); @@ -70,7 +71,7 @@ public function add(): bool return false; } else { - $this->io->writeln("$this->host mapped successfully to $this->ip"); + $this->io->writeln("✅ $this->host mapped successfully to $this->ip"); } @@ -154,7 +155,7 @@ private function findHostLine(array $lines): int|null private function writeFile(array $lines): int { $this->io->writeln('We need sudo permissions to create a backup copy of your hosts file and to remove the host'); - $this->io->writeln('You may be prompted for your password'); + $this->io->writeln('🔐 You may be prompted for your password'); if (Execute::onShell(['sudo', 'cp', '/etc/hosts', '/etc/hosts.bkp'], false) !== Command::SUCCESS) { $this->io->error('Error creating hosts backup file.'); @@ -162,7 +163,7 @@ private function writeFile(array $lines): int return false; } - $this->io->writeln('Backup file /etc/hosts.bkp created successfully'); + $this->io->writeln('đŸ“Ļ Backup file /etc/hosts.bkp created successfully'); $inputStream = new InputStream(); diff --git a/src/index.php b/src/index.php index 4183651..f4b08cd 100644 --- a/src/index.php +++ b/src/index.php @@ -4,7 +4,7 @@ $version = \Composer\InstalledVersions::getPrettyVersion('tiknil/skipper'); -$app = new CliApplication('Tiknil Skipper', $version ?? 'dev'); +$app = new CliApplication('Tiknil Skipper â›ĩī¸', $version ?? 'dev'); $app->registerCommands();