mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Improve Command (#5878)
This commit is contained in:
parent
19c38ac8a9
commit
21d63d5e01
@ -11,20 +11,13 @@ declare(strict_types=1);
|
|||||||
*/
|
*/
|
||||||
namespace Hyperf\Command;
|
namespace Hyperf\Command;
|
||||||
|
|
||||||
use Hyperf\Contract\Arrayable;
|
|
||||||
use Hyperf\Coroutine\Coroutine;
|
use Hyperf\Coroutine\Coroutine;
|
||||||
use Hyperf\Stringable\Str;
|
|
||||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Swoole\ExitException;
|
use Swoole\ExitException;
|
||||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
|
||||||
use Symfony\Component\Console\Helper\Table;
|
|
||||||
use Symfony\Component\Console\Helper\TableStyle;
|
|
||||||
use Symfony\Component\Console\Input\ArrayInput;
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
|
||||||
use Symfony\Component\Console\Question\Question;
|
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
@ -36,33 +29,32 @@ use function Hyperf\Tappable\tap;
|
|||||||
abstract class Command extends SymfonyCommand
|
abstract class Command extends SymfonyCommand
|
||||||
{
|
{
|
||||||
use DisableEventDispatcher;
|
use DisableEventDispatcher;
|
||||||
|
use Concerns\InteractsWithIO;
|
||||||
|
use Concerns\HasParameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the command.
|
* The name of the command.
|
||||||
*/
|
*/
|
||||||
protected ?string $name = null;
|
protected ?string $name = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of the command.
|
||||||
|
*/
|
||||||
protected string $description = '';
|
protected string $description = '';
|
||||||
|
|
||||||
protected ?InputInterface $input = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var null|SymfonyStyle
|
|
||||||
*/
|
|
||||||
protected ?OutputInterface $output = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default verbosity of output commands.
|
|
||||||
*/
|
|
||||||
protected int $verbosity = OutputInterface::VERBOSITY_NORMAL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execution in a coroutine environment.
|
* Execution in a coroutine environment.
|
||||||
*/
|
*/
|
||||||
protected bool $coroutine = true;
|
protected bool $coroutine = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The eventDispatcher.
|
||||||
|
*/
|
||||||
protected ?EventDispatcherInterface $eventDispatcher = null;
|
protected ?EventDispatcherInterface $eventDispatcher = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hookFlags of the command.
|
||||||
|
*/
|
||||||
protected int $hookFlags = -1;
|
protected int $hookFlags = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,18 +62,6 @@ abstract class Command extends SymfonyCommand
|
|||||||
*/
|
*/
|
||||||
protected ?string $signature = null;
|
protected ?string $signature = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* The mapping between human-readable verbosity levels and Symfony's OutputInterface.
|
|
||||||
*/
|
|
||||||
protected array $verbosityMap
|
|
||||||
= [
|
|
||||||
'v' => OutputInterface::VERBOSITY_VERBOSE,
|
|
||||||
'vv' => OutputInterface::VERBOSITY_VERY_VERBOSE,
|
|
||||||
'vvv' => OutputInterface::VERBOSITY_DEBUG,
|
|
||||||
'quiet' => OutputInterface::VERBOSITY_QUIET,
|
|
||||||
'normal' => OutputInterface::VERBOSITY_NORMAL,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The exit code of the command.
|
* The exit code of the command.
|
||||||
*/
|
*/
|
||||||
@ -101,9 +81,15 @@ abstract class Command extends SymfonyCommand
|
|||||||
parent::__construct($this->name);
|
parent::__construct($this->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
! empty($this->description) && $this->setDescription($this->description);
|
|
||||||
|
|
||||||
$this->addDisableDispatcherOption();
|
$this->addDisableDispatcherOption();
|
||||||
|
|
||||||
|
if (! empty($this->description)) {
|
||||||
|
$this->setDescription($this->description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($this->signature)) {
|
||||||
|
$this->specifyParameters();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,195 +102,6 @@ abstract class Command extends SymfonyCommand
|
|||||||
return parent::run($this->input = $input, $this->output);
|
return parent::run($this->input = $input, $this->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm a question with the user.
|
|
||||||
*/
|
|
||||||
public function confirm(string $question, bool $default = false): bool
|
|
||||||
{
|
|
||||||
return $this->output->confirm($question, $default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user for input.
|
|
||||||
*/
|
|
||||||
public function ask(string $question, string $default = null)
|
|
||||||
{
|
|
||||||
return $this->output->ask($question, $default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user for input with auto-completion.
|
|
||||||
*
|
|
||||||
* @param null|bool|float|int|string $default
|
|
||||||
*/
|
|
||||||
public function anticipate(string $question, array $choices, $default = null)
|
|
||||||
{
|
|
||||||
return $this->askWithCompletion($question, $choices, $default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user for input with auto-completion.
|
|
||||||
*
|
|
||||||
* @param null|bool|float|int|string $default
|
|
||||||
*/
|
|
||||||
public function askWithCompletion(string $question, array $choices, $default = null)
|
|
||||||
{
|
|
||||||
$question = new Question($question, $default);
|
|
||||||
|
|
||||||
$question->setAutocompleterValues($choices);
|
|
||||||
|
|
||||||
return $this->output->askQuestion($question);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user for input but hide the answer from the console.
|
|
||||||
*/
|
|
||||||
public function secret(string $question, bool $fallback = true)
|
|
||||||
{
|
|
||||||
$question = new Question($question);
|
|
||||||
|
|
||||||
$question->setHidden(true)->setHiddenFallback($fallback);
|
|
||||||
|
|
||||||
return $this->output->askQuestion($question);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Give the user a multiple choice from an array of answers.
|
|
||||||
* @param mixed $default
|
|
||||||
*/
|
|
||||||
public function choiceMultiple(
|
|
||||||
string $question,
|
|
||||||
array $choices,
|
|
||||||
$default = null,
|
|
||||||
?int $attempts = null
|
|
||||||
): array {
|
|
||||||
$question = new ChoiceQuestion($question, $choices, $default);
|
|
||||||
|
|
||||||
$question->setMaxAttempts($attempts)->setMultiselect(true);
|
|
||||||
|
|
||||||
return $this->output->askQuestion($question);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Give the user a single choice from an array of answers.
|
|
||||||
*
|
|
||||||
* @param mixed $default
|
|
||||||
*/
|
|
||||||
public function choice(
|
|
||||||
string $question,
|
|
||||||
array $choices,
|
|
||||||
$default = null,
|
|
||||||
?int $attempts = null
|
|
||||||
): mixed {
|
|
||||||
return $this->choiceMultiple($question, $choices, $default, $attempts)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format input to textual table.
|
|
||||||
*/
|
|
||||||
public function table(array $headers, array|Arrayable $rows, TableStyle|string $tableStyle = 'default', array $columnStyles = []): void
|
|
||||||
{
|
|
||||||
$table = new Table($this->output);
|
|
||||||
|
|
||||||
if ($rows instanceof Arrayable) {
|
|
||||||
$rows = $rows->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$table->setHeaders($headers)->setRows($rows)->setStyle($tableStyle);
|
|
||||||
|
|
||||||
foreach ($columnStyles as $columnIndex => $columnStyle) {
|
|
||||||
$table->setColumnStyle($columnIndex, $columnStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
$table->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as standard output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $style
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function line($string, $style = null, $verbosity = null)
|
|
||||||
{
|
|
||||||
$styled = $style ? "<{$style}>{$string}</{$style}>" : $string;
|
|
||||||
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as information output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function info($string, $verbosity = null)
|
|
||||||
{
|
|
||||||
$this->line($string, 'info', $verbosity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as comment output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function comment($string, $verbosity = null)
|
|
||||||
{
|
|
||||||
$this->line($string, 'comment', $verbosity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as question output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function question($string, $verbosity = null)
|
|
||||||
{
|
|
||||||
$this->line($string, 'question', $verbosity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as error output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function error($string, $verbosity = null)
|
|
||||||
{
|
|
||||||
$this->line($string, 'error', $verbosity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string as warning output.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
* @param null|mixed $verbosity
|
|
||||||
*/
|
|
||||||
public function warn($string, $verbosity = null)
|
|
||||||
{
|
|
||||||
if (! $this->output->getFormatter()->hasStyle('warning')) {
|
|
||||||
$style = new OutputFormatterStyle('yellow');
|
|
||||||
$this->output->getFormatter()->setStyle('warning', $style);
|
|
||||||
}
|
|
||||||
$this->line($string, 'warning', $verbosity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a string in an alert box.
|
|
||||||
*
|
|
||||||
* @param mixed $string
|
|
||||||
*/
|
|
||||||
public function alert($string)
|
|
||||||
{
|
|
||||||
$length = Str::length(strip_tags($string)) + 12;
|
|
||||||
$this->comment(str_repeat('*', $length));
|
|
||||||
$this->comment('* ' . $string . ' *');
|
|
||||||
$this->comment(str_repeat('*', $length));
|
|
||||||
$this->output->newLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call another console command.
|
* Call another console command.
|
||||||
*/
|
*/
|
||||||
@ -315,36 +112,6 @@ abstract class Command extends SymfonyCommand
|
|||||||
return $this->getApplication()->find($command)->run($this->createInputFromArguments($arguments), $this->output);
|
return $this->getApplication()->find($command)->run($this->createInputFromArguments($arguments), $this->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the current command.
|
|
||||||
*/
|
|
||||||
abstract public function handle();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the verbosity level.
|
|
||||||
*
|
|
||||||
* @param mixed $level
|
|
||||||
*/
|
|
||||||
protected function setVerbosity($level)
|
|
||||||
{
|
|
||||||
$this->verbosity = $this->parseVerbosity($level);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
|
||||||
*
|
|
||||||
* @param null|mixed $level
|
|
||||||
*/
|
|
||||||
protected function parseVerbosity($level = null): int
|
|
||||||
{
|
|
||||||
if (isset($this->verbosityMap[$level])) {
|
|
||||||
$level = $this->verbosityMap[$level];
|
|
||||||
} elseif (! is_int($level)) {
|
|
||||||
$level = $this->verbosity;
|
|
||||||
}
|
|
||||||
return $level;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an input instance from the given arguments.
|
* Create an input instance from the given arguments.
|
||||||
*/
|
*/
|
||||||
@ -373,27 +140,6 @@ abstract class Command extends SymfonyCommand
|
|||||||
})->all();
|
})->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the arguments and options on the command.
|
|
||||||
*/
|
|
||||||
protected function specifyParameters(): void
|
|
||||||
{
|
|
||||||
// We will loop through all the arguments and options for the command and
|
|
||||||
// set them all on the base command instance. This specifies what can get
|
|
||||||
// past into these commands as "parameters" to control the execution.
|
|
||||||
if (method_exists($this, 'getArguments')) {
|
|
||||||
foreach ($this->getArguments() ?? [] as $arguments) {
|
|
||||||
call_user_func_array([$this, 'addArgument'], $arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_exists($this, 'getOptions')) {
|
|
||||||
foreach ($this->getOptions() ?? [] as $options) {
|
|
||||||
call_user_func_array([$this, 'addOption'], $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the console command using a fluent definition.
|
* Configure the console command using a fluent definition.
|
||||||
*/
|
*/
|
||||||
@ -413,19 +159,17 @@ abstract class Command extends SymfonyCommand
|
|||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
parent::configure();
|
parent::configure();
|
||||||
if (! isset($this->signature)) {
|
|
||||||
$this->specifyParameters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$this->disableDispatcher($input);
|
$this->disableDispatcher($input);
|
||||||
|
$method = method_exists($this, 'handle') ? 'handle' : '__invoke';
|
||||||
|
|
||||||
$callback = function () {
|
$callback = function () use ($method) {
|
||||||
try {
|
try {
|
||||||
$this->eventDispatcher?->dispatch(new Event\BeforeHandle($this));
|
$this->eventDispatcher?->dispatch(new Event\BeforeHandle($this));
|
||||||
$this->handle();
|
$this->{$method}();
|
||||||
$this->eventDispatcher?->dispatch(new Event\AfterHandle($this));
|
$this->eventDispatcher?->dispatch(new Event\AfterHandle($this));
|
||||||
} catch (Throwable $exception) {
|
} catch (Throwable $exception) {
|
||||||
if (class_exists(ExitException::class) && $exception instanceof ExitException) {
|
if (class_exists(ExitException::class) && $exception instanceof ExitException) {
|
||||||
|
63
src/command/src/Concerns/HasParameters.php
Normal file
63
src/command/src/Concerns/HasParameters.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://hyperf.wiki
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Hyperf\Command\Concerns;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
trait HasParameters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify the arguments and options on the command.
|
||||||
|
*/
|
||||||
|
protected function specifyParameters()
|
||||||
|
{
|
||||||
|
// We will loop through all of the arguments and options for the command and
|
||||||
|
// set them all on the base command instance. This specifies what can get
|
||||||
|
// passed into these commands as "parameters" to control the execution.
|
||||||
|
foreach ($this->getArguments() as $arguments) {
|
||||||
|
if ($arguments instanceof InputArgument) {
|
||||||
|
$this->getDefinition()->addArgument($arguments);
|
||||||
|
} else {
|
||||||
|
$this->addArgument(...$arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getOptions() as $options) {
|
||||||
|
if ($options instanceof InputOption) {
|
||||||
|
$this->getDefinition()->addOption($options);
|
||||||
|
} else {
|
||||||
|
$this->addOption(...$options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the console command arguments.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getArguments()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the console command options.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getOptions()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
425
src/command/src/Concerns/InteractsWithIO.php
Normal file
425
src/command/src/Concerns/InteractsWithIO.php
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* This file is part of Hyperf.
|
||||||
|
*
|
||||||
|
* @link https://www.hyperf.io
|
||||||
|
* @document https://hyperf.wiki
|
||||||
|
* @contact group@hyperf.io
|
||||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
namespace Hyperf\Command\Concerns;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Hyperf\Contract\Arrayable;
|
||||||
|
use Hyperf\Stringable\Str;
|
||||||
|
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||||
|
use Symfony\Component\Console\Helper\Table;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
use Symfony\Component\Console\Style\OutputStyle;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
trait InteractsWithIO
|
||||||
|
{
|
||||||
|
protected ?InputInterface $input = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var null|OutputInterface|SymfonyStyle
|
||||||
|
*/
|
||||||
|
protected ?OutputInterface $output = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default verbosity of output commands.
|
||||||
|
*/
|
||||||
|
protected int $verbosity = OutputInterface::VERBOSITY_NORMAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mapping between human readable verbosity levels and Symfony's OutputInterface.
|
||||||
|
*/
|
||||||
|
protected array $verbosityMap = [
|
||||||
|
'v' => OutputInterface::VERBOSITY_VERBOSE,
|
||||||
|
'vv' => OutputInterface::VERBOSITY_VERY_VERBOSE,
|
||||||
|
'vvv' => OutputInterface::VERBOSITY_DEBUG,
|
||||||
|
'quiet' => OutputInterface::VERBOSITY_QUIET,
|
||||||
|
'normal' => OutputInterface::VERBOSITY_NORMAL,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given argument is present.
|
||||||
|
*
|
||||||
|
* @param int|string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasArgument($name)
|
||||||
|
{
|
||||||
|
return $this->input->hasArgument($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a command argument.
|
||||||
|
*
|
||||||
|
* @param null|string $key
|
||||||
|
* @return null|array|bool|string
|
||||||
|
*/
|
||||||
|
public function argument($key = null)
|
||||||
|
{
|
||||||
|
if (is_null($key)) {
|
||||||
|
return $this->input->getArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->input->getArgument($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the arguments passed to the command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function arguments()
|
||||||
|
{
|
||||||
|
return $this->argument();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given option is present.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasOption($name)
|
||||||
|
{
|
||||||
|
return $this->input->hasOption($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a command option.
|
||||||
|
*
|
||||||
|
* @param null|string $key
|
||||||
|
* @return null|array|bool|string
|
||||||
|
*/
|
||||||
|
public function option($key = null)
|
||||||
|
{
|
||||||
|
if (is_null($key)) {
|
||||||
|
return $this->input->getOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->input->getOption($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the options passed to the command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function options()
|
||||||
|
{
|
||||||
|
return $this->option();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm a question with the user.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param bool $default
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function confirm($question, $default = false)
|
||||||
|
{
|
||||||
|
return $this->output->confirm($question, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for input.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param null|string $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function ask($question, $default = null)
|
||||||
|
{
|
||||||
|
return $this->output->ask($question, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for input with auto completion.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param array|callable $choices
|
||||||
|
* @param null|string $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function anticipate($question, $choices, $default = null)
|
||||||
|
{
|
||||||
|
return $this->askWithCompletion($question, $choices, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for input with auto completion.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param array|callable $choices
|
||||||
|
* @param null|string $default
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function askWithCompletion($question, $choices, $default = null)
|
||||||
|
{
|
||||||
|
$question = new Question($question, $default);
|
||||||
|
|
||||||
|
is_callable($choices)
|
||||||
|
? $question->setAutocompleterCallback($choices)
|
||||||
|
: $question->setAutocompleterValues($choices);
|
||||||
|
|
||||||
|
return $this->output->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for input but hide the answer from the console.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param bool $fallback
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function secret($question, $fallback = true)
|
||||||
|
{
|
||||||
|
$question = new Question($question);
|
||||||
|
|
||||||
|
$question->setHidden(true)->setHiddenFallback($fallback);
|
||||||
|
|
||||||
|
return $this->output->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the user a single choice from an array of answers.
|
||||||
|
*
|
||||||
|
* @param string $question
|
||||||
|
* @param null|int|string $default
|
||||||
|
* @param null|mixed $attempts
|
||||||
|
* @param bool $multiple
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = false)
|
||||||
|
{
|
||||||
|
$question = new ChoiceQuestion($question, $choices, $default);
|
||||||
|
|
||||||
|
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
|
||||||
|
|
||||||
|
return $this->output->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format input to textual table.
|
||||||
|
*
|
||||||
|
* @param array $headers
|
||||||
|
* @param array|Arrayable $rows
|
||||||
|
* @param string|\Symfony\Component\Console\Helper\TableStyle $tableStyle
|
||||||
|
*/
|
||||||
|
public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])
|
||||||
|
{
|
||||||
|
$table = new Table($this->output);
|
||||||
|
|
||||||
|
if ($rows instanceof Arrayable) {
|
||||||
|
$rows = $rows->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);
|
||||||
|
|
||||||
|
foreach ($columnStyles as $columnIndex => $columnStyle) {
|
||||||
|
$table->setColumnStyle($columnIndex, $columnStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a given callback while advancing a progress bar.
|
||||||
|
*
|
||||||
|
* @param int|iterable $totalSteps
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public function withProgressBar($totalSteps, Closure $callback)
|
||||||
|
{
|
||||||
|
$bar = $this->output->createProgressBar(
|
||||||
|
is_iterable($totalSteps) ? count($totalSteps) : $totalSteps
|
||||||
|
);
|
||||||
|
|
||||||
|
$bar->start();
|
||||||
|
|
||||||
|
if (is_iterable($totalSteps)) {
|
||||||
|
foreach ($totalSteps as $value) {
|
||||||
|
$callback($value, $bar);
|
||||||
|
|
||||||
|
$bar->advance();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$callback($bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar->finish();
|
||||||
|
|
||||||
|
if (is_iterable($totalSteps)) {
|
||||||
|
return $totalSteps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as information output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function info($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
$this->line($string, 'info', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as standard output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|string $style
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function line($string, $style = null, $verbosity = null)
|
||||||
|
{
|
||||||
|
$styled = $style ? "<{$style}>{$string}</{$style}>" : $string;
|
||||||
|
|
||||||
|
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as comment output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function comment($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
$this->line($string, 'comment', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as question output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function question($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
$this->line($string, 'question', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as error output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function error($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
$this->line($string, 'error', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string as warning output.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function warn($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
if (! $this->output->getFormatter()->hasStyle('warning')) {
|
||||||
|
$style = new OutputFormatterStyle('yellow');
|
||||||
|
|
||||||
|
$this->output->getFormatter()->setStyle('warning', $style);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->line($string, 'warning', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string in an alert box.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param null|int|string $verbosity
|
||||||
|
*/
|
||||||
|
public function alert($string, $verbosity = null)
|
||||||
|
{
|
||||||
|
$length = Str::length(strip_tags($string)) + 12;
|
||||||
|
|
||||||
|
$this->comment(str_repeat('*', $length), $verbosity);
|
||||||
|
$this->comment('* ' . $string . ' *', $verbosity);
|
||||||
|
$this->comment(str_repeat('*', $length), $verbosity);
|
||||||
|
|
||||||
|
$this->comment('', $verbosity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a blank line.
|
||||||
|
*
|
||||||
|
* @param int $count
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function newLine($count = 1)
|
||||||
|
{
|
||||||
|
$this->output->newLine($count);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the input interface implementation.
|
||||||
|
*/
|
||||||
|
public function setInput(InputInterface $input)
|
||||||
|
{
|
||||||
|
$this->input = $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the output interface implementation.
|
||||||
|
*/
|
||||||
|
public function setOutput(OutputStyle $output)
|
||||||
|
{
|
||||||
|
$this->output = $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the output implementation.
|
||||||
|
*
|
||||||
|
* @return OutputStyle
|
||||||
|
*/
|
||||||
|
public function getOutput()
|
||||||
|
{
|
||||||
|
return $this->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the verbosity level.
|
||||||
|
*
|
||||||
|
* @param int|string $level
|
||||||
|
*/
|
||||||
|
protected function setVerbosity($level)
|
||||||
|
{
|
||||||
|
$this->verbosity = $this->parseVerbosity($level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
||||||
|
*
|
||||||
|
* @param null|int|string $level
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function parseVerbosity($level = null)
|
||||||
|
{
|
||||||
|
if (isset($this->verbosityMap[$level])) {
|
||||||
|
$level = $this->verbosityMap[$level];
|
||||||
|
} elseif (! is_int($level)) {
|
||||||
|
$level = $this->verbosity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $level;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user