mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
234 lines
5.5 KiB
PHP
234 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* This file is part of CodeIgniter 4 framework.
|
|
*
|
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace CodeIgniter\CLI;
|
|
|
|
use Config\Exceptions;
|
|
use Psr\Log\LoggerInterface;
|
|
use ReflectionException;
|
|
use Throwable;
|
|
|
|
/**
|
|
* BaseCommand is the base class used in creating CLI commands.
|
|
*
|
|
* @property array<string, string> $arguments
|
|
* @property Commands $commands
|
|
* @property string $description
|
|
* @property string $group
|
|
* @property LoggerInterface $logger
|
|
* @property string $name
|
|
* @property array<string, string> $options
|
|
* @property string $usage
|
|
*/
|
|
abstract class BaseCommand
|
|
{
|
|
/**
|
|
* The group the command is lumped under
|
|
* when listing commands.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $group;
|
|
|
|
/**
|
|
* The Command's name
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $name;
|
|
|
|
/**
|
|
* the Command's usage description
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $usage;
|
|
|
|
/**
|
|
* the Command's short description
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description;
|
|
|
|
/**
|
|
* the Command's options description
|
|
*
|
|
* @var array<string, string>
|
|
*/
|
|
protected $options = [];
|
|
|
|
/**
|
|
* the Command's Arguments description
|
|
*
|
|
* @var array<string, string>
|
|
*/
|
|
protected $arguments = [];
|
|
|
|
/**
|
|
* The Logger to use for a command
|
|
*
|
|
* @var LoggerInterface
|
|
*/
|
|
protected $logger;
|
|
|
|
/**
|
|
* Instance of Commands so
|
|
* commands can call other commands.
|
|
*
|
|
* @var Commands
|
|
*/
|
|
protected $commands;
|
|
|
|
public function __construct(LoggerInterface $logger, Commands $commands)
|
|
{
|
|
$this->logger = $logger;
|
|
$this->commands = $commands;
|
|
}
|
|
|
|
/**
|
|
* Actually execute a command.
|
|
*
|
|
* @param array<int|string, string|null> $params
|
|
*
|
|
* @return int|void
|
|
*/
|
|
abstract public function run(array $params);
|
|
|
|
/**
|
|
* Can be used by a command to run other commands.
|
|
*
|
|
* @param array<int|string, string|null> $params
|
|
*
|
|
* @return int|void
|
|
*
|
|
* @throws ReflectionException
|
|
*/
|
|
protected function call(string $command, array $params = [])
|
|
{
|
|
return $this->commands->run($command, $params);
|
|
}
|
|
|
|
/**
|
|
* A simple method to display an error with line/file, in child commands.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function showError(Throwable $e)
|
|
{
|
|
$exception = $e;
|
|
$message = $e->getMessage();
|
|
$config = config(Exceptions::class);
|
|
|
|
require $config->errorViewPath . '/cli/error_exception.php';
|
|
}
|
|
|
|
/**
|
|
* Show Help includes (Usage, Arguments, Description, Options).
|
|
*
|
|
* @return void
|
|
*/
|
|
public function showHelp()
|
|
{
|
|
CLI::write(lang('CLI.helpUsage'), 'yellow');
|
|
|
|
if (isset($this->usage)) {
|
|
$usage = $this->usage;
|
|
} else {
|
|
$usage = $this->name;
|
|
|
|
if ($this->arguments !== []) {
|
|
$usage .= ' [arguments]';
|
|
}
|
|
}
|
|
|
|
CLI::write($this->setPad($usage, 0, 0, 2));
|
|
|
|
if (isset($this->description)) {
|
|
CLI::newLine();
|
|
CLI::write(lang('CLI.helpDescription'), 'yellow');
|
|
CLI::write($this->setPad($this->description, 0, 0, 2));
|
|
}
|
|
|
|
if ($this->arguments !== []) {
|
|
CLI::newLine();
|
|
CLI::write(lang('CLI.helpArguments'), 'yellow');
|
|
$length = max(array_map(strlen(...), array_keys($this->arguments)));
|
|
|
|
foreach ($this->arguments as $argument => $description) {
|
|
CLI::write(CLI::color($this->setPad($argument, $length, 2, 2), 'green') . $description);
|
|
}
|
|
}
|
|
|
|
if ($this->options !== []) {
|
|
CLI::newLine();
|
|
CLI::write(lang('CLI.helpOptions'), 'yellow');
|
|
$length = max(array_map(strlen(...), array_keys($this->options)));
|
|
|
|
foreach ($this->options as $option => $description) {
|
|
CLI::write(CLI::color($this->setPad($option, $length, 2, 2), 'green') . $description);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pads our string out so that all titles are the same length to nicely line up descriptions.
|
|
*
|
|
* @param int $extra How many extra spaces to add at the end
|
|
*/
|
|
public function setPad(string $item, int $max, int $extra = 2, int $indent = 0): string
|
|
{
|
|
$max += $extra + $indent;
|
|
|
|
return str_pad(str_repeat(' ', $indent) . $item, $max);
|
|
}
|
|
|
|
/**
|
|
* Get pad for $key => $value array output
|
|
*
|
|
* @param array<string, string> $array
|
|
*
|
|
* @deprecated Use setPad() instead.
|
|
*
|
|
* @codeCoverageIgnore
|
|
*/
|
|
public function getPad(array $array, int $pad): int
|
|
{
|
|
$max = 0;
|
|
|
|
foreach (array_keys($array) as $key) {
|
|
$max = max($max, strlen($key));
|
|
}
|
|
|
|
return $max + $pad;
|
|
}
|
|
|
|
/**
|
|
* Makes it simple to access our protected properties.
|
|
*
|
|
* @return array<string, string>|Commands|LoggerInterface|string|null
|
|
*/
|
|
public function __get(string $key)
|
|
{
|
|
return $this->{$key} ?? null;
|
|
}
|
|
|
|
/**
|
|
* Makes it simple to check our protected properties.
|
|
*/
|
|
public function __isset(string $key): bool
|
|
{
|
|
return isset($this->{$key});
|
|
}
|
|
}
|