From 04169f028b43901245c4b98b5ed975c6cb242406 Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Fri, 30 Oct 2026 16:47:47 +0800 Subject: [PATCH] refactor: write the top-level and Encryption commands through `$this->getOutput()` --- system/Commands/Encryption/GenerateKey.php | 21 +++++------ system/Commands/Encryption/RotateKey.php | 26 ++++++------- system/Commands/Help.php | 44 +++++++++++----------- system/Commands/ListCommands.php | 32 ++++++++-------- 4 files changed, 62 insertions(+), 61 deletions(-) diff --git a/system/Commands/Encryption/GenerateKey.php b/system/Commands/Encryption/GenerateKey.php index 09af76d5ecfc..a85d5aada002 100644 --- a/system/Commands/Encryption/GenerateKey.php +++ b/system/Commands/Encryption/GenerateKey.php @@ -15,7 +15,6 @@ use CodeIgniter\CLI\AbstractCommand; use CodeIgniter\CLI\Attributes\Command; -use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\Input\Option; use CodeIgniter\Config\DotEnv; use CodeIgniter\Encryption\Encryption; @@ -81,7 +80,7 @@ protected function interact(array &$arguments, array &$options): void return; } - if (CLI::prompt('Overwrite existing key?', ['n', 'y']) === 'y') { + if ($this->getPrompt()->ask('Overwrite existing key?', ['n', 'y']) === 'y') { $options['force'] = null; // simulate the presence of the --force option } } @@ -89,9 +88,10 @@ protected function interact(array &$arguments, array &$options): void protected function execute(array $arguments, array $options): int { $prefix = $options['prefix']; + $output = $this->getOutput(); if (! in_array($prefix, self::VALID_PREFIXES, true)) { - CLI::error(sprintf('Invalid prefix "%s". Use either "hex2bin" or "base64".', $prefix)); + $output->error(sprintf('Invalid prefix "%s". Use either "hex2bin" or "base64".', $prefix)); return EXIT_ERROR; } @@ -99,7 +99,7 @@ protected function execute(array $arguments, array $options): int $encodedKey = $this->generateRandomKey($prefix, (int) $options['length']); if ($options['show'] === true) { - CLI::write($encodedKey, 'yellow'); + $output->write($encodedKey, 'yellow'); return EXIT_SUCCESS; } @@ -108,12 +108,12 @@ protected function execute(array $arguments, array $options): int if ($currentKey !== '' && $options['force'] === false) { if ($this->isInteractive()) { - CLI::write('Setting new encryption key cancelled.', 'yellow'); + $output->write('Setting new encryption key cancelled.', 'yellow'); return EXIT_SUCCESS; } - CLI::error('Setting new encryption key aborted: pass --force to overwrite the existing key in non-interactive mode.'); + $output->error('Setting new encryption key aborted: pass --force to overwrite the existing key in non-interactive mode.'); return EXIT_ERROR; } @@ -122,14 +122,14 @@ protected function execute(array $arguments, array $options): int $baseEnv = ROOTPATH . 'env'; if (! is_file($envFile) && ! is_file($baseEnv)) { - CLI::write('Both default shipped `env` file and custom `.env` are missing.', 'yellow'); - CLI::write(sprintf('Here\'s your new key instead: %s', CLI::color($encodedKey, 'yellow'))); + $output->write('Both default shipped `env` file and custom `.env` are missing.', 'yellow'); + $output->write(sprintf('Here\'s your new key instead: %s', $output->color($encodedKey, 'yellow'))); return EXIT_ERROR; } if (! $this->writeNewEncryptionKeyToFile($encodedKey, $envFile, $baseEnv)) { - CLI::error(sprintf('Failed to write new encryption key to %s.', clean_path($envFile))); + $output->error(sprintf('Failed to write new encryption key to %s.', clean_path($envFile))); return EXIT_ERROR; } @@ -141,8 +141,7 @@ protected function execute(array $arguments, array $options): int $dotenv = new DotEnv((new Paths())->envDirectory ?? ROOTPATH); // @phpstan-ignore nullCoalesce.property $dotenv->load(); - CLI::write(sprintf('New encryption key written to %s.', clean_path($envFile)), 'green'); - CLI::newLine(); + $output->write(sprintf('New encryption key written to %s.', clean_path($envFile)), 'green'); return EXIT_SUCCESS; } diff --git a/system/Commands/Encryption/RotateKey.php b/system/Commands/Encryption/RotateKey.php index 563256309801..c24faaea5f5e 100644 --- a/system/Commands/Encryption/RotateKey.php +++ b/system/Commands/Encryption/RotateKey.php @@ -15,7 +15,6 @@ use CodeIgniter\CLI\AbstractCommand; use CodeIgniter\CLI\Attributes\Command; -use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\Input\Option; use Config\Paths; @@ -81,7 +80,7 @@ protected function interact(array &$arguments, array &$options): void return; } - if (CLI::prompt('Rotate encryption key? The current key will be moved to `previousKeys`.', ['n', 'y']) === 'y') { + if ($this->getPrompt()->ask('Rotate encryption key? The current key will be moved to `previousKeys`.', ['n', 'y']) === 'y') { $options['force'] = null; // simulate the presence of the --force option } } @@ -89,9 +88,10 @@ protected function interact(array &$arguments, array &$options): void protected function execute(array $arguments, array $options): int { $prefix = $options['prefix']; + $output = $this->getOutput(); if (! in_array($prefix, self::VALID_PREFIXES, true)) { - CLI::error(sprintf('Invalid prefix "%s". Use either "hex2bin" or "base64".', $prefix)); + $output->error(sprintf('Invalid prefix "%s". Use either "hex2bin" or "base64".', $prefix)); return EXIT_ERROR; } @@ -99,19 +99,19 @@ protected function execute(array $arguments, array $options): int $currentKey = env('encryption.key', ''); if ($currentKey === '') { - CLI::error('No existing `encryption.key` to rotate. Run `spark key:generate` first.'); + $output->error('No existing `encryption.key` to rotate. Run `spark key:generate` first.'); return EXIT_ERROR; } if ($options['force'] === false) { if ($this->isInteractive()) { - CLI::write('Key rotation cancelled.', 'yellow'); + $output->write('Key rotation cancelled.', 'yellow'); return EXIT_SUCCESS; } - CLI::error('Key rotation aborted: pass --force to rotate the encryption key in non-interactive mode.'); + $output->error('Key rotation aborted: pass --force to rotate the encryption key in non-interactive mode.'); return EXIT_ERROR; } @@ -119,7 +119,7 @@ protected function execute(array $arguments, array $options): int $keep = $options['keep']; if (! is_string($keep) || ! ctype_digit($keep)) { - CLI::error('The --keep option must be a non-negative integer.'); + $output->error('The --keep option must be a non-negative integer.'); return EXIT_ERROR; } @@ -127,7 +127,7 @@ protected function execute(array $arguments, array $options): int $length = $options['length']; if (! is_string($length) || ! ctype_digit($length) || (int) $length < 1) { - CLI::error('The --length option must be a positive integer.'); + $output->error('The --length option must be a positive integer.'); return EXIT_ERROR; } @@ -140,20 +140,20 @@ protected function execute(array $arguments, array $options): int $envFile = ((new Paths())->envDirectory ?? ROOTPATH) . '.env'; // @phpstan-ignore nullCoalesce.property if (! is_file($envFile)) { - CLI::error(sprintf('Cannot rotate: `.env` file not found at %s.', clean_path($envFile))); + $output->error(sprintf('Cannot rotate: `.env` file not found at %s.', clean_path($envFile))); return EXIT_ERROR; } if (! is_writable($envFile)) { - CLI::error(sprintf('Cannot rotate: `.env` file at %s is not writable.', clean_path($envFile))); + $output->error(sprintf('Cannot rotate: `.env` file at %s is not writable.', clean_path($envFile))); return EXIT_ERROR; } if (! $this->writePreviousKeys($previousKeys, $envFile)) { // @codeCoverageIgnoreStart - CLI::error(sprintf('Failed to write `encryption.previousKeys` to %s.', clean_path($envFile))); + $output->error(sprintf('Failed to write `encryption.previousKeys` to %s.', clean_path($envFile))); return EXIT_ERROR; // @codeCoverageIgnoreEnd @@ -178,12 +178,12 @@ protected function execute(array $arguments, array $options): int $count = count($previousKeys); - CLI::write(sprintf( + $output->write(sprintf( 'Encryption key rotated. %d %s retained for decryption fallback.', $count, $count === 1 ? 'previous key' : 'previous keys', ), 'green'); - CLI::write('Re-encrypt existing data with the new key when ready.', 'yellow'); + $output->write('Re-encrypt existing data with the new key when ready.', 'yellow'); return EXIT_SUCCESS; } diff --git a/system/Commands/Help.php b/system/Commands/Help.php index c44ffee943ac..683c86fe2ec1 100644 --- a/system/Commands/Help.php +++ b/system/Commands/Help.php @@ -15,9 +15,9 @@ use CodeIgniter\CLI\AbstractCommand; use CodeIgniter\CLI\Attributes\Command; -use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\Input\Argument; use CodeIgniter\CLI\Input\Option; +use CodeIgniter\CLI\Output; /** * Displays the basic usage information for a given command. @@ -51,57 +51,57 @@ protected function execute(array $arguments, array $options): int return EXIT_ERROR; } - $this->describeHelp($commands->getCommand($command, legacy: false)); + $this->describeHelp($commands->getCommand($command, legacy: false), $this->getOutput()); return EXIT_SUCCESS; } - private function describeHelp(AbstractCommand $command): void + private function describeHelp(AbstractCommand $command, Output $output): void { - CLI::write(lang('CLI.helpUsage'), 'yellow'); + $output->write(lang('CLI.helpUsage'), 'yellow'); foreach ($command->getUsages() as $usage) { - CLI::write($this->addPadding($usage)); + $output->write($this->addPadding($usage)); } if ($command->getDescription() !== '') { - CLI::newLine(); - CLI::write(lang('CLI.helpDescription'), 'yellow'); - CLI::write($this->addPadding($command->getDescription())); + $output->newLine(); + $output->write(lang('CLI.helpDescription'), 'yellow'); + $output->write($this->addPadding($command->getDescription())); } if ($command->getAliases() !== []) { - CLI::newLine(); - CLI::write(lang('CLI.helpAliases'), 'yellow'); + $output->newLine(); + $output->write(lang('CLI.helpAliases'), 'yellow'); foreach ($command->getAliases() as $alias) { - CLI::write($this->addPadding($alias)); + $output->write($this->addPadding($alias)); } } $maxPadding = $this->getMaxPadding($command); if ($command->getArgumentsDefinition() !== []) { - CLI::newLine(); - CLI::write(lang('CLI.helpArguments'), 'yellow'); + $output->newLine(); + $output->write(lang('CLI.helpArguments'), 'yellow'); foreach ($command->getArgumentsDefinition() as $argument => $definition) { $default = ! $definition->required && $this->shouldShowDefault($definition->default) ? sprintf(' [default: %s]', $this->formatDefaultValue($definition->default)) : ''; - CLI::write(sprintf( + $output->write(sprintf( '%s%s%s', - CLI::color($this->addPadding($argument, 2, $maxPadding), 'green'), + $output->color($this->addPadding($argument, 2, $maxPadding), 'green'), $definition->description, - CLI::color($default, 'yellow'), + $output->color($default, 'yellow'), )); } } if ($command->getOptionsDefinition() !== []) { - CLI::newLine(); - CLI::write(lang('CLI.helpOptions'), 'yellow'); + $output->newLine(); + $output->write(lang('CLI.helpOptions'), 'yellow'); $hasShortcuts = $command->getShortcuts() !== []; @@ -130,12 +130,12 @@ private function describeHelp(AbstractCommand $command): void ? sprintf(' [default: %s]', $this->formatDefaultValue($definition->default)) : ''; - CLI::write(sprintf( + $output->write(sprintf( '%s%s%s%s', - CLI::color($this->addPadding($optionString, 2, $maxPadding), 'green'), + $output->color($this->addPadding($optionString, 2, $maxPadding), 'green'), $definition->description, - CLI::color($default, 'yellow'), - $definition->isArray ? CLI::color(' (multiple values allowed)', 'yellow') : '', + $output->color($default, 'yellow'), + $definition->isArray ? $output->color(' (multiple values allowed)', 'yellow') : '', )); } } diff --git a/system/Commands/ListCommands.php b/system/Commands/ListCommands.php index 84d983042701..3a36280a9780 100644 --- a/system/Commands/ListCommands.php +++ b/system/Commands/ListCommands.php @@ -15,8 +15,8 @@ use CodeIgniter\CLI\AbstractCommand; use CodeIgniter\CLI\Attributes\Command; -use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\Input\Option; +use CodeIgniter\CLI\Output; /** * Lists the available commands. @@ -34,14 +34,16 @@ protected function configure(): void protected function execute(array $arguments, array $options): int { + $output = $this->getOutput(); + if ($options['simple'] === true) { - return $this->describeCommandsSimple(); + return $this->describeCommandsSimple($output); } - return $this->describeCommandsDetailed(); + return $this->describeCommandsDetailed($output); } - private function describeCommandsSimple(): int + private function describeCommandsSimple(Output $output): int { // Legacy takes precedence on key collision so the listing reflects the // command that would actually be invoked. @@ -53,16 +55,16 @@ private function describeCommandsSimple(): int sort($commands); foreach ($commands as $command) { - CLI::write($command); + $output->write($command); } return EXIT_SUCCESS; } - private function describeCommandsDetailed(): int + private function describeCommandsDetailed(Output $output): int { - CLI::write(lang('CLI.helpUsage'), 'yellow'); - CLI::write($this->addPadding('command [options] [--] [arguments]')); + $output->write(lang('CLI.helpUsage'), 'yellow'); + $output->write($this->addPadding('command [options] [--] [arguments]')); $entries = []; $maxPad = 0; @@ -110,23 +112,23 @@ private function describeCommandsDetailed(): int $groups[$group][] = [$command, $description]; } - CLI::newLine(); - CLI::write(lang('CLI.helpAvailableCommands'), 'yellow'); + $output->newLine(); + $output->write(lang('CLI.helpAvailableCommands'), 'yellow'); $firstGroup = array_key_first($groups); foreach ($groups as $group => $commands) { if ($group !== $firstGroup) { - CLI::newLine(); + $output->newLine(); } - CLI::write($group, 'yellow'); + $output->write($group, 'yellow'); foreach ($commands as $command) { - CLI::write(sprintf( + $output->write(sprintf( '%s%s', - CLI::color($this->addPadding($command[0], 2, $maxPad), 'green'), - CLI::wrap($command[1], 0, $maxPad), + $output->color($this->addPadding($command[0], 2, $maxPad), 'green'), + $output->wrap($command[1], 0, $maxPad), )); } }