From 0df108277867458ff25a774542be394f0227db6b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 7 Jan 2021 12:39:38 +0200 Subject: [PATCH] Keep on fixing CLI commands --- .../Grav/Console/Application/Application.php | 24 ++ .../Console/Application/PluginApplication.php | 23 +- system/src/Grav/Console/Cli/BackupCommand.php | 25 +- system/src/Grav/Console/Cli/CleanCommand.php | 63 +++-- .../Grav/Console/Cli/ClearCacheCommand.php | 30 +- .../src/Grav/Console/Cli/ComposerCommand.php | 11 +- .../src/Grav/Console/Cli/InstallCommand.php | 78 +++--- .../src/Grav/Console/Cli/LogViewerCommand.php | 10 +- .../Grav/Console/Cli/NewProjectCommand.php | 6 +- .../Cli/PageSystemValidatorCommand.php | 41 +-- .../src/Grav/Console/Cli/SandboxCommand.php | 69 +++-- .../src/Grav/Console/Cli/SchedulerCommand.php | 20 +- .../src/Grav/Console/Cli/SecurityCommand.php | 11 +- system/src/Grav/Console/Cli/ServerCommand.php | 32 +-- .../Grav/Console/Cli/YamlLinterCommand.php | 9 +- system/src/Grav/Console/ConsoleCommand.php | 3 +- system/src/Grav/Console/ConsoleTrait.php | 62 +++-- .../Grav/Console/Gpm/DirectInstallCommand.php | 123 +++++---- system/src/Grav/Console/Gpm/IndexCommand.php | 37 +-- system/src/Grav/Console/Gpm/InfoCommand.php | 72 ++--- .../src/Grav/Console/Gpm/InstallCommand.php | 259 +++++++++--------- .../Grav/Console/Gpm/SelfupgradeCommand.php | 120 ++++---- .../src/Grav/Console/Gpm/UninstallCommand.php | 105 ++++--- system/src/Grav/Console/Gpm/UpdateCommand.php | 82 +++--- .../src/Grav/Console/Gpm/VersionCommand.php | 11 +- system/src/Grav/Console/GpmCommand.php | 11 +- system/src/Grav/Console/GravCommand.php | 3 +- .../Grav/Console/Plugin/PluginListCommand.php | 29 +- .../Grav/Console/TerminalObjects/Table.php | 1 + 29 files changed, 719 insertions(+), 651 deletions(-) diff --git a/system/src/Grav/Console/Application/Application.php b/system/src/Grav/Console/Application/Application.php index 1634a8447..be4e3c8cd 100644 --- a/system/src/Grav/Console/Application/Application.php +++ b/system/src/Grav/Console/Application/Application.php @@ -10,9 +10,11 @@ namespace Grav\Console\Application; use Grav\Common\Grav; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; /** * Class GpmApplication @@ -40,6 +42,9 @@ class Application extends \Symfony\Component\Console\Application return parent::getCommandName($input); } + /** + * @return void + */ protected function init(): void { if ($this->initialized) { @@ -79,4 +84,23 @@ class Application extends \Symfony\Component\Console\Application return $inputDefinition; } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + protected function configureIO(InputInterface $input, OutputInterface $output) + { + $formatter = $output->getFormatter(); + $formatter->setStyle('normal', new OutputFormatterStyle('white')); + $formatter->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); + $formatter->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); + $formatter->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); + $formatter->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); + $formatter->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); + $formatter->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); + + parent::configureIO($input, $output); + } } diff --git a/system/src/Grav/Console/Application/PluginApplication.php b/system/src/Grav/Console/Application/PluginApplication.php index aca1c4e11..dd23d9301 100644 --- a/system/src/Grav/Console/Application/PluginApplication.php +++ b/system/src/Grav/Console/Application/PluginApplication.php @@ -9,8 +9,8 @@ namespace Grav\Console\Application; -use Grav\Common\Data\Data; use Grav\Common\Grav; +use Grav\Common\Plugins; use Grav\Console\Application\CommandLoader\PluginCommandLoader; use Grav\Console\Plugin\PluginListCommand; use Symfony\Component\Console\Exception\NamespaceNotFoundException; @@ -28,6 +28,11 @@ class PluginApplication extends Application /** @var string|null */ protected $pluginName; + /** + * PluginApplication constructor. + * @param string $name + * @param string $version + */ public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') { parent::__construct($name, $version); @@ -37,11 +42,18 @@ class PluginApplication extends Application ]); } + /** + * @param string $pluginName + * @return void + */ public function setPluginName(string $pluginName): void { $this->pluginName = $pluginName; } + /** + * @return string + */ public function getPluginName(): string { return $this->pluginName; @@ -68,6 +80,9 @@ class PluginApplication extends Application return parent::run($input, $output); } + /** + * @return void + */ protected function init(): void { if ($this->initialized) { @@ -85,8 +100,10 @@ class PluginApplication extends Application $grav = Grav::instance(); $grav->initializeCli(); - /** @var Data $plugin */ - $plugin = $this->pluginName ? $grav['plugins']->get($this->pluginName) : null; + /** @var Plugins $plugins */ + $plugins = $grav['plugins']; + + $plugin = $this->pluginName ? $plugins::get($this->pluginName) : null; if (null === $plugin) { throw new NamespaceNotFoundException("Plugin \"{$this->pluginName}\" is not installed."); } diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index 7aa7cf156..8dbf5b6af 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -15,7 +15,6 @@ use Grav\Console\GravCommand; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; use ZipArchive; use function count; @@ -27,7 +26,6 @@ class BackupCommand extends GravCommand { /** @var string $source */ protected $source; - /** @var ProgressBar $progress */ protected $progress; @@ -56,11 +54,9 @@ class BackupCommand extends GravCommand { $this->initializeGrav(); - $this->progress = new ProgressBar($this->output); - $this->progress->setFormat('Archiving %current% files [%bar%] %percent:3s%% %elapsed:6s% %message%'); - $this->progress->setBarWidth(100); + $input = $this->getInput(); + $io = $this->getIO(); - $io = new SymfonyStyle($this->input, $this->output); $io->title('Grav Backup'); if (!class_exists(ZipArchive::class)) { @@ -68,28 +64,33 @@ class BackupCommand extends GravCommand return 1; } + ProgressBar::setFormatDefinition('zip', 'Archiving %current% files [%bar%] %percent:3s%% %elapsed:6s% %message%'); + + $this->progress = $io->createProgressBar(); + $this->progress->setFormat('zip'); + $this->progress->setBarWidth(100); + /** @var Backups $backups */ $backups = Grav::instance()['backups']; - $backups_list = $backups->getBackupProfiles(); + $backups_list = $backups::getBackupProfiles(); $backups_names = $backups->getBackupNames(); $id = null; - $inline_id = $this->input->getArgument('id'); + $inline_id = $input->getArgument('id'); if (null !== $inline_id && is_numeric($inline_id)) { $id = $inline_id; } if (null === $id) { if (count($backups_list) > 1) { - $helper = $this->getHelper('question'); $question = new ChoiceQuestion( 'Choose a backup?', $backups_names, 0 ); $question->setErrorMessage('Option %s is invalid.'); - $backup_name = $helper->ask($this->input, $this->output, $question); + $backup_name = $io->askQuestion($question); $id = array_search($backup_name, $backups_names, true); $io->newLine(); @@ -99,7 +100,7 @@ class BackupCommand extends GravCommand } } - $backup = $backups->backup($id, [$this, 'outputProgress']); + $backup = $backups::backup($id, function($args) { $this->outputProgress($args); }); $io->newline(2); $io->success('Backup Successfully Created: ' . $backup); @@ -111,7 +112,7 @@ class BackupCommand extends GravCommand * @param array $args * @return void */ - public function outputProgress($args): void + public function outputProgress(array $args): void { switch ($args['type']) { case 'count': diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index ba03cb67b..9b1b2fd34 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -14,6 +14,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Style\SymfonyStyle; /** * Class CleanCommand @@ -21,11 +22,10 @@ use Symfony\Component\Console\Formatter\OutputFormatterStyle; */ class CleanCommand extends Command { - /* @var InputInterface $output */ + /** @var InputInterface */ protected $input; - - /* @var OutputInterface $output */ - protected $output; + /** @var SymfonyStyle */ + protected $io; /** @var array */ protected $paths_to_remove = [ @@ -284,33 +284,40 @@ class CleanCommand extends Command { $this->setupConsole($input, $output); - $this->cleanPaths(); - - return 0; + return $this->cleanPaths() ? 0 : 1; } /** - * @return void + * @return bool */ - private function cleanPaths(): void + private function cleanPaths(): bool { - $this->output->writeln(''); - $this->output->writeln('DELETING'); + $success = true; + + $this->io->writeln(''); + $this->io->writeln('DELETING'); $anything = false; foreach ($this->paths_to_remove as $path) { - $path = ROOT_DIR . $path; - if (is_dir($path) && @Folder::delete($path)) { - $anything = true; - $this->output->writeln('dir: ' . $path); - } elseif (is_file($path) && @unlink($path)) { - $anything = true; - $this->output->writeln('file: ' . $path); + $path = GRAV_ROOT . $path; + try { + if (is_dir($path) && Folder::delete($path)) { + $anything = true; + $this->io->writeln('dir: ' . $path); + } elseif (is_file($path) && @unlink($path)) { + $anything = true; + $this->io->writeln('file: ' . $path); + } + } catch (\Exception $e) { + $success = false; + $this->io->error(sprintf('Failed to delete %s: %s', $path, $e->getMessage())); } } if (!$anything) { - $this->output->writeln(''); - $this->output->writeln('Nothing to clean...'); + $this->io->writeln(''); + $this->io->writeln('Nothing to clean...'); } + + return $success; } /** @@ -323,14 +330,14 @@ class CleanCommand extends Command public function setupConsole(InputInterface $input, OutputInterface $output): void { $this->input = $input; - $this->output = $output; + $this->io = new SymfonyStyle($input, $output); - $this->output->getFormatter()->setStyle('normal', new OutputFormatterStyle('white')); - $this->output->getFormatter()->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); - $this->output->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); - $this->output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); - $this->output->getFormatter()->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); - $this->output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); - $this->output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); + $this->io->getFormatter()->setStyle('normal', new OutputFormatterStyle('white')); + $this->io->getFormatter()->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); + $this->io->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); + $this->io->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); + $this->io->getFormatter()->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); + $this->io->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); + $this->io->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); } } diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php index fba7a6b2d..47c94b953 100644 --- a/system/src/Grav/Console/Cli/ClearCacheCommand.php +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -57,37 +57,39 @@ class ClearCacheCommand extends GravCommand */ private function cleanPaths(): void { - $this->output->writeln(''); + $input = $this->getInput(); + $io = $this->getIO(); + $io->newLine(); - if ($this->input->getOption('purge')) { - $this->output->writeln('Purging old cache'); - $this->output->writeln(''); + if ($input->getOption('purge')) { + $io->writeln('Purging old cache'); + $io->newLine(); $msg = Cache::purgeJob(); - $this->output->writeln($msg); + $io->writeln($msg); } else { - $this->output->writeln('Clearing cache'); - $this->output->writeln(''); + $io->writeln('Clearing cache'); + $io->newLine(); - if ($this->input->getOption('all')) { + if ($input->getOption('all')) { $remove = 'all'; - } elseif ($this->input->getOption('assets-only')) { + } elseif ($input->getOption('assets-only')) { $remove = 'assets-only'; - } elseif ($this->input->getOption('images-only')) { + } elseif ($input->getOption('images-only')) { $remove = 'images-only'; - } elseif ($this->input->getOption('cache-only')) { + } elseif ($input->getOption('cache-only')) { $remove = 'cache-only'; - } elseif ($this->input->getOption('tmp-only')) { + } elseif ($input->getOption('tmp-only')) { $remove = 'tmp-only'; - } elseif ($this->input->getOption('invalidate')) { + } elseif ($input->getOption('invalidate')) { $remove = 'invalidate'; } else { $remove = 'standard'; } foreach (Cache::clearCache($remove) as $result) { - $this->output->writeln($result); + $io->writeln($result); } } } diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php index 635cd7488..99fdf3592 100644 --- a/system/src/Grav/Console/Cli/ComposerCommand.php +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -46,15 +46,18 @@ class ComposerCommand extends GravCommand */ protected function serve(): int { - $action = $this->input->getOption('install') ? 'install' : ($this->input->getOption('update') ? 'update' : 'install'); + $input = $this->getInput(); + $io = $this->getIO(); - if ($this->input->getOption('install')) { + $action = $input->getOption('install') ? 'install' : ($input->getOption('update') ? 'update' : 'install'); + + if ($input->getOption('install')) { $action = 'install'; } // Updates composer first - $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln($this->composerUpdate(GRAV_ROOT, $action)); + $io->writeln("\nInstalling vendor dependencies"); + $io->writeln($this->composerUpdate(GRAV_ROOT, $action)); return 0; } diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index cc33bc590..001b83a42 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -22,10 +22,8 @@ class InstallCommand extends GravCommand { /** @var array */ protected $config; - /** @var string */ protected $destination; - /** @var string */ protected $user_path; @@ -56,14 +54,17 @@ class InstallCommand extends GravCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + $dependencies_file = '.dependencies'; - $this->destination = $this->input->getArgument('destination') ?: ROOT_DIR; + $this->destination = $input->getArgument('destination') ?: ROOT_DIR; // fix trailing slash $this->destination = rtrim($this->destination, DS) . DS; $this->user_path = $this->destination . USER_PATH; if ($local_config_file = $this->loadLocalConfig()) { - $this->output->writeln('Read local config from ' . $local_config_file . ''); + $io->writeln('Read local config from ' . $local_config_file . ''); } // Look for dependencies file in ROOT and USER dir @@ -72,11 +73,11 @@ class InstallCommand extends GravCommand } elseif (file_exists($this->destination . $dependencies_file)) { $file = YamlFile::instance($this->destination . $dependencies_file); } else { - $this->output->writeln('ERROR Missing .dependencies file in user/ folder'); - if ($this->input->getArgument('destination')) { - $this->output->writeln('HINT Are you trying to install a plugin or a theme? Make sure you use bin/gpm install , not bin/grav install. This command is only used to install Grav skeletons.'); + $io->writeln('ERROR Missing .dependencies file in user/ folder'); + if ($input->getArgument('destination')) { + $io->writeln('HINT Are you trying to install a plugin or a theme? Make sure you use bin/gpm install , not bin/grav install. This command is only used to install Grav skeletons.'); } else { - $this->output->writeln('HINT Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.'); + $io->writeln('HINT Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.'); } return 1; @@ -87,16 +88,15 @@ class InstallCommand extends GravCommand // If no config, fail. if (!$this->config) { - $this->output->writeln('ERROR invalid YAML in ' . $dependencies_file); + $io->writeln('ERROR invalid YAML in ' . $dependencies_file); return 1; } - $error = 0; - if (!$this->input->getOption('symlink')) { + if (!$input->getOption('symlink')) { // Updates composer first - $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln($this->composerUpdate(GRAV_ROOT, 'install')); + $io->writeln("\nInstalling vendor dependencies"); + $io->writeln($this->composerUpdate(GRAV_ROOT, 'install')); $error = $this->gitclone(); } else { @@ -113,10 +113,12 @@ class InstallCommand extends GravCommand */ private function gitclone(): int { - $this->output->writeln(''); - $this->output->writeln('Cloning Bits'); - $this->output->writeln('============'); - $this->output->writeln(''); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Cloning Bits'); + $io->writeln('============'); + $io->newLine(); $error = 0; $this->destination = rtrim($this->destination, DS); @@ -126,16 +128,16 @@ class InstallCommand extends GravCommand exec('cd "' . $this->destination . '" && git clone -b ' . $data['branch'] . ' --depth 1 ' . $data['url'] . ' ' . $data['path'], $output, $return); if (!$return) { - $this->output->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); + $io->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); } else { - $this->output->writeln('ERROR cloning ' . $data['url']); + $io->writeln('ERROR cloning ' . $data['url']); $error = 1; } - $this->output->writeln(''); + $io->newLine(); } else { - $this->output->writeln('' . $path . ' already exists, skipping...'); - $this->output->writeln(''); + $io->writeln('' . $path . ' already exists, skipping...'); + $io->newLine(); } } @@ -149,14 +151,16 @@ class InstallCommand extends GravCommand */ private function symlink(): int { - $this->output->writeln(''); - $this->output->writeln('Symlinking Bits'); - $this->output->writeln('==============='); - $this->output->writeln(''); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Symlinking Bits'); + $io->writeln('==============='); + $io->newLine(); if (!$this->local_config) { - $this->output->writeln('No local configuration available, aborting...'); - $this->output->writeln(''); + $io->writeln('No local configuration available, aborting...'); + $io->newLine(); return 1; } @@ -168,8 +172,8 @@ class InstallCommand extends GravCommand $src = $data['src'] ?? null; $path = $data['path'] ?? null; if (!isset($scm, $src, $path)) { - $this->output->writeln("Dependency '$name' has broken configuration, skipping..."); - $this->output->writeln(''); + $io->writeln("Dependency '$name' has broken configuration, skipping..."); + $io->newLine(); $error = 1; continue; @@ -188,20 +192,20 @@ class InstallCommand extends GravCommand } if (is_link($to) && !is_file("{$to}/{$name}.yaml")) { - $this->output->writeln('Removed broken symlink '. $path .''); + $io->writeln('Removed broken symlink '. $path .''); unlink($to); } if (null === $from) { - $this->output->writeln('source for ' . $src . ' does not exists, skipping...'); - $this->output->writeln(''); + $io->writeln('source for ' . $src . ' does not exists, skipping...'); + $io->newLine(); $error = 1; } elseif (!file_exists($to)) { symlink($from, $to); - $this->output->writeln('SUCCESS symlinked ' . $src . ' -> ' . $path . ''); - $this->output->writeln(''); + $io->writeln('SUCCESS symlinked ' . $src . ' -> ' . $path . ''); + $io->newLine(); } else { - $this->output->writeln('destination: ' . $path . ' already exists, skipping...'); - $this->output->writeln(''); + $io->writeln('destination: ' . $path . ' already exists, skipping...'); + $io->newLine(); } } diff --git a/system/src/Grav/Console/Cli/LogViewerCommand.php b/system/src/Grav/Console/Cli/LogViewerCommand.php index f25737f16..7eecbc20c 100644 --- a/system/src/Grav/Console/Cli/LogViewerCommand.php +++ b/system/src/Grav/Console/Cli/LogViewerCommand.php @@ -14,7 +14,6 @@ use Grav\Common\Grav; use Grav\Common\Helpers\LogViewer; use Grav\Console\GravCommand; use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Style\SymfonyStyle; /** * Class LogViewerCommand @@ -50,11 +49,12 @@ class LogViewerCommand extends GravCommand */ protected function serve(): int { - $file = $this->input->getOption('file') ?? 'grav.log'; - $lines = $this->input->getOption('lines') ?? 20; - $verbose = $this->input->getOption('verbose') ?? false; + $input = $this->getInput(); + $io = $this->getIO(); - $io = new SymfonyStyle($this->input, $this->output); + $file = $input->getOption('file') ?? 'grav.log'; + $lines = $input->getOption('lines') ?? 20; + $verbose = $input->getOption('verbose') ?? false; $io->title('Log Viewer'); diff --git a/system/src/Grav/Console/Cli/NewProjectCommand.php b/system/src/Grav/Console/Cli/NewProjectCommand.php index a9007c462..d8ba08ce4 100644 --- a/system/src/Grav/Console/Cli/NewProjectCommand.php +++ b/system/src/Grav/Console/Cli/NewProjectCommand.php @@ -48,6 +48,8 @@ class NewProjectCommand extends GravCommand */ protected function serve(): int { + $io = $this->getIO(); + $sandboxCommand = $this->getApplication()->find('sandbox'); $installCommand = $this->getApplication()->find('install'); @@ -63,9 +65,9 @@ class NewProjectCommand extends GravCommand '-s' => $this->input->getOption('symlink') ]); - $error = $sandboxCommand->run($sandboxArguments, $this->output); + $error = $sandboxCommand->run($sandboxArguments, $io); if ($error === 0) { - $error = $installCommand->run($installArguments, $this->output); + $error = $installCommand->run($installArguments, $io); } return $error; diff --git a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php index a408da243..06abbbdf3 100644 --- a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php +++ b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php @@ -149,10 +149,13 @@ class PageSystemValidatorCommand extends GravCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + $this->setLanguage('en'); $this->initializePages(); - $this->output->writeln(''); + $io->newLine(); $this->grav = $grav = Grav::instance(); @@ -161,27 +164,27 @@ class PageSystemValidatorCommand extends GravCommand /** @var Config $config */ $config = $grav['config']; - if ($this->input->getOption('record')) { - $this->output->writeln('Pages: ' . $config->get('system.pages.type', 'page')); + if ($input->getOption('record')) { + $io->writeln('Pages: ' . $config->get('system.pages.type', 'page')); - $this->output->writeln('Record tests'); - $this->output->writeln(''); + $io->writeln('Record tests'); + $io->newLine(); $results = $this->record(); $file = $this->getFile('pages-old'); $file->save($results); - $this->output->writeln('Recorded tests to ' . $file->filename()); - } elseif ($this->input->getOption('check')) { - $this->output->writeln('Pages: ' . $config->get('system.pages.type', 'page')); + $io->writeln('Recorded tests to ' . $file->filename()); + } elseif ($input->getOption('check')) { + $io->writeln('Pages: ' . $config->get('system.pages.type', 'page')); - $this->output->writeln('Run tests'); - $this->output->writeln(''); + $io->writeln('Run tests'); + $io->newLine(); $new = $this->record(); $file = $this->getFile('pages-new'); $file->save($new); - $this->output->writeln('Recorded tests to ' . $file->filename()); + $io->writeln('Recorded tests to ' . $file->filename()); $file = $this->getFile('pages-old'); $old = $file->content(); @@ -189,11 +192,11 @@ class PageSystemValidatorCommand extends GravCommand $results = $this->check($old, $new); $file = $this->getFile('diff'); $file->save($results); - $this->output->writeln('Recorded results to ' . $file->filename()); + $io->writeln('Recorded results to ' . $file->filename()); } else { - $this->output->writeln('page-system-validator [-r|--record] [-c|--check]'); + $io->writeln('page-system-validator [-r|--record] [-c|--check]'); } - $this->output->writeln(''); + $io->newLine(); return 0; } @@ -201,8 +204,10 @@ class PageSystemValidatorCommand extends GravCommand /** * @return array */ - private function record() + private function record(): array { + $io = $this->getIO(); + /** @var Pages $pages */ $pages = $this->grav['pages']; $all = $pages->all(); @@ -211,7 +216,7 @@ class PageSystemValidatorCommand extends GravCommand $results[''] = $this->recordRow($pages->root()); foreach ($all as $path => $page) { if (null === $page) { - $this->output->writeln('Error on page ' . $path . ''); + $io->writeln('Error on page ' . $path . ''); continue; } @@ -225,7 +230,7 @@ class PageSystemValidatorCommand extends GravCommand * @param PageInterface $page * @return array */ - private function recordRow(PageInterface $page) + private function recordRow(PageInterface $page): array { $results = []; @@ -287,7 +292,7 @@ class PageSystemValidatorCommand extends GravCommand * @param string $name * @return CompiledYamlFile */ - private function getFile(string $name) + private function getFile(string $name): CompiledYamlFile { return CompiledYamlFile::instance('cache://tests/' . $name . '.yaml'); } diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 7824c956d..356e3dc05 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -100,7 +100,9 @@ class SandboxCommand extends GravCommand */ protected function serve(): int { - $this->destination = $this->input->getArgument('destination'); + $input = $this->getInput(); + + $this->destination = $input->getArgument('destination'); // Create Some core stuff if it doesn't exist $error = $this->createDirectories(); @@ -109,7 +111,7 @@ class SandboxCommand extends GravCommand } // Copy files or create symlinks - $error = $this->input->getOption('symlink') ? $this->symlink() : $this->copy(); + $error = $input->getOption('symlink') ? $this->symlink() : $this->copy(); if ($error) { return $error; } @@ -137,8 +139,10 @@ class SandboxCommand extends GravCommand */ private function createDirectories(): int { - $this->output->writeln(''); - $this->output->writeln('Creating Directories'); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Creating Directories'); $dirs_created = false; if (!file_exists($this->destination)) { @@ -148,13 +152,13 @@ class SandboxCommand extends GravCommand foreach ($this->directories as $dir) { if (!file_exists($this->destination . $dir)) { $dirs_created = true; - $this->output->writeln(' ' . $dir . ''); + $io->writeln(' ' . $dir . ''); Folder::create($this->destination . $dir); } } if (!$dirs_created) { - $this->output->writeln(' Directories already exist'); + $io->writeln(' Directories already exist'); } return 0; @@ -165,8 +169,10 @@ class SandboxCommand extends GravCommand */ private function copy(): int { - $this->output->writeln(''); - $this->output->writeln('Copying Files'); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Copying Files'); foreach ($this->mappings as $source => $target) { @@ -177,7 +183,7 @@ class SandboxCommand extends GravCommand $from = $this->source . $source; $to = $this->destination . $target; - $this->output->writeln(' ' . $source . ' -> ' . $to); + $io->writeln(' ' . $source . ' -> ' . $to); @Folder::rcopy($from, $to); } @@ -189,8 +195,10 @@ class SandboxCommand extends GravCommand */ private function symlink(): int { - $this->output->writeln(''); - $this->output->writeln('Resetting Symbolic Links'); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Resetting Symbolic Links'); foreach ($this->mappings as $source => $target) { @@ -201,7 +209,7 @@ class SandboxCommand extends GravCommand $from = $this->source . $source; $to = $this->destination . $target; - $this->output->writeln(' ' . $source . ' -> ' . $to); + $io->writeln(' ' . $source . ' -> ' . $to); if (is_dir($to)) { @Folder::delete($to); @@ -219,8 +227,10 @@ class SandboxCommand extends GravCommand */ private function pages(): int { - $this->output->writeln(''); - $this->output->writeln('Pages Initializing'); + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Pages Initializing'); // get pages files and initialize if no pages exist $pages_dir = $this->destination . '/user/pages'; @@ -229,7 +239,7 @@ class SandboxCommand extends GravCommand if (count($pages_files) === 0) { $destination = $this->source . '/user/pages'; Folder::rcopy($destination, $pages_dir); - $this->output->writeln(' ' . $destination . ' -> Created'); + $io->writeln(' ' . $destination . ' -> Created'); } return 0; @@ -244,8 +254,9 @@ class SandboxCommand extends GravCommand return 1; } - $this->output->writeln(''); - $this->output->writeln('File Initializing'); + $io = $this->getIO(); + $io->newLine(); + $io->writeln('File Initializing'); $files_init = false; // Copy files if they do not exist @@ -260,12 +271,12 @@ class SandboxCommand extends GravCommand if (!file_exists($to)) { $files_init = true; copy($from, $to); - $this->output->writeln(' ' . $target . ' -> Created'); + $io->writeln(' ' . $target . ' -> Created'); } } if (!$files_init) { - $this->output->writeln(' Files already exist'); + $io->writeln(' Files already exist'); } return 0; @@ -276,8 +287,9 @@ class SandboxCommand extends GravCommand */ private function perms(): int { - $this->output->writeln(''); - $this->output->writeln('Permissions Initializing'); + $io = $this->getIO(); + $io->newLine(); + $io->writeln('Permissions Initializing'); $dir_perms = 0755; @@ -285,10 +297,10 @@ class SandboxCommand extends GravCommand foreach ($binaries as $bin) { chmod($bin, $dir_perms); - $this->output->writeln(' bin/' . basename($bin) . ' permissions reset to ' . decoct($dir_perms)); + $io->writeln(' bin/' . basename($bin) . ' permissions reset to ' . decoct($dir_perms)); } - $this->output->writeln(""); + $io->newLine(); return 0; } @@ -299,29 +311,30 @@ class SandboxCommand extends GravCommand private function check(): bool { $success = true; + $io = $this->getIO(); if (!file_exists($this->destination)) { - $this->output->writeln(' file: ' . $this->destination . ' does not exist!'); + $io->writeln(' file: ' . $this->destination . ' does not exist!'); $success = false; } foreach ($this->directories as $dir) { if (!file_exists($this->destination . $dir)) { - $this->output->writeln(' directory: ' . $dir . ' does not exist!'); + $io->writeln(' directory: ' . $dir . ' does not exist!'); $success = false; } } foreach ($this->mappings as $target => $link) { if (!file_exists($this->destination . $target)) { - $this->output->writeln(' mappings: ' . $target . ' does not exist!'); + $io->writeln(' mappings: ' . $target . ' does not exist!'); $success = false; } } if (!$success) { - $this->output->writeln(''); - $this->output->writeln('install should be run with --symlink|--s to symlink first'); + $io->newLine(); + $io->writeln('install should be run with --symlink|--s to symlink first'); } return $success; diff --git a/system/src/Grav/Console/Cli/SchedulerCommand.php b/system/src/Grav/Console/Cli/SchedulerCommand.php index a969e80de..394096300 100644 --- a/system/src/Grav/Console/Cli/SchedulerCommand.php +++ b/system/src/Grav/Console/Cli/SchedulerCommand.php @@ -17,7 +17,6 @@ use Grav\Console\GravCommand; use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Style\SymfonyStyle; use function is_null; /** @@ -77,17 +76,18 @@ class SchedulerCommand extends GravCommand $this->setHelp('foo'); - $io = new SymfonyStyle($this->input, $this->output); + $input = $this->getInput(); + $io = $this->getIO(); $error = 0; - if ($this->input->getOption('jobs')) { + if ($input->getOption('jobs')) { // Show jobs list $jobs = $scheduler->getAllJobs(); $job_states = (array)$scheduler->getJobStates()->content(); $rows = []; - $table = new Table($this->output); + $table = new Table($io); $table->setStyle('box'); $headers = ['Job ID', 'Command', 'Run At', 'Status', 'Last Run', 'State']; @@ -121,13 +121,13 @@ class SchedulerCommand extends GravCommand $io->newLine(); $io->note('For error details run "bin/grav scheduler -d"'); $io->newLine(); - } elseif ($this->input->getOption('details')) { + } elseif ($input->getOption('details')) { $jobs = $scheduler->getAllJobs(); $job_states = (array)$scheduler->getJobStates()->content(); $io->title('Job Details'); - $table = new Table($this->output); + $table = new Table($io); $table->setStyle('box'); $table->setHeaders(['Job ID', 'Last Run', 'Next Run', 'Errors']); $rows = []; @@ -159,7 +159,7 @@ class SchedulerCommand extends GravCommand $table->setRows($rows); $table->render(); - } elseif ($jobid = $this->input->getOption('run')) { + } elseif ($jobid = $input->getOption('run')) { $io->title('Force Run Job: ' . $jobid); $job = $scheduler->getJob($jobid); @@ -177,13 +177,13 @@ class SchedulerCommand extends GravCommand $output = $job->getOutput(); if ($output) { - $this->output->write($output); + $io->write($output); } } else { $error = 1; $io->error('Could not find a job with id: ' . $jobid); } - } elseif ($this->input->getOption('install')) { + } elseif ($input->getOption('install')) { $io->title('Install Scheduler'); $verb = 'install'; @@ -208,7 +208,7 @@ class SchedulerCommand extends GravCommand // Run scheduler $scheduler->run(); - if ($this->input->getOption('verbose')) { + if ($input->getOption('verbose')) { $io->title('Running Scheduled Jobs'); $io->text($scheduler->getVerboseOutput()); } diff --git a/system/src/Grav/Console/Cli/SecurityCommand.php b/system/src/Grav/Console/Cli/SecurityCommand.php index f60dd225f..fcf200a7b 100644 --- a/system/src/Grav/Console/Cli/SecurityCommand.php +++ b/system/src/Grav/Console/Cli/SecurityCommand.php @@ -13,7 +13,6 @@ use Grav\Common\Grav; use Grav\Common\Security; use Grav\Console\GravCommand; use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Style\SymfonyStyle; use function count; /** @@ -43,19 +42,19 @@ class SecurityCommand extends GravCommand { $this->initializePages(); + $io = $this->getIO(); + /** @var Grav $grav */ $grav = Grav::instance(); - $this->progress = new ProgressBar($this->output, count($grav['pages']->routes()) - 1); + $this->progress = $io->createProgressBar(count($grav['pages']->routes()) - 1); $this->progress->setFormat('Scanning %current% pages [%bar%] %percent:3s%% %elapsed:6s%'); $this->progress->setBarWidth(100); - $io = new SymfonyStyle($this->input, $this->output); $io->title('Grav Security Check'); + $io->newline(2); $output = Security::detectXssFromPages($grav['pages'], false, [$this, 'outputProgress']); - $io->newline(2); - $error = 0; if (!empty($output)) { $counter = 1; @@ -82,7 +81,7 @@ class SecurityCommand extends GravCommand * @param array $args * @return void */ - public function outputProgress($args): void + public function outputProgress(array $args): void { switch ($args['type']) { case 'count': diff --git a/system/src/Grav/Console/Cli/ServerCommand.php b/system/src/Grav/Console/Cli/ServerCommand.php index 1d59fded2..80bbe2a8b 100644 --- a/system/src/Grav/Console/Cli/ServerCommand.php +++ b/system/src/Grav/Console/Cli/ServerCommand.php @@ -12,7 +12,6 @@ namespace Grav\Console\Cli; use Grav\Common\Utils; use Grav\Console\GravCommand; use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; @@ -29,8 +28,6 @@ class ServerCommand extends GravCommand protected $ip; /** @var int */ protected $port; - /** @var SymfonyStyle */ - protected $io; /** * @return void @@ -51,7 +48,8 @@ class ServerCommand extends GravCommand */ protected function serve(): int { - $io = $this->io = new SymfonyStyle($this->input, $this->output); + $input = $this->getInput(); + $io = $this->getIO(); $io->title('Grav Web Server'); @@ -59,15 +57,15 @@ class ServerCommand extends GravCommand ini_set('cli_server.color', 'on'); // Options - $force_symfony = $this->input->getOption('symfony'); - $force_php = $this->input->getOption('php'); + $force_symfony = $input->getOption('symfony'); + $force_php = $input->getOption('php'); // Find PHP $executableFinder = new PhpExecutableFinder(); $php = $executableFinder->find(false); $this->ip = '127.0.0.1'; - $this->port = (int)($this->input->getOption('port') ?? 8000); + $this->port = (int)($input->getOption('port') ?? 8000); // Get an open port while (!$this->portAvailable($this->ip, $this->port)) { @@ -92,16 +90,12 @@ class ServerCommand extends GravCommand $error = 0; foreach ($commands as $name => $command) { $process = $this->runProcess($name, $command); - if (!$process) { $io->note('Starting ' . $name . '...'); } // Should only get here if there's an error running - if (!$process->isRunning() && ( - ($name === self::SYMFONY_SERVER && $force_symfony) || - ($name === self::PHP_SERVER) - )) { + if (!$process->isRunning() && (($name === self::SYMFONY_SERVER && $force_symfony) || ($name === self::PHP_SERVER))) { $error = 1; $io->error('Could not start ' . $name); } @@ -115,23 +109,25 @@ class ServerCommand extends GravCommand * @param array $cmd * @return Process */ - protected function runProcess($name, $cmd) + protected function runProcess(string $name, array $cmd): Process { + $io = $this->getIO(); + $process = new Process($cmd); $process->setTimeout(0); $process->start(); if ($name === self::SYMFONY_SERVER && Utils::contains($process->getErrorOutput(), 'symfony: not found')) { - $this->io->error('The symfony binary could not be found, please install the CLI tools: https://symfony.com/download'); - $this->io->warning('Falling back to PHP web server...'); + $io->error('The symfony binary could not be found, please install the CLI tools: https://symfony.com/download'); + $io->warning('Falling back to PHP web server...'); } if ($name === self::PHP_SERVER) { - $this->io->success('Built-in PHP web server listening on http://' . $this->ip . ':' . $this->port . ' (PHP v' . PHP_VERSION . ')'); + $io->success('Built-in PHP web server listening on http://' . $this->ip . ':' . $this->port . ' (PHP v' . PHP_VERSION . ')'); } $process->wait(function ($type, $buffer) { - $this->output->write($buffer); + $this->getIO()->write($buffer); }); return $process; @@ -144,7 +140,7 @@ class ServerCommand extends GravCommand * @param int $port * @return bool */ - protected function portAvailable($ip, $port): bool + protected function portAvailable(string $ip, int $port): bool { $fp = @fsockopen($ip, $port, $errno, $errstr, 0.1); if (!$fp) { diff --git a/system/src/Grav/Console/Cli/YamlLinterCommand.php b/system/src/Grav/Console/Cli/YamlLinterCommand.php index 66f4cc173..db6e573ed 100644 --- a/system/src/Grav/Console/Cli/YamlLinterCommand.php +++ b/system/src/Grav/Console/Cli/YamlLinterCommand.php @@ -48,12 +48,13 @@ class YamlLinterCommand extends GravCommand */ protected function serve(): int { - $io = new SymfonyStyle($this->input, $this->output); + $input = $this->getInput(); + $io = $this->getIO(); $io->title('Yaml Linter'); $error = 0; - if ($this->input->getOption('all')) { + if ($input->getOption('all')) { $io->section('All'); $errors = YamlLinter::lint(''); @@ -63,7 +64,7 @@ class YamlLinterCommand extends GravCommand $error = 1; $this->displayErrors($errors, $io); } - } elseif ($folder = $this->input->getOption('folder')) { + } elseif ($folder = $input->getOption('folder')) { $io->section($folder); $errors = YamlLinter::lint($folder); @@ -113,7 +114,7 @@ class YamlLinterCommand extends GravCommand * @param SymfonyStyle $io * @return void */ - protected function displayErrors($errors, SymfonyStyle $io): void + protected function displayErrors(array $errors, SymfonyStyle $io): void { $io->error('YAML Linting issues found...'); foreach ($errors as $path => $error) { diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index 479c6909d..6c796321c 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -24,8 +24,7 @@ class ConsoleCommand extends Command /** * @param InputInterface $input * @param OutputInterface $output - * - * @return int|null|void + * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php index cab4dd8ad..4c239e912 100644 --- a/system/src/Grav/Console/ConsoleTrait.php +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -19,10 +19,10 @@ use Grav\Console\Cli\ClearCacheCommand; use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\File\YamlFile; use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; /** * Trait ConsoleTrait @@ -32,9 +32,9 @@ trait ConsoleTrait { /** @var string */ protected $argv; - /* @var InputInterface $output */ + /** @var InputInterface */ protected $input; - /* @var OutputInterface $output */ + /** @var SymfonyStyle */ protected $output; /** @var array */ protected $local_config; @@ -57,19 +57,24 @@ trait ConsoleTrait { $this->argv = $_SERVER['argv'][0]; $this->input = $input; - $this->output = $output; - - $this->output->getFormatter()->setStyle('normal', new OutputFormatterStyle('white')); - $this->output->getFormatter()->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); - $this->output->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); - $this->output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); - $this->output->getFormatter()->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); - $this->output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); - $this->output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); + $this->output = new SymfonyStyle($input, $output); $this->setupGrav(); } + public function getInput(): InputInterface + { + return $this->input; + } + + /** + * @return SymfonyStyle + */ + public function getIO(): SymfonyStyle + { + return $this->output; + } + /** * Adds an option. * @@ -78,10 +83,8 @@ trait ConsoleTrait * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants * @param string $description A description text * @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE) - * - * @throws InvalidArgumentException If option mode is invalid or incompatible - * * @return $this + * @throws InvalidArgumentException If option mode is invalid or incompatible */ public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) { @@ -92,6 +95,9 @@ trait ConsoleTrait return $this; } + /** + * @return void + */ final protected function setupGrav(): void { try { @@ -246,27 +252,29 @@ trait ConsoleTrait */ public function isGravInstance($path) { + $io = $this->getIO(); + if (!file_exists($path)) { - $this->output->writeln(''); - $this->output->writeln("ERROR: Destination doesn't exist:"); - $this->output->writeln(" $path"); - $this->output->writeln(''); + $io->writeln(''); + $io->writeln("ERROR: Destination doesn't exist:"); + $io->writeln(" $path"); + $io->writeln(''); exit; } if (!is_dir($path)) { - $this->output->writeln(''); - $this->output->writeln("ERROR: Destination chosen to install is not a directory:"); - $this->output->writeln(" $path"); - $this->output->writeln(''); + $io->writeln(''); + $io->writeln("ERROR: Destination chosen to install is not a directory:"); + $io->writeln(" $path"); + $io->writeln(''); exit; } if (!file_exists($path . DS . 'index.php') || !file_exists($path . DS . '.dependencies') || !file_exists($path . DS . 'system' . DS . 'config' . DS . 'system.yaml')) { - $this->output->writeln(''); - $this->output->writeln('ERROR: Destination chosen to install does not appear to be a Grav instance:'); - $this->output->writeln(" $path"); - $this->output->writeln(''); + $io->writeln(''); + $io->writeln('ERROR: Destination chosen to install does not appear to be a Grav instance:'); + $io->writeln(" $path"); + $io->writeln(''); exit; } } diff --git a/system/src/Grav/Console/Gpm/DirectInstallCommand.php b/system/src/Grav/Console/Gpm/DirectInstallCommand.php index 82ae29b86..44838d8c1 100644 --- a/system/src/Grav/Console/Gpm/DirectInstallCommand.php +++ b/system/src/Grav/Console/Gpm/DirectInstallCommand.php @@ -21,7 +21,6 @@ use RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; use ZipArchive; use function is_array; use function is_callable; @@ -34,7 +33,6 @@ class DirectInstallCommand extends GpmCommand { /** @var string */ protected $all_yes; - /** @var string */ protected $destination; @@ -73,8 +71,9 @@ class DirectInstallCommand extends GpmCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); if (!class_exists(ZipArchive::class)) { - $io = new SymfonyStyle($this->input, $this->output); $io->title('Direct Install'); $io->error('php-zip extension needs to be enabled!'); @@ -82,28 +81,27 @@ class DirectInstallCommand extends GpmCommand } // Making sure the destination is usable - $this->destination = realpath($this->input->getOption('destination')); + $this->destination = realpath($input->getOption('destination')); if (!Installer::isGravInstance($this->destination) || !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) ) { - $this->output->writeln('ERROR: ' . Installer::lastErrorMsg()); + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); return 1; } - $this->all_yes = $this->input->getOption('all-yes'); + $this->all_yes = $input->getOption('all-yes'); - $package_file = $this->input->getArgument('package-file'); + $package_file = $input->getArgument('package-file'); - $helper = $this->getHelper('question'); $question = new ConfirmationQuestion("Are you sure you want to direct-install {$package_file} [y|N] ", false); - $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if (!$answer) { - $this->output->writeln('exiting...'); - $this->output->writeln(''); + $io->writeln('exiting...'); + $io->newLine(); return 1; } @@ -111,61 +109,61 @@ class DirectInstallCommand extends GpmCommand $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $tmp_zip = $tmp_dir . '/Grav-' . uniqid(); - $this->output->writeln(''); - $this->output->writeln("Preparing to install {$package_file}"); + $io->newLine(); + $io->writeln("Preparing to install {$package_file}"); if (Response::isRemote($package_file)) { - $this->output->write(' |- Downloading package... 0%'); + $io->write(' |- Downloading package... 0%'); try { $zip = GPM::downloadPackage($package_file, $tmp_zip); } catch (RuntimeException $e) { - $this->output->writeln(''); - $this->output->writeln(" `- ERROR: {$e->getMessage()}"); - $this->output->writeln(''); + $io->newLine(); + $io->writeln(" `- ERROR: {$e->getMessage()}"); + $io->newLine(); return 1; } if ($zip) { - $this->output->write("\x0D"); - $this->output->write(' |- Downloading package... 100%'); - $this->output->writeln(''); + $io->write("\x0D"); + $io->write(' |- Downloading package... 100%'); + $io->newLine(); } } else { - $this->output->write(' |- Copying package... 0%'); + $io->write(' |- Copying package... 0%'); $zip = GPM::copyPackage($package_file, $tmp_zip); if ($zip) { - $this->output->write("\x0D"); - $this->output->write(' |- Copying package... 100%'); - $this->output->writeln(''); + $io->write("\x0D"); + $io->write(' |- Copying package... 100%'); + $io->newLine(); } } if (file_exists($zip)) { $tmp_source = $tmp_dir . '/Grav-' . uniqid(); - $this->output->write(' |- Extracting package... '); + $io->write(' |- Extracting package... '); $extracted = Installer::unZip($zip, $tmp_source); if (!$extracted) { - $this->output->write("\x0D"); - $this->output->writeln(' |- Extracting package... failed'); + $io->write("\x0D"); + $io->writeln(' |- Extracting package... failed'); Folder::delete($tmp_source); Folder::delete($tmp_zip); return 1; } - $this->output->write("\x0D"); - $this->output->writeln(' |- Extracting package... ok'); + $io->write("\x0D"); + $io->writeln(' |- Extracting package... ok'); $type = GPM::getPackageType($extracted); if (!$type) { - $this->output->writeln(" '- ERROR: Not a valid Grav package"); - $this->output->writeln(''); + $io->writeln(" '- ERROR: Not a valid Grav package"); + $io->newLine(); Folder::delete($tmp_source); Folder::delete($tmp_zip); @@ -188,14 +186,14 @@ class DirectInstallCommand extends GpmCommand $dependencies[] = $dependency; } } - $this->output->writeln(' |- Dependencies found... [' . implode(',', $dependencies) . ']'); + $io->writeln(' |- Dependencies found... [' . implode(',', $dependencies) . ']'); $question = new ConfirmationQuestion(" | '- Dependencies will not be satisfied. Continue ? [y|N] ", false); - $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if (!$answer) { - $this->output->writeln('exiting...'); - $this->output->writeln(''); + $io->writeln('exiting...'); + $io->newLine(); Folder::delete($tmp_source); Folder::delete($tmp_zip); @@ -205,31 +203,31 @@ class DirectInstallCommand extends GpmCommand } if ($type === 'grav') { - $this->output->write(' |- Checking destination... '); + $io->write(' |- Checking destination... '); Installer::isValidDestination(GRAV_ROOT . '/system'); if (Installer::IS_LINK === Installer::lastErrorCode()) { - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... symbolic link'); - $this->output->writeln(" '- ERROR: symlinks found... " . GRAV_ROOT . ''); - $this->output->writeln(''); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + $io->writeln(" '- ERROR: symlinks found... " . GRAV_ROOT . ''); + $io->newLine(); Folder::delete($tmp_source); Folder::delete($tmp_zip); return 1; } - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... ok'); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); - $this->output->write(' |- Installing package... '); + $io->write(' |- Installing package... '); $this->upgradeGrav($zip, $extracted); } else { $name = GPM::getPackageName($extracted); if (!$name) { - $this->output->writeln('ERROR: Name could not be determined. Please specify with --name|-n'); - $this->output->writeln(''); + $io->writeln('ERROR: Name could not be determined. Please specify with --name|-n'); + $io->newLine(); Folder::delete($tmp_source); Folder::delete($tmp_zip); @@ -239,24 +237,24 @@ class DirectInstallCommand extends GpmCommand $install_path = GPM::getInstallPath($type, $name); $is_update = file_exists($install_path); - $this->output->write(' |- Checking destination... '); + $io->write(' |- Checking destination... '); Installer::isValidDestination(GRAV_ROOT . DS . $install_path); if (Installer::lastErrorCode() === Installer::IS_LINK) { - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... symbolic link'); - $this->output->writeln(" '- ERROR: symlink found... " . GRAV_ROOT . DS . $install_path . ''); - $this->output->writeln(''); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + $io->writeln(" '- ERROR: symlink found... " . GRAV_ROOT . DS . $install_path . ''); + $io->newLine(); Folder::delete($tmp_source); Folder::delete($tmp_zip); return 1; } - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... ok'); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); - $this->output->write(' |- Installing package... '); + $io->write(' |- Installing package... '); Installer::install( $zip, @@ -272,18 +270,18 @@ class DirectInstallCommand extends GpmCommand Folder::delete($tmp_source); - $this->output->write("\x0D"); + $io->write("\x0D"); if (Installer::lastErrorCode()) { - $this->output->writeln(" '- " . Installer::lastErrorMsg() . ''); - $this->output->writeln(''); + $io->writeln(" '- " . Installer::lastErrorMsg() . ''); + $io->newLine(); } else { - $this->output->writeln(' |- Installing package... ok'); - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); + $io->writeln(' |- Installing package... ok'); + $io->writeln(" '- Success! "); + $io->newLine(); } } else { - $this->output->writeln(" '- ERROR: ZIP package could not be found"); + $io->writeln(" '- ERROR: ZIP package could not be found"); Folder::delete($tmp_zip); return 1; @@ -300,9 +298,10 @@ class DirectInstallCommand extends GpmCommand /** * @param string $zip * @param string $folder - * @param false $keepFolder + * @param bool $keepFolder + * @return void */ - private function upgradeGrav($zip, $folder, $keepFolder = false) + private function upgradeGrav(string $zip, string $folder, bool $keepFolder = false): void { static $ignores = [ 'backup', diff --git a/system/src/Grav/Console/Gpm/IndexCommand.php b/system/src/Grav/Console/Gpm/IndexCommand.php index 1f0f86d45..4404cec9c 100644 --- a/system/src/Grav/Console/Gpm/IndexCommand.php +++ b/system/src/Grav/Console/Gpm/IndexCommand.php @@ -27,10 +27,8 @@ class IndexCommand extends GpmCommand { /** @var Packages */ protected $data; - /** @var GPM */ protected $gpm; - /** @var array */ protected $options; @@ -100,20 +98,21 @@ class IndexCommand extends GpmCommand */ protected function serve(): int { - $this->options = $this->input->getOptions(); + $input = $this->getInput(); + $this->options = $input->getOptions(); $this->gpm = new GPM($this->options['force']); $this->displayGPMRelease(); $this->data = $this->gpm->getRepository(); $data = $this->filter($this->data); - $io = new SymfonyStyle($this->input, $this->output); + $io = $this->getIO(); if (count($data) === 0) { $io->writeln('No data was found in the GPM repository stored locally.'); $io->writeln('Please try clearing cache and running the bin/gpm index -f command again'); $io->writeln('If this doesn\'t work try tweaking your GPM system settings.'); - $io->writeln(''); + $io->newLine(); $io->writeln('For more help go to:'); $io->writeln(' -> https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm'); @@ -126,8 +125,8 @@ class IndexCommand extends GpmCommand $packages = $this->sort($packages); if (!empty($packages)) { - $section = $this->output->section('Packages table'); - $table = new Table($section); + $io->section('Packages table'); + $table = new Table($io); $table->setHeaders(['Count', 'Name', 'Slug', 'Version', 'Installed']); $index = 0; @@ -146,25 +145,24 @@ class IndexCommand extends GpmCommand $table->render(); } - $io->writeln(''); + $io->newLine(); } $io->writeln('You can either get more informations about a package by typing:'); $io->writeln(" {$this->argv} info "); - $io->writeln(''); + $io->newLine(); $io->writeln('Or you can install a package by typing:'); $io->writeln(" {$this->argv} install "); - $io->writeln(''); + $io->newLine(); return 0; } /** * @param Package $package - * * @return string */ - private function version($package) + private function version(Package $package): string { $list = $this->gpm->{'getUpdatable' . ucfirst($package->package_type)}(); $package = $list[$package->slug] ?? $package; @@ -178,19 +176,14 @@ class IndexCommand extends GpmCommand return "v{$version}"; } - if ($updatable) { - return "v{$package->version} -> v{$package->available}"; - } - - return ''; + return "v{$package->version} -> v{$package->available}"; } /** * @param Package $package - * * @return string */ - private function installed($package) + private function installed(Package $package): string { $package = $list[$package->slug] ?? $package; $type = ucfirst(preg_replace('/s$/', '', $package->package_type)); @@ -202,10 +195,9 @@ class IndexCommand extends GpmCommand /** * @param Packages $data - * * @return Packages */ - public function filter($data) + public function filter(Packages $data): Packages { // filtering and sorting if ($this->options['plugins-only']) { @@ -260,14 +252,13 @@ class IndexCommand extends GpmCommand * @param Packages $packages * @return Packages */ - public function sort($packages) + public function sort(Packages $packages): Packages { foreach ($this->options['sort'] as $key) { $packages = $packages->sort(function ($a, $b) use ($key) { switch ($key) { case 'author': return strcmp($a->{$key}['name'], $b->{$key}['name']); - break; default: return strcmp($a->$key, $b->$key); } diff --git a/system/src/Grav/Console/Gpm/InfoCommand.php b/system/src/Grav/Console/Gpm/InfoCommand.php index 3fc282243..d7b9e9419 100644 --- a/system/src/Grav/Console/Gpm/InfoCommand.php +++ b/system/src/Grav/Console/Gpm/InfoCommand.php @@ -24,10 +24,8 @@ class InfoCommand extends GpmCommand { /** @var array */ protected $data; - /** @var GPM */ protected $gpm; - /** @var string */ protected $all_yes; @@ -64,37 +62,40 @@ class InfoCommand extends GpmCommand */ protected function serve(): int { - $this->gpm = new GPM($this->input->getOption('force')); + $input = $this->getInput(); + $io = $this->getIO(); - $this->all_yes = $this->input->getOption('all-yes'); + $this->gpm = new GPM($input->getOption('force')); + + $this->all_yes = $input->getOption('all-yes'); $this->displayGPMRelease(); - $foundPackage = $this->gpm->findPackage($this->input->getArgument('package')); + $foundPackage = $this->gpm->findPackage($input->getArgument('package')); if (!$foundPackage) { - $this->output->writeln("The package '{$this->input->getArgument('package')}' was not found in the Grav repository."); - $this->output->writeln(''); - $this->output->writeln('You can list all the available packages by typing:'); - $this->output->writeln(" {$this->argv} index"); - $this->output->writeln(''); + $io->writeln("The package '{$input->getArgument('package')}' was not found in the Grav repository."); + $io->newLine(); + $io->writeln('You can list all the available packages by typing:'); + $io->writeln(" {$this->argv} index"); + $io->newLine(); return 1; } - $this->output->writeln("Found package '{$this->input->getArgument('package')}' under the '" . ucfirst($foundPackage->package_type) . "' section"); - $this->output->writeln(''); - $this->output->writeln("{$foundPackage->name} [{$foundPackage->slug}]"); - $this->output->writeln(str_repeat('-', strlen($foundPackage->name) + strlen($foundPackage->slug) + 3)); - $this->output->writeln('' . strip_tags($foundPackage->description_plain) . ''); - $this->output->writeln(''); + $io->writeln("Found package '{$input->getArgument('package')}' under the '" . ucfirst($foundPackage->package_type) . "' section"); + $io->newLine(); + $io->writeln("{$foundPackage->name} [{$foundPackage->slug}]"); + $io->writeln(str_repeat('-', strlen($foundPackage->name) + strlen($foundPackage->slug) + 3)); + $io->writeln('' . strip_tags($foundPackage->description_plain) . ''); + $io->newLine(); $packageURL = ''; if (isset($foundPackage->author['url'])) { $packageURL = '<' . $foundPackage->author['url'] . '>'; } - $this->output->writeln('' . str_pad( + $io->writeln('' . str_pad( 'Author', 12 ) . ': ' . $foundPackage->author['name'] . ' <' . $foundPackage->author['email'] . '> ' . $packageURL); @@ -126,7 +127,7 @@ class InfoCommand extends GpmCommand } $name = str_pad($name, 12); - $this->output->writeln("{$name}: {$data}"); + $io->writeln("{$name}: {$data}"); } } @@ -137,54 +138,53 @@ class InfoCommand extends GpmCommand // display current version if installed and different if ($installed && $updatable) { $local = $this->gpm->{'getInstalled'. $type}($foundPackage->slug); - $this->output->writeln(''); - $this->output->writeln("Currently installed version: {$local->version}"); - $this->output->writeln(''); + $io->newLine(); + $io->writeln("Currently installed version: {$local->version}"); + $io->newLine(); } // display changelog information - $questionHelper = $this->getHelper('question'); $question = new ConfirmationQuestion( 'Would you like to read the changelog? [y|N] ', false ); - $answer = $this->all_yes ? true : $questionHelper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if ($answer) { $changelog = $foundPackage->changelog; - $this->output->writeln(''); + $io->newLine(); foreach ($changelog as $version => $log) { $title = $version . ' [' . $log['date'] . ']'; $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { return "\n" . ucfirst($match[1]) . ':'; }, $log['content']); - $this->output->writeln("{$title}"); - $this->output->writeln(str_repeat('-', strlen($title))); - $this->output->writeln($content); - $this->output->writeln(''); + $io->writeln("{$title}"); + $io->writeln(str_repeat('-', strlen($title))); + $io->writeln($content); + $io->newLine(); $question = new ConfirmationQuestion('Press [ENTER] to continue or [q] to quit ', true); - $answer = $this->all_yes ? false : $questionHelper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? false : $io->askQuestion($question); if (!$answer) { break; } - $this->output->writeln(''); + $io->newLine(); } } - $this->output->writeln(''); + $io->newLine(); if ($installed && $updatable) { - $this->output->writeln('You can update this package by typing:'); - $this->output->writeln(" {$this->argv} update {$foundPackage->slug}"); + $io->writeln('You can update this package by typing:'); + $io->writeln(" {$this->argv} update {$foundPackage->slug}"); } else { - $this->output->writeln("You can install this package by typing:"); - $this->output->writeln(" {$this->argv} install {$foundPackage->slug}"); + $io->writeln('You can install this package by typing:'); + $io->writeln(" {$this->argv} install {$foundPackage->slug}"); } - $this->output->writeln(''); + $io->newLine(); return 0; } diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 3590fa670..706013ea5 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -22,12 +22,12 @@ use Grav\Console\GpmCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; use ZipArchive; use function array_key_exists; use function count; +use function define; -\define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/'); +define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/'); /** * Class InstallCommand @@ -37,25 +37,18 @@ class InstallCommand extends GpmCommand { /** @var array */ protected $data; - /** @var GPM */ protected $gpm; - /** @var string */ protected $destination; - /** @var string */ protected $file; - /** @var string */ protected $tmp; - /** @var bool */ protected $use_symlinks; - /** @var array */ protected $demo_processing = []; - /** @var string */ protected $all_yes; @@ -99,7 +92,7 @@ class InstallCommand extends GpmCommand * * @param GPM $gpm */ - public function setGpm(GPM $gpm) + public function setGpm(GPM $gpm): void { $this->gpm = $gpm; } @@ -109,45 +102,47 @@ class InstallCommand extends GpmCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + if (!class_exists(ZipArchive::class)) { - $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Install'); $io->error('php-zip extension needs to be enabled!'); return 1; } - $this->gpm = new GPM($this->input->getOption('force')); + $this->gpm = new GPM($input->getOption('force')); - $this->all_yes = $this->input->getOption('all-yes'); + $this->all_yes = $input->getOption('all-yes'); $this->displayGPMRelease(); - $this->destination = realpath($this->input->getOption('destination')); + $this->destination = realpath($input->getOption('destination')); - $packages = array_map('strtolower', $this->input->getArgument('package')); + $packages = array_map('strtolower', $input->getArgument('package')); $this->data = $this->gpm->findPackages($packages); $this->loadLocalConfig(); if (!Installer::isGravInstance($this->destination) || !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) ) { - $this->output->writeln('ERROR: ' . Installer::lastErrorMsg()); + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); return 1; } - $this->output->writeln(''); + $io->newLine(); if (!$this->data['total']) { - $this->output->writeln('Nothing to install.'); - $this->output->writeln(''); + $io->writeln('Nothing to install.'); + $io->newLine(); return 0; } if (count($this->data['not_found'])) { - $this->output->writeln('These packages were not found on Grav: ' . implode( + $io->writeln('These packages were not found on Grav: ' . implode( ', ', array_keys($this->data['not_found']) ) . ''); @@ -158,24 +153,23 @@ class InstallCommand extends GpmCommand if (null !== $this->local_config) { // Symlinks available, ask if Grav should use them $this->use_symlinks = false; - $helper = $this->getHelper('question'); $question = new ConfirmationQuestion('Should Grav use the symlinks if available? [y|N] ', false); - $answer = $this->all_yes ? false : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? false : $io->askQuestion($question); if ($answer) { $this->use_symlinks = true; } } - $this->output->writeln(''); + $io->newLine(); try { $dependencies = $this->gpm->getDependencies($packages); } catch (Exception $e) { //Error out if there are incompatible packages requirements and tell which ones, and what to do //Error out if there is any error in parsing the dependencies and their versions, and tell which one is broken - $this->output->writeln("{$e->getMessage()}"); + $io->writeln("{$e->getMessage()}"); return 1; } @@ -186,13 +180,13 @@ class InstallCommand extends GpmCommand $this->installDependencies($dependencies, 'update', 'The following dependencies need to be updated...'); $this->installDependencies($dependencies, 'ignore', "The following dependencies can be updated as there is a newer version, but it's not mandatory...", false); } catch (Exception $e) { - $this->output->writeln('Installation aborted'); + $io->writeln('Installation aborted'); return 1; } - $this->output->writeln('Dependencies are OK'); - $this->output->writeln(''); + $io->writeln('Dependencies are OK'); + $io->newLine(); } @@ -200,7 +194,7 @@ class InstallCommand extends GpmCommand foreach ($this->data as $data) { foreach ($data as $package_name => $package) { if (array_key_exists($package_name, $dependencies)) { - $this->output->writeln("Package {$package_name} already installed as dependency"); + $io->writeln("Package {$package_name} already installed as dependency"); } else { $is_valid_destination = Installer::isValidDestination($this->destination . DS . $package->install_path); if ($is_valid_destination || Installer::lastErrorCode() == Installer::NOT_FOUND) { @@ -211,25 +205,24 @@ class InstallCommand extends GpmCommand $this->askConfirmationIfMajorVersionUpdated($package); $this->gpm->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package->slug, $package->available, array_keys($data)); } catch (Exception $e) { - $this->output->writeln("{$e->getMessage()}"); + $io->writeln("{$e->getMessage()}"); return 1; } - $helper = $this->getHelper('question'); $question = new ConfirmationQuestion("The package {$package_name} is already installed, overwrite? [y|N] ", false); - $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if ($answer) { $is_update = true; $this->processPackage($package, $is_update); } else { - $this->output->writeln("Package {$package_name} not overwritten"); + $io->writeln("Package {$package_name} not overwritten"); } } else { if (Installer::lastErrorCode() == Installer::IS_LINK) { - $this->output->writeln("Cannot overwrite existing symlink for {$package_name}"); - $this->output->writeln(''); + $io->writeln("Cannot overwrite existing symlink for {$package_name}"); + $io->newLine(); } } } @@ -255,9 +248,9 @@ class InstallCommand extends GpmCommand * @param Package $package * @return void */ - public function askConfirmationIfMajorVersionUpdated($package): void + public function askConfirmationIfMajorVersionUpdated(Package $package): void { - $helper = $this->getHelper('question'); + $io = $this->getIO(); $package_name = $package->name; $new_version = $package->available ?: $this->gpm->getLatestVersionOfPackage($package->slug); $old_version = $package->version; @@ -266,14 +259,14 @@ class InstallCommand extends GpmCommand if ($major_version_changed) { if ($this->all_yes) { - $this->output->writeln("The package {$package_name} will be updated to a new major version {$new_version}, from {$old_version}"); + $io->writeln("The package {$package_name} will be updated to a new major version {$new_version}, from {$old_version}"); return; } $question = new ConfirmationQuestion("The package {$package_name} will be updated to a new major version {$new_version}, from {$old_version}. Be sure to read what changed with the new major release. Continue? [y|N] ", false); - if (!$helper->ask($this->input, $this->output, $question)) { - $this->output->writeln("Package {$package_name} not updated"); + if (!$io->askQuestion($question)) { + $io->writeln("Package {$package_name} not updated"); exit; } } @@ -291,21 +284,20 @@ class InstallCommand extends GpmCommand * @return void * @throws Exception */ - public function installDependencies($dependencies, $type, $message, $required = true): void + public function installDependencies(array $dependencies, string $type, string $message, bool $required = true): void { + $io = $this->getIO(); $packages = array_filter($dependencies, static function ($action) use ($type) { return $action === $type; }); if (count($packages) > 0) { - $this->output->writeln($message); + $io->writeln($message); foreach ($packages as $dependencyName => $dependencyVersion) { - $this->output->writeln(" |- Package {$dependencyName}"); + $io->writeln(" |- Package {$dependencyName}"); } - $this->output->writeln(''); - - $helper = $this->getHelper('question'); + $io->newLine(); if ($type === 'install') { $questionAction = 'Install'; @@ -326,14 +318,14 @@ class InstallCommand extends GpmCommand } $question = new ConfirmationQuestion("${questionAction} {$questionArticle} {$questionNoun}? [Y|n] ", true); - $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if ($answer) { foreach ($packages as $dependencyName => $dependencyVersion) { $package = $this->gpm->findPackage($dependencyName); $this->processPackage($package, $type === 'update'); } - $this->output->writeln(''); + $io->newLine(); } elseif ($required) { throw new Exception(); } @@ -345,11 +337,13 @@ class InstallCommand extends GpmCommand * @param bool $is_update True if the package is an update * @return void */ - private function processPackage($package, $is_update = false): void + private function processPackage(?Package $package, bool $is_update = false): void { + $io = $this->getIO(); + if (!$package) { - $this->output->writeln('Package not found on the GPM!'); - $this->output->writeln(''); + $io->writeln('Package not found on the GPM!'); + $io->newLine(); return; } @@ -371,7 +365,7 @@ class InstallCommand extends GpmCommand * @param Package $package * @return void */ - private function processDemo($package): void + private function processDemo(Package $package): void { $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; if (file_exists($demo_dir)) { @@ -385,8 +379,9 @@ class InstallCommand extends GpmCommand * @param Package $package * @return void */ - private function installDemoContent($package): void + private function installDemoContent(Package $package): void { + $io = $this->getIO(); $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; if (file_exists($demo_dir)) { @@ -394,15 +389,15 @@ class InstallCommand extends GpmCommand $pages_dir = $dest_dir . DS . 'pages'; // Demo content exists, prompt to install it. - $this->output->writeln("Attention: {$package->name} contains demo content"); - $helper = $this->getHelper('question'); + $io->writeln("Attention: {$package->name} contains demo content"); + $question = new ConfirmationQuestion('Do you wish to install this demo content? [y|N] ', false); - $answer = $helper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln(" '- Skipped! "); - $this->output->writeln(''); + $io->writeln(" '- Skipped! "); + $io->newLine(); return; } @@ -411,11 +406,11 @@ class InstallCommand extends GpmCommand if (file_exists($demo_dir . DS . 'pages')) { $pages_backup = 'pages.' . date('m-d-Y-H-i-s'); $question = new ConfirmationQuestion('This will backup your current `user/pages` folder to `user/' . $pages_backup . '`, continue? [y|N]', false); - $answer = $this->all_yes ? true : $helper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if (!$answer) { - $this->output->writeln(" '- Skipped! "); - $this->output->writeln(''); + $io->writeln(" '- Skipped! "); + $io->newLine(); return; } @@ -423,18 +418,18 @@ class InstallCommand extends GpmCommand // backup current pages folder if (file_exists($dest_dir)) { if (rename($pages_dir, $dest_dir . DS . $pages_backup)) { - $this->output->writeln(' |- Backing up pages... ok'); + $io->writeln(' |- Backing up pages... ok'); } else { - $this->output->writeln(' |- Backing up pages... failed'); + $io->writeln(' |- Backing up pages... failed'); } } } // Confirmation received, copy over the data - $this->output->writeln(' |- Installing demo content... ok '); + $io->writeln(' |- Installing demo content... ok '); Folder::rcopy($demo_dir, $dest_dir); - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); + $io->writeln(" '- Success! "); + $io->newLine(); } } @@ -442,7 +437,7 @@ class InstallCommand extends GpmCommand * @param Package $package * @return array|false */ - private function getGitRegexMatches($package) + private function getGitRegexMatches(Package $package) { if (isset($package->repository)) { $repository = $package->repository; @@ -459,7 +454,7 @@ class InstallCommand extends GpmCommand * @param Package $package * @return string|false */ - private function getSymlinkSource($package) + private function getSymlinkSource(Package $package) { $matches = $this->getGitRegexMatches($package); @@ -483,84 +478,88 @@ class InstallCommand extends GpmCommand } /** - * @param Package $package + * @param Package $package * @return void */ - private function processSymlink($package): void + private function processSymlink(Package $package): void { + $io = $this->getIO(); + exec('cd ' . $this->destination); $to = $this->destination . DS . $package->install_path; $from = $this->getSymlinkSource($package); - $this->output->writeln("Preparing to Symlink {$package->name}"); - $this->output->write(' |- Checking source... '); + $io->writeln("Preparing to Symlink {$package->name}"); + $io->write(' |- Checking source... '); if (file_exists($from)) { - $this->output->writeln('ok'); + $io->writeln('ok'); - $this->output->write(' |- Checking destination... '); + $io->write(' |- Checking destination... '); $checks = $this->checkDestination($package); if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); } elseif (file_exists($to)) { - $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); - $this->output->writeln(''); + $io->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); + $io->newLine(); } else { symlink($from, $to); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Symlinking package... ok '); - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); + $io->writeln(' |- Symlinking package... ok '); + $io->writeln(" '- Success! "); + $io->newLine(); } return; } - $this->output->writeln('not found!'); - $this->output->writeln(" '- Installation failed or aborted."); + $io->writeln('not found!'); + $io->writeln(" '- Installation failed or aborted."); } /** - * @param Package $package - * @param bool $is_update + * @param Package $package + * @param bool $is_update * @return bool */ - private function processGpm($package, $is_update = false) + private function processGpm(Package $package, bool $is_update = false) { + $io = $this->getIO(); + $version = $package->available ?? $package->version; $license = Licenses::get($package->slug); - $this->output->writeln("Preparing to install {$package->name} [v{$version}]"); + $io->writeln("Preparing to install {$package->name} [v{$version}]"); - $this->output->write(' |- Downloading package... 0%'); + $io->write(' |- Downloading package... 0%'); $this->file = $this->downloadPackage($package, $license); if (!$this->file) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); return false; } - $this->output->write(' |- Checking destination... '); + $io->write(' |- Checking destination... '); $checks = $this->checkDestination($package); if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); } else { - $this->output->write(' |- Installing package... '); + $io->write(' |- Installing package... '); $installation = $this->installPackage($package, $is_update); if (!$installation) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); } else { - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); + $io->writeln(" '- Success! "); + $io->newLine(); return true; } @@ -571,11 +570,13 @@ class InstallCommand extends GpmCommand /** * @param Package $package - * @param string|null $license + * @param string|null $license * @return string|null */ - private function downloadPackage($package, $license = null) + private function downloadPackage(Package $package, string $license = null) { + $io = $this->getIO(); + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $this->tmp = $tmp_dir . '/Grav-' . uniqid(); $filename = $package->slug . basename($package->zipball_url); @@ -600,19 +601,19 @@ class InstallCommand extends GpmCommand $output = Response::get($package->zipball_url . $query, [], [$this, 'progress']); } catch (Exception $e) { $error = str_replace("\n", "\n | '- ", $e->getMessage()); - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Downloading package... error '); - $this->output->writeln(" | '- " . $error); + $io->writeln(' |- Downloading package... error '); + $io->writeln(" | '- " . $error); return null; } Folder::create($this->tmp); - $this->output->write("\x0D"); - $this->output->write(' |- Downloading package... 100%'); - $this->output->writeln(''); + $io->write("\x0D"); + $io->write(' |- Downloading package... 100%'); + $io->newLine(); file_put_contents($this->tmp . DS . $filename, $output); @@ -620,21 +621,21 @@ class InstallCommand extends GpmCommand } /** - * @param Package $package + * @param Package $package * @return bool */ - private function checkDestination($package): bool + private function checkDestination(Package $package): bool { - $question_helper = $this->getHelper('question'); + $io = $this->getIO(); Installer::isValidDestination($this->destination . DS . $package->install_path); if (Installer::lastErrorCode() === Installer::IS_LINK) { - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... symbolic link'); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); if ($this->all_yes) { - $this->output->writeln(" | '- Skipped automatically."); + $io->writeln(" | '- Skipped automatically."); return false; } @@ -643,10 +644,10 @@ class InstallCommand extends GpmCommand " | '- Destination has been detected as symlink, delete symbolic link first? [y|N] ", false ); - $answer = $question_helper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln(" | '- You decided to not delete the symlink automatically."); + $io->writeln(" | '- You decided to not delete the symlink automatically."); return false; } @@ -654,8 +655,8 @@ class InstallCommand extends GpmCommand unlink($this->destination . DS . $package->install_path); } - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... ok'); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); return true; } @@ -664,11 +665,13 @@ class InstallCommand extends GpmCommand * Install a package * * @param Package $package - * @param bool $is_update True if it's an update. False if it's an install + * @param bool $is_update True if it's an update. False if it's an install * @return bool */ - private function installPackage($package, $is_update = false) + private function installPackage(Package $package, bool $is_update = false): bool { + $io = $this->getIO(); + $type = $package->package_type; Installer::install($this->file, $this->destination, ['install_path' => $package->install_path, 'theme' => $type === 'themes', 'is_update' => $is_update]); @@ -676,24 +679,24 @@ class InstallCommand extends GpmCommand Folder::delete($this->tmp); if ($error_code) { - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Installing package... error '); - $this->output->writeln(" | '- " . Installer::lastErrorMsg()); + $io->writeln(' |- Installing package... error '); + $io->writeln(" | '- " . Installer::lastErrorMsg()); return false; } $message = Installer::getMessage(); if ($message) { - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(" |- {$message}"); + $io->writeln(" |- {$message}"); } - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Installing package... ok '); + $io->writeln(' |- Installing package... ok '); return true; } @@ -702,10 +705,12 @@ class InstallCommand extends GpmCommand * @param array $progress * @return void */ - public function progress($progress): void + public function progress(array $progress): void { - $this->output->write("\x0D"); - $this->output->write(' |- Downloading package... ' . str_pad( + $io = $this->getIO(); + + $io->write("\x0D"); + $io->write(' |- Downloading package... ' . str_pad( $progress['percent'], 5, ' ', diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 9268b0bf2..2b253ce17 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -20,7 +20,6 @@ use Grav\Console\GpmCommand; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; use ZipArchive; use function is_callable; use function strlen; @@ -33,25 +32,19 @@ class SelfupgradeCommand extends GpmCommand { /** @var array */ protected $data; - /** @var string */ protected $file; - /** @var array */ protected $types = ['plugins', 'themes']; - /** @var string */ private $tmp; - /** @var Upgrader */ private $upgrader; /** @var string */ protected $all_yes; - /** @var string */ protected $overwrite; - /** @var int */ protected $timeout; @@ -97,18 +90,20 @@ class SelfupgradeCommand extends GpmCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + if (!class_exists(ZipArchive::class)) { - $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Self Upgrade'); $io->error('php-zip extension needs to be enabled!'); return 1; } - $this->upgrader = new Upgrader($this->input->getOption('force')); - $this->all_yes = $this->input->getOption('all-yes'); - $this->overwrite = $this->input->getOption('overwrite'); - $this->timeout = (int) $this->input->getOption('timeout'); + $this->upgrader = new Upgrader($input->getOption('force')); + $this->all_yes = $input->getOption('all-yes'); + $this->overwrite = $input->getOption('overwrite'); + $this->timeout = (int) $input->getOption('timeout'); $this->displayGPMRelease(); @@ -119,28 +114,28 @@ class SelfupgradeCommand extends GpmCommand $release = strftime('%c', strtotime($this->upgrader->getReleaseDate())); if (!$this->upgrader->meetsRequirements()) { - $this->output->writeln('ATTENTION:'); - $this->output->writeln(' Grav has increased the minimum PHP requirement.'); - $this->output->writeln(' You are currently running PHP ' . phpversion() . ', but PHP ' . $this->upgrader->minPHPVersion() . ' is required.'); - $this->output->writeln(' Additional information: http://getgrav.org/blog/changing-php-requirements'); - $this->output->writeln(''); - $this->output->writeln('Selfupgrade aborted.'); - $this->output->writeln(''); + $io->writeln('ATTENTION:'); + $io->writeln(' Grav has increased the minimum PHP requirement.'); + $io->writeln(' You are currently running PHP ' . phpversion() . ', but PHP ' . $this->upgrader->minPHPVersion() . ' is required.'); + $io->writeln(' Additional information: http://getgrav.org/blog/changing-php-requirements'); + $io->newLine(); + $io->writeln('Selfupgrade aborted.'); + $io->newLine(); return 1; } if (!$this->overwrite && !$this->upgrader->isUpgradable()) { - $this->output->writeln("You are already running the latest version of Grav (v{$local}) released on {$release}"); + $io->writeln("You are already running the latest version of Grav (v{$local}) released on {$release}"); return 0; } Installer::isValidDestination(GRAV_ROOT . '/system'); if (Installer::IS_LINK === Installer::lastErrorCode()) { - $this->output->writeln('ATTENTION: Grav is symlinked, cannot upgrade, aborting...'); - $this->output->writeln(''); - $this->output->writeln("You are currently running a symbolically linked Grav v{$local}. Latest available is v{$remote}."); + $io->writeln('ATTENTION: Grav is symlinked, cannot upgrade, aborting...'); + $io->newLine(); + $io->writeln("You are currently running a symbolically linked Grav v{$local}. Latest available is v{$remote}."); return 1; } @@ -148,65 +143,63 @@ class SelfupgradeCommand extends GpmCommand // not used but preloaded just in case! new ArrayInput([]); - $questionHelper = $this->getHelper('question'); - - $this->output->writeln("Grav v{$remote} is now available [release date: {$release}]."); - $this->output->writeln('You are currently using v' . GRAV_VERSION . '.'); + $io->writeln("Grav v{$remote} is now available [release date: {$release}]."); + $io->writeln('You are currently using v' . GRAV_VERSION . '.'); if (!$this->all_yes) { $question = new ConfirmationQuestion( 'Would you like to read the changelog before proceeding? [y|N] ', false ); - $answer = $questionHelper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if ($answer) { $changelog = $this->upgrader->getChangelog(GRAV_VERSION); - $this->output->writeln(''); + $io->newLine(); foreach ($changelog as $version => $log) { $title = $version . ' [' . $log['date'] . ']'; $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { return "\n" . ucfirst($match[1]) . ':'; }, $log['content']); - $this->output->writeln($title); - $this->output->writeln(str_repeat('-', strlen($title))); - $this->output->writeln($content); - $this->output->writeln(''); + $io->writeln($title); + $io->writeln(str_repeat('-', strlen($title))); + $io->writeln($content); + $io->newLine(); } $question = new ConfirmationQuestion('Press [ENTER] to continue.', true); - $questionHelper->ask($this->input, $this->output, $question); + $io->askQuestion($question); } $question = new ConfirmationQuestion('Would you like to upgrade now? [y|N] ', false); - $answer = $questionHelper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln('Aborting...'); + $io->writeln('Aborting...'); return 1; } } - $this->output->writeln(''); - $this->output->writeln("Preparing to upgrade to v{$remote}.."); + $io->newLine(); + $io->writeln("Preparing to upgrade to v{$remote}.."); - $this->output->write(" |- Downloading upgrade [{$this->formatBytes($update['size'])}]... 0%"); + $io->write(" |- Downloading upgrade [{$this->formatBytes($update['size'])}]... 0%"); $this->file = $this->download($update); - $this->output->write(' |- Installing upgrade... '); + $io->write(' |- Installing upgrade... '); $installation = $this->upgrade(); $error = 0; if (!$installation) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); $error = 1; } else { - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); + $io->writeln(" '- Success! "); + $io->newLine(); } // clear cache after successful upgrade @@ -219,8 +212,10 @@ class SelfupgradeCommand extends GpmCommand * @param array $package * @return string */ - private function download($package) + private function download(array $package): string { + $io = $this->getIO(); + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $this->tmp = $tmp_dir . '/Grav-' . uniqid('', false); $options = [ @@ -236,9 +231,9 @@ class SelfupgradeCommand extends GpmCommand Folder::create($this->tmp); - $this->output->write("\x0D"); - $this->output->write(" |- Downloading upgrade [{$this->formatBytes($package['size'])}]... 100%"); - $this->output->writeln(''); + $io->write("\x0D"); + $io->write(" |- Downloading upgrade [{$this->formatBytes($package['size'])}]... 100%"); + $io->newLine(); file_put_contents($this->tmp . DS . $package['name'], $output); @@ -248,8 +243,10 @@ class SelfupgradeCommand extends GpmCommand /** * @return bool */ - private function upgrade() + private function upgrade(): bool { + $io = $this->getIO(); + if ($this->file) { $folder = Installer::unZip($this->file, $this->tmp . '/zip'); } else { @@ -265,17 +262,17 @@ class SelfupgradeCommand extends GpmCommand } if ($errorCode & (Installer::ZIP_OPEN_ERROR | Installer::ZIP_EXTRACT_ERROR)) { - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Installing upgrade... error '); - $this->output->writeln(" | '- " . Installer::lastErrorMsg()); + $io->writeln(' |- Installing upgrade... error '); + $io->writeln(" | '- " . Installer::lastErrorMsg()); return false; } - $this->output->write("\x0D"); + $io->write("\x0D"); // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Installing upgrade... ok '); + $io->writeln(' |- Installing upgrade... ok '); return true; } @@ -284,10 +281,12 @@ class SelfupgradeCommand extends GpmCommand * @param array $progress * @return void */ - public function progress($progress): void + public function progress(array $progress): void { - $this->output->write("\x0D"); - $this->output->write(" |- Downloading upgrade [{$this->formatBytes($progress['filesize']) }]... " . str_pad( + $io = $this->getIO(); + + $io->write("\x0D"); + $io->write(" |- Downloading upgrade [{$this->formatBytes($progress['filesize']) }]... " . str_pad( $progress['percent'], 5, ' ', @@ -300,7 +299,7 @@ class SelfupgradeCommand extends GpmCommand * @param int $precision * @return string */ - public function formatBytes($size, $precision = 2) + public function formatBytes($size, int $precision = 2): string { $base = log($size) / log(1024); $suffixes = array('', 'k', 'M', 'G', 'T'); @@ -311,9 +310,10 @@ class SelfupgradeCommand extends GpmCommand /** * @param string $zip * @param string $folder - * @param false $keepFolder + * @param bool $keepFolder + * @return void */ - private function upgradeGrav($zip, $folder, $keepFolder = false) + private function upgradeGrav(string $zip, string $folder, bool $keepFolder = false): void { static $ignores = [ 'backup', diff --git a/system/src/Grav/Console/Gpm/UninstallCommand.php b/system/src/Grav/Console/Gpm/UninstallCommand.php index 1413521ed..6c88376c5 100644 --- a/system/src/Grav/Console/Gpm/UninstallCommand.php +++ b/system/src/Grav/Console/Gpm/UninstallCommand.php @@ -29,22 +29,16 @@ class UninstallCommand extends GpmCommand { /** @var array */ protected $data; - /** @var GPM */ protected $gpm; - /** @var string */ protected $destination; - /** @var string */ protected $file; - /** @var string */ protected $tmp; - /** @var array */ protected $dependencies = []; - /** @var string */ protected $all_yes; @@ -75,11 +69,14 @@ class UninstallCommand extends GpmCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + $this->gpm = new GPM(); - $this->all_yes = $this->input->getOption('all-yes'); + $this->all_yes = $input->getOption('all-yes'); - $packages = array_map('strtolower', $this->input->getArgument('package')); + $packages = array_map('strtolower', $input->getArgument('package')); $this->data = ['total' => 0, 'not_found' => []]; $total = 0; @@ -95,17 +92,17 @@ class UninstallCommand extends GpmCommand } $this->data['total'] = $total; - $this->output->writeln(''); + $io->newLine(); if (!$this->data['total']) { - $this->output->writeln('Nothing to uninstall.'); - $this->output->writeln(''); + $io->writeln('Nothing to uninstall.'); + $io->newLine(); return 0; } if (count($this->data['not_found'])) { - $this->output->writeln('These packages were not found installed: ' . implode( + $io->writeln('These packages were not found installed: ' . implode( ', ', $this->data['not_found'] ) . ''); @@ -115,23 +112,23 @@ class UninstallCommand extends GpmCommand $error = 0; foreach ($this->data as $slug => $package) { - $this->output->writeln("Preparing to uninstall {$package->name} [v{$package->version}]"); + $io->writeln("Preparing to uninstall {$package->name} [v{$package->version}]"); - $this->output->write(' |- Checking destination... '); + $io->write(' |- Checking destination... '); $checks = $this->checkDestination($slug, $package); if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); $error = 1; } else { $uninstall = $this->uninstallPackage($slug, $package); if (!$uninstall) { - $this->output->writeln(" '- Uninstallation failed or aborted."); + $io->writeln(" '- Uninstallation failed or aborted."); $error = 1; } else { - $this->output->writeln(" '- Success! "); + $io->writeln(" '- Success! "); } } } @@ -145,10 +142,13 @@ class UninstallCommand extends GpmCommand /** * @param string $slug * @param Package $package + * @param bool $is_dependency * @return bool */ - private function uninstallPackage($slug, $package, $is_dependency = false) + private function uninstallPackage($slug, $package, $is_dependency = false): bool { + $io = $this->getIO(); + if (!$slug) { return false; } @@ -156,17 +156,16 @@ class UninstallCommand extends GpmCommand //check if there are packages that have this as a dependency. Abort and show list $dependent_packages = $this->gpm->getPackagesThatDependOnPackage($slug); if (count($dependent_packages) > ($is_dependency ? 1 : 0)) { - $this->output->writeln(''); - $this->output->writeln(''); - $this->output->writeln('Uninstallation failed.'); - $this->output->writeln(''); + $io->newLine(2); + $io->writeln('Uninstallation failed.'); + $io->newLine(); if (count($dependent_packages) > ($is_dependency ? 2 : 1)) { - $this->output->writeln('The installed packages ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove those first.'); + $io->writeln('The installed packages ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove those first.'); } else { - $this->output->writeln('The installed package ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove it first.'); + $io->writeln('The installed package ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove it first.'); } - $this->output->writeln(''); + $io->newLine(); return false; } @@ -180,12 +179,10 @@ class UninstallCommand extends GpmCommand } } } elseif (count($dependencies) > 0) { - $this->output->writeln(' `- Dependencies found...'); - $this->output->writeln(''); + $io->writeln(' `- Dependencies found...'); + $io->newLine(); } - $questionHelper = $this->getHelper('question'); - foreach ($dependencies as $dependency) { $this->dependencies[] = $dependency['name']; @@ -201,23 +198,23 @@ class UninstallCommand extends GpmCommand $dependency_exists = $this->packageExists($dependency, $dependencyPackage); if ($dependency_exists == Installer::EXISTS) { - $this->output->writeln("A dependency on {$dependencyPackage->name} [v{$dependencyPackage->version}] was found"); + $io->writeln("A dependency on {$dependencyPackage->name} [v{$dependencyPackage->version}] was found"); $question = new ConfirmationQuestion(" |- Uninstall {$dependencyPackage->name}? [y|N] ", false); - $answer = $this->all_yes ? true : $questionHelper->ask($this->input, $this->output, $question); + $answer = $this->all_yes ? true : $io->askQuestion($question); if ($answer) { $uninstall = $this->uninstallPackage($dependency, $dependencyPackage, true); if (!$uninstall) { - $this->output->writeln(" '- Uninstallation failed or aborted."); + $io->writeln(" '- Uninstallation failed or aborted."); } else { - $this->output->writeln(" '- Success! "); + $io->writeln(" '- Success! "); } - $this->output->writeln(''); + $io->newLine(); } else { - $this->output->writeln(" '- You decided not to uninstall {$dependencyPackage->name}."); - $this->output->writeln(''); + $io->writeln(" '- You decided not to uninstall {$dependencyPackage->name}."); + $io->newLine(); } } } @@ -230,23 +227,21 @@ class UninstallCommand extends GpmCommand $errorCode = Installer::lastErrorCode(); if ($errorCode && $errorCode !== Installer::IS_LINK && $errorCode !== Installer::EXISTS) { - $this->output->writeln(" |- Uninstalling {$package->name} package... error "); - $this->output->writeln(" | '- " . Installer::lastErrorMsg() . ''); + $io->writeln(" |- Uninstalling {$package->name} package... error "); + $io->writeln(" | '- " . Installer::lastErrorMsg() . ''); return false; } $message = Installer::getMessage(); if ($message) { - $this->output->writeln(" |- {$message}"); + $io->writeln(" |- {$message}"); } if (!$is_dependency && $this->dependencies) { - $this->output->writeln("Finishing up uninstalling {$package->name}"); + $io->writeln("Finishing up uninstalling {$package->name}"); } - $this->output->writeln(" |- Uninstalling {$package->name} package... ok "); - - + $io->writeln(" |- Uninstalling {$package->name} package... ok "); return true; } @@ -256,18 +251,18 @@ class UninstallCommand extends GpmCommand * @param Package $package * @return bool */ - private function checkDestination($slug, $package) + private function checkDestination(string $slug, Package $package): bool { - $questionHelper = $this->getHelper('question'); + $io = $this->getIO(); $exists = $this->packageExists($slug, $package); - if ($exists == Installer::IS_LINK) { - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... symbolic link'); + if ($exists === Installer::IS_LINK) { + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); if ($this->all_yes) { - $this->output->writeln(" | '- Skipped automatically."); + $io->writeln(" | '- Skipped automatically."); return false; } @@ -276,17 +271,17 @@ class UninstallCommand extends GpmCommand " | '- Destination has been detected as symlink, delete symbolic link first? [y|N] ", false ); - $answer = $this->all_yes ? true : $questionHelper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln(" | '- You decided not to delete the symlink automatically."); + $io->writeln(" | '- You decided not to delete the symlink automatically."); return false; } } - $this->output->write("\x0D"); - $this->output->writeln(' |- Checking destination... ok'); + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); return true; } @@ -298,7 +293,7 @@ class UninstallCommand extends GpmCommand * @param Package $package * @return int */ - private function packageExists($slug, $package) + private function packageExists(string $slug, Package $package): int { $path = Grav::instance()['locator']->findResource($package->package_type . '://' . $slug); Installer::isValidDestination($path); diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php index 3b0b570f5..d5e90a8ee 100644 --- a/system/src/Grav/Console/Gpm/UpdateCommand.php +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -17,7 +17,6 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; use ZipArchive; use function array_key_exists; use function count; @@ -30,25 +29,18 @@ class UpdateCommand extends GpmCommand { /** @var array */ protected $data; - /** @var string */ protected $destination; - /** @var string */ protected $file; - /** @var array */ protected $types = ['plugins', 'themes']; - /** @var GPM */ protected $gpm; - /** @var string */ protected $all_yes; - /** @var string */ protected $overwrite; - /** @var Upgrader */ protected $upgrader; @@ -110,49 +102,50 @@ class UpdateCommand extends GpmCommand */ protected function serve(): int { + $input = $this->getInput(); + $io = $this->getIO(); + if (!class_exists(ZipArchive::class)) { - $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Update'); $io->error('php-zip extension needs to be enabled!'); return 1; } - $this->upgrader = new Upgrader($this->input->getOption('force')); + $this->upgrader = new Upgrader($input->getOption('force')); $local = $this->upgrader->getLocalVersion(); $remote = $this->upgrader->getRemoteVersion(); if ($local !== $remote) { - $this->output->writeln('WARNING: A new version of Grav is available. You should update Grav before updating plugins and themes. If you continue without updating Grav, some plugins or themes may stop working.'); - $this->output->writeln(''); - $questionHelper = $this->getHelper('question'); + $io->writeln('WARNING: A new version of Grav is available. You should update Grav before updating plugins and themes. If you continue without updating Grav, some plugins or themes may stop working.'); + $io->newLine(); $question = new ConfirmationQuestion('Continue with the update process? [Y|n] ', true); - $answer = $questionHelper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln('Update aborted. Exiting...'); + $io->writeln('Update aborted. Exiting...'); return 1; } } - $this->gpm = new GPM($this->input->getOption('force')); + $this->gpm = new GPM($input->getOption('force')); - $this->all_yes = $this->input->getOption('all-yes'); - $this->overwrite = $this->input->getOption('overwrite'); + $this->all_yes = $input->getOption('all-yes'); + $this->overwrite = $input->getOption('overwrite'); $this->displayGPMRelease(); - $this->destination = realpath($this->input->getOption('destination')); + $this->destination = realpath($input->getOption('destination')); if (!Installer::isGravInstance($this->destination)) { - $this->output->writeln('ERROR: ' . Installer::lastErrorMsg()); + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); exit; } - if ($this->input->getOption('plugins') === false && $this->input->getOption('themes') === false) { + if ($input->getOption('plugins') === false && $input->getOption('themes') === false) { $list_type = ['plugins' => true, 'themes' => true]; } else { - $list_type['plugins'] = $this->input->getOption('plugins'); - $list_type['themes'] = $this->input->getOption('themes'); + $list_type['plugins'] = $input->getOption('plugins'); + $list_type['themes'] = $input->getOption('themes'); } if ($this->overwrite) { @@ -163,19 +156,19 @@ class UpdateCommand extends GpmCommand $description = ' need updating'; } - $only_packages = array_map('strtolower', $this->input->getArgument('package')); + $only_packages = array_map('strtolower', $input->getArgument('package')); if (!$this->overwrite && !$this->data['total']) { - $this->output->writeln('Nothing to update.'); + $io->writeln('Nothing to update.'); return 0; } - $this->output->write("Found {$this->gpm->countInstalled()} packages installed of which {$this->data['total']}{$description}"); + $io->write("Found {$this->gpm->countInstalled()} packages installed of which {$this->data['total']}{$description}"); $limit_to = $this->userInputPackages($only_packages); - $this->output->writeln(''); + $io->newLine(); unset($this->data['total'], $limit_to['total']); @@ -183,7 +176,7 @@ class UpdateCommand extends GpmCommand // updates review $slugs = []; - $index = 0; + $index = 1; foreach ($this->data as $packages) { foreach ($packages as $slug => $package) { if (!array_key_exists($slug, $limit_to) && count($only_packages)) { @@ -194,9 +187,9 @@ class UpdateCommand extends GpmCommand $package->available = $package->version; } - $this->output->writeln( + $io->writeln( // index - str_pad($index++ + 1, 2, '0', STR_PAD_LEFT) . '. ' . + str_pad((string)$index++, 2, '0', STR_PAD_LEFT) . '. ' . // name '' . str_pad($package->name, 15) . ' ' . // version @@ -208,13 +201,12 @@ class UpdateCommand extends GpmCommand if (!$this->all_yes) { // prompt to continue - $this->output->writeln(''); - $questionHelper = $this->getHelper('question'); + $io->newLine(); $question = new ConfirmationQuestion('Continue with the update process? [Y|n] ', true); - $answer = $questionHelper->ask($this->input, $this->output, $question); + $answer = $io->askQuestion($question); if (!$answer) { - $this->output->writeln('Update aborted. Exiting...'); + $io->writeln('Update aborted. Exiting...'); return 1; } @@ -226,14 +218,14 @@ class UpdateCommand extends GpmCommand $args = new ArrayInput([ 'command' => 'install', 'package' => $slugs, - '-f' => $this->input->getOption('force'), + '-f' => $input->getOption('force'), '-d' => $this->destination, '-y' => true ]); - $command_exec = $install_command->run($args, $this->output); + $command_exec = $install_command->run($args, $io); if ($command_exec != 0) { - $this->output->writeln('Error: An error occurred while trying to install the packages'); + $io->writeln('Error: An error occurred while trying to install the packages'); return 1; } @@ -245,13 +237,15 @@ class UpdateCommand extends GpmCommand * @param array $only_packages * @return array */ - private function userInputPackages($only_packages) + private function userInputPackages(array $only_packages): array { + $io = $this->getIO(); + $found = ['total' => 0]; $ignore = []; if (!count($only_packages)) { - $this->output->writeln(''); + $io->newLine(); } else { foreach ($only_packages as $only_package) { $find = $this->gpm->findPackage($only_package); @@ -271,19 +265,19 @@ class UpdateCommand extends GpmCommand $list = array_keys($list); if ($found['total'] !== $this->data['total']) { - $this->output->write(", only {$found['total']} will be updated"); + $io->write(", only {$found['total']} will be updated"); } - $this->output->writeln(''); - $this->output->writeln('Limiting updates for only ' . implode( + $io->newLine(); + $io->writeln('Limiting updates for only ' . implode( ', ', $list ) . ''); } if (count($ignore)) { - $this->output->writeln(''); - $this->output->writeln('Packages not found or not requiring updates: ' . implode( + $io->newLine(); + $io->writeln('Packages not found or not requiring updates: ' . implode( ', ', $ignore ) . ''); diff --git a/system/src/Grav/Console/Gpm/VersionCommand.php b/system/src/Grav/Console/Gpm/VersionCommand.php index 07277bd5c..0880dddb8 100644 --- a/system/src/Grav/Console/Gpm/VersionCommand.php +++ b/system/src/Grav/Console/Gpm/VersionCommand.php @@ -54,8 +54,11 @@ class VersionCommand extends GpmCommand */ protected function serve(): int { - $this->gpm = new GPM($this->input->getOption('force')); - $packages = $this->input->getArgument('package'); + $input = $this->getInput(); + $io = $this->getIO(); + + $this->gpm = new GPM($input->getOption('force')); + $packages = $input->getArgument('package'); $installed = false; @@ -111,9 +114,9 @@ class VersionCommand extends GpmCommand $updatable = $updatable ?: ''; if ($installed || $package === 'grav') { - $this->output->writeln("You are running {$name} v{$version}{$updatable}"); + $io->writeln("You are running {$name} v{$version}{$updatable}"); } else { - $this->output->writeln("Package {$package} not found"); + $io->writeln("Package {$package} not found"); } } diff --git a/system/src/Grav/Console/GpmCommand.php b/system/src/Grav/Console/GpmCommand.php index 4e15ebda4..685049e0d 100644 --- a/system/src/Grav/Console/GpmCommand.php +++ b/system/src/Grav/Console/GpmCommand.php @@ -26,8 +26,7 @@ class GpmCommand extends Command /** * @param InputInterface $input * @param OutputInterface $output - * - * @return int|null|void + * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -36,6 +35,7 @@ class GpmCommand extends Command $grav = Grav::instance(); $grav['config']->init(); $grav['uri']->init(); + // @phpstan-ignore-next-line $grav['accounts']; return $this->serve(); @@ -60,8 +60,9 @@ class GpmCommand extends Command /** @var Config $config */ $config = Grav::instance()['config']; - $this->output->writeln(''); - $this->output->writeln('GPM Releases Configuration: ' . ucfirst($config->get('system.gpm.releases')) . ''); - $this->output->writeln(''); + $io = $this->getIO(); + $io->newLine(); + $io->writeln('GPM Releases Configuration: ' . ucfirst($config->get('system.gpm.releases')) . ''); + $io->newLine(); } } diff --git a/system/src/Grav/Console/GravCommand.php b/system/src/Grav/Console/GravCommand.php index bd1ef03ae..41fe61c0d 100644 --- a/system/src/Grav/Console/GravCommand.php +++ b/system/src/Grav/Console/GravCommand.php @@ -24,8 +24,7 @@ class GravCommand extends Command /** * @param InputInterface $input * @param OutputInterface $output - * - * @return int|null|void + * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { diff --git a/system/src/Grav/Console/Plugin/PluginListCommand.php b/system/src/Grav/Console/Plugin/PluginListCommand.php index 2e301290f..df8301e63 100644 --- a/system/src/Grav/Console/Plugin/PluginListCommand.php +++ b/system/src/Grav/Console/Plugin/PluginListCommand.php @@ -34,22 +34,21 @@ class PluginListCommand extends ConsoleCommand */ protected function serve(): int { - $bin = 'bin/plugin'; + $bin = $this->argv; $pattern = '([A-Z]\w+Command\.php)'; - $output = $this->output; - $output->writeln(''); - $output->writeln('Usage:'); - $output->writeln(" {$bin} [slug] [command] [arguments]"); - $output->writeln(''); - $output->writeln('Example:'); - $output->writeln(" {$bin} error log -l 1 --trace"); - - $output->writeln(''); - $output->writeln('Plugins with CLI available:'); + $io = $this->getIO(); + $io->newLine(); + $io->writeln('Usage:'); + $io->writeln(" {$bin} [slug] [command] [arguments]"); + $io->newLine(); + $io->writeln('Example:'); + $io->writeln(" {$bin} error log -l 1 --trace"); + $io->newLine(); + $io->writeln('Plugins with CLI available:'); $plugins = Plugins::all(); - $total = 0; + $index = 0; foreach ($plugins as $name => $plugin) { if (!$plugin->enabled) { continue; @@ -60,9 +59,9 @@ class PluginListCommand extends ConsoleCommand continue; } - $total++; - $index = str_pad($total, 2, '0', STR_PAD_LEFT); - $output->writeln(' ' . $index . '. ' . str_pad($name, 15) . " {$bin} {$name} list"); + $index++; + $num = str_pad((string)$index, 2, '0', STR_PAD_LEFT); + $io->writeln(' ' . $num . '. ' . str_pad($name, 15) . " {$bin} {$name} list"); } return 0; diff --git a/system/src/Grav/Console/TerminalObjects/Table.php b/system/src/Grav/Console/TerminalObjects/Table.php index 4f5123381..bf0ac5280 100644 --- a/system/src/Grav/Console/TerminalObjects/Table.php +++ b/system/src/Grav/Console/TerminalObjects/Table.php @@ -12,6 +12,7 @@ namespace Grav\Console\TerminalObjects; /** * Class Table * @package Grav\Console\TerminalObjects + * @deprecated 1.7 Use Symfony Console Table */ class Table extends \League\CLImate\TerminalObject\Basic\Table {