Fix command with validation when using -n/--no-interaction option

master 3.8.7
Julien Rosset 6 months ago
parent 6c31a16e80
commit fefb3bf3c1

@ -5,13 +5,14 @@ namespace jrosset\CliProgram\Validation;
use Closure; use Closure;
use jrosset\CliProgram\Validation\Validators\InvalidValueException; use jrosset\CliProgram\Validation\Validators\InvalidValueException;
use jrosset\CliProgram\Validation\Validators\IValidator; use jrosset\CliProgram\Validation\Validators\IValidator;
use ReflectionFunction;
use Stringable; use Stringable;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Throwable;
/** /**
* Provide a value validation process ({@see IValidator}) to {@see self::addArgument()} and {@see self::addOption()} * Provide a value validation process ({@see IValidator}) to {@see self::addArgument()} and {@see self::addOption()}
@ -25,16 +26,58 @@ trait TCommandWithValidation {
* @var array<string, IValidator> The validators of each {@see InputOption} * @var array<string, IValidator> The validators of each {@see InputOption}
*/ */
private array $optionsValidator = []; private array $optionsValidator = [];
/**
* @var Closure|null The <i>real</i> code ({@see Command::$code} is used to perform input validation before execution) to execute when running this command.
* <br><br>If set, it overrides the code defined in the execute() method.
*/
private ?Closure $realCode = null;
/** /**
* @inheritDoc * @inheritDoc
*
* @throws Throwable If an argument or option is not valid
*/ */
protected function interact (InputInterface $input, OutputInterface $output): void { protected function initialize (InputInterface $input, OutputInterface $output): void {
parent::interact($input, $output); parent::setCode(
function (InputInterface $input, OutputInterface $output): int {
$this->validate($input, $output); $this->validate($input, $output);
return $this->realCode !== null
? ($this->realCode)($input, $output)
: $this->execute($input, $output);
}
);
parent::initialize($input, $output);
}
/**
* @inheritDoc
*/
public function setCode (callable $code): static {
if ($code instanceof Closure) {
/** @noinspection PhpUnhandledExceptionInspection */
$codeReflection = new ReflectionFunction($code);
if ($codeReflection->getClosureThis() === null) {
set_error_handler(
static function () {
}
);
try {
if ($rebindCode = Closure::bind($code, $this)) {
$code = $rebindCode;
} }
}
finally {
restore_error_handler();
}
}
}
else {
$code = $code(...);
}
// {@see Command::$code} is used to perform input validation before execution, so set {@see self::$realCode} instead
$this->realCode = $code;
return $this;
}
/** /**
* Validate the command input * Validate the command input
* *

@ -11,14 +11,14 @@ abstract class BasedValidator implements IValidator {
/** /**
* @var TValidator The internal validator * @var TValidator The internal validator
*/ */
private $internalValidator; private IValidator $internalValidator;
/** /**
* Create a validator * Create a validator
* *
* @param TValidator $internalValidator The internal validator * @param TValidator $internalValidator The internal validator
*/ */
public function __construct ($internalValidator) { public function __construct (IValidator $internalValidator) {
$this->internalValidator = $internalValidator; $this->internalValidator = $internalValidator;
} }
/** /**
@ -26,7 +26,7 @@ abstract class BasedValidator implements IValidator {
* *
* @return TValidator The internal validator * @return TValidator The internal validator
*/ */
protected function getInternalValidator () { protected function getInternalValidator (): IValidator {
return $this->internalValidator; return $this->internalValidator;
} }

@ -13,7 +13,7 @@ namespace jrosset\CliProgram\Validation\Validators;
*/ */
trait TInternalValueValidator { trait TInternalValueValidator {
/** /**
* @var TValue|null The current value, after * @var TValue|null The current value, after it's validation
*/ */
private $value = null; private $value = null;

Loading…
Cancel
Save