PHP 7.4 & PHP 8.0 → branche 2.x

2.x 2.0.0
Julien Rosset 2 years ago
parent caa254ab80
commit 0ef982f8b7

@ -9,17 +9,17 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.x-dev" "dev-master": "2.x-dev"
} }
}, },
"minimum-stability": "stable", "minimum-stability": "stable",
"require": { "require": {
"php": "^8.1", "php": "^7.4 || ^8.0.0",
"symfony/console": "^6.1", "symfony/console": "^5.4",
"jrosset/betterphptoken": "^1.0", "jrosset/betterphptoken": "^1.0",
"jrosset/collections": "^3.0", "jrosset/collections": "^2.3",
"jrosset/extendedmonolog": "^2.0" "jrosset/extendedmonolog": "^1.1"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

@ -2,7 +2,6 @@
namespace jrosset\CliProgram\Validation; namespace jrosset\CliProgram\Validation;
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 Stringable; use Stringable;
@ -96,7 +95,6 @@ trait TCommandWithValidation {
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only) * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
* @param string $description The argument description * @param string $description The argument description
* @param IValidator|null $validator The validator or Null if none * @param IValidator|null $validator The validator or Null if none
* @param Closure|array|null $suggestedValues The function or list of suggested values when completing ; Null if none
* *
* @return $this * @return $this
* *
@ -106,21 +104,15 @@ trait TCommandWithValidation {
string $name, string $name,
int $mode = null, int $mode = null,
string $description = '', string $description = '',
mixed $default = null, $default = null,
?IValidator $validator = null, ?IValidator $validator = null
Closure|array|null $suggestedValues = null ): self {
): static {
$default = static::treatStringableDefaultValue($default); $default = static::treatStringableDefaultValue($default);
if ($validator !== null) { if ($validator !== null) {
$default = $validator->getValidDefault($default); $default = $validator->getValidDefault($default);
} }
if ($suggestedValues !== null) {
parent::addArgument($name, $mode, $description, $default, $suggestedValues);
}
else {
parent::addArgument($name, $mode, $description, $default); parent::addArgument($name, $mode, $description, $default);
}
return $this->setArgumentValidator($name, $validator); return $this->setArgumentValidator($name, $validator);
} }
/** /**
@ -133,7 +125,7 @@ trait TCommandWithValidation {
* *
* @throws InvalidArgumentException If the {@see InputArgument} doesn't exist * @throws InvalidArgumentException If the {@see InputArgument} doesn't exist
*/ */
public function setArgumentValidator (string $name, ?IValidator $validator): static { public function setArgumentValidator (string $name, ?IValidator $validator): self {
if (!$this->getDefinition()->hasArgument($name)) { if (!$this->getDefinition()->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist', $name)); throw new InvalidArgumentException(sprintf('The "%s" argument does not exist', $name));
} }
@ -169,7 +161,6 @@ trait TCommandWithValidation {
* @param string $description The argument description * @param string $description The argument description
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE) * @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
* @param IValidator|null $validator The validator or Null if none ; ignored if **$mode** = {@see InputOption::VALUE_NONE} * @param IValidator|null $validator The validator or Null if none ; ignored if **$mode** = {@see InputOption::VALUE_NONE}
* @param Closure|array|null $suggestedValues The function or list of suggested values when completing ; Null if none
* *
* @return $this * @return $this
* *
@ -177,24 +168,18 @@ trait TCommandWithValidation {
*/ */
public function addOption ( public function addOption (
string $name, string $name,
string|array|null $shortcut = null, $shortcut = null,
int $mode = null, int $mode = null,
string $description = '', string $description = '',
mixed $default = null, $default = null,
?IValidator $validator = null, ?IValidator $validator = null
Closure|array|null $suggestedValues = null ): self {
): static {
$default = static::treatStringableDefaultValue($default); $default = static::treatStringableDefaultValue($default);
if ($validator !== null) { if ($validator !== null) {
$default = $validator->getValidDefault($default); $default = $validator->getValidDefault($default);
} }
if ($suggestedValues !== null) {
parent::addOption($name, $shortcut, $mode, $description, $default, $suggestedValues);
}
else {
parent::addOption($name, $shortcut, $mode, $description, $default); parent::addOption($name, $shortcut, $mode, $description, $default);
}
return $this->setOptionValidator($name, $validator); return $this->setOptionValidator($name, $validator);
} }
/** /**
@ -207,7 +192,7 @@ trait TCommandWithValidation {
* *
* @throws InvalidArgumentException If the {@see InputOption} doesn't exist * @throws InvalidArgumentException If the {@see InputOption} doesn't exist
*/ */
public function setOptionValidator (string $name, ?IValidator $validator): static { public function setOptionValidator (string $name, ?IValidator $validator): self {
if (!$this->getDefinition()->hasOption($name)) { if (!$this->getDefinition()->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "--%s" option does not exist', $name)); throw new InvalidArgumentException(sprintf('The "--%s" option does not exist', $name));
} }
@ -241,7 +226,7 @@ trait TCommandWithValidation {
* *
* @return mixed The default value * @return mixed The default value
*/ */
protected static function treatStringableDefaultValue (mixed $default): mixed { protected static function treatStringableDefaultValue ($default) {
if ($default instanceof Stringable) { if ($default instanceof Stringable) {
return $default->__toString(); return $default->__toString();
} }

@ -20,7 +20,7 @@ abstract class AbstractDateTimeValidator extends BasedValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
$this->getInternalValidator()->setPattern($this->getPattern()); $this->getInternalValidator()->setPattern($this->getPattern());
return parent::validate($value); return parent::validate($value);
} }

@ -33,7 +33,7 @@ abstract class BasedValidator implements IValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
return $this->internalValidator->validate($value); return $this->internalValidator->validate($value);
} }
} }

@ -29,7 +29,7 @@ class DateTimeValidator extends AbstractDateTimeValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function getValidDefault (mixed $default): string|bool|int|float|array { public function getValidDefault ($default) {
if ($default instanceof DateTimeInterface) { if ($default instanceof DateTimeInterface) {
return $default->format('Y-m-d H:i:s'); return $default->format('Y-m-d H:i:s');
} }

@ -29,7 +29,7 @@ class DateValidator extends AbstractDateTimeValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function getValidDefault (mixed $default): string|bool|int|float|array { public function getValidDefault ($default) {
if ($default instanceof DateTimeInterface) { if ($default instanceof DateTimeInterface) {
return $default->format('Y-m-d'); return $default->format('Y-m-d');
} }

@ -56,7 +56,7 @@ class DecimalValidator extends BasedValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
if (!parent::validate($value)) { if (!parent::validate($value)) {
return false; return false;
} }

@ -1,62 +0,0 @@
<?php
namespace jrosset\CliProgram\Validation\Validators;
use jrosset\Collections\Collection;
use ReflectionEnum;
use ReflectionException;
use UnitEnum;
/**
* An argument/option value validator based on an enumeration
*
* @template TEnum of UnitEnum
* @template-implements IValidator<TEnum>
* @template-implements TInternalValueValidator<TEnum>
*/
class EnumValidator extends BasedValidator {
/**
* @var ReflectionEnum The enumeration
*/
private ReflectionEnum $enum;
/**
* Create a validator
*
* @param class-string<UnitEnum> $enumClass The enumeration class
*
* @throws ReflectionException If the enumeration class doesn't exist
*/
public function __construct (string $enumClass) {
$this->enum = new ReflectionEnum($enumClass);
$enumCases = new Collection();
foreach ($this->enum->getCases() as $enumCase) {
$enumCases->add($enumCase->getName());
}
parent::__construct(new ListValidator($enumCases));
}
/**
* @inheritDoc
*
* @throws ReflectionException
*/
public function getValidDefault (mixed $default): string|bool|int|float|array {
if ($default instanceof UnitEnum) {
$default = $default->name;
}
return $default;
}
/**
* @inheritDoc
*
* @throws ReflectionException
*/
public function getValue (): UnitEnum {
$enumCase = $this->getInternalValidator()->getValue();
return $this->enum->getCase($enumCase)->getValue();
}
}

@ -15,7 +15,7 @@ interface IValidator {
* *
* @return string|bool|int|float|array The valid default value * @return string|bool|int|float|array The valid default value
*/ */
public function getValidDefault (mixed $default): string|bool|int|float|array; public function getValidDefault ($default);
/** /**
* Validate a value * Validate a value
@ -24,7 +24,7 @@ interface IValidator {
* *
* @return bool True if the value is valid, else False * @return bool True if the value is valid, else False
*/ */
public function validate (mixed $value): bool; public function validate ($value): bool;
/** /**
* Get the value, after it's validation * Get the value, after it's validation
* *

@ -50,7 +50,7 @@ class IntegerValidator extends BasedValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
if (!parent::validate($value)) { if (!parent::validate($value)) {
return false; return false;
} }

@ -33,7 +33,7 @@ class ListValidator implements IValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
if ($this->getAllowedValues()->contains($value)) { if ($this->getAllowedValues()->contains($value)) {
$this->setValue($value); $this->setValue($value);
return true; return true;

@ -32,7 +32,7 @@ class RegexValidator implements IValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function validate (mixed $value): bool { public function validate ($value): bool {
return preg_match($this->pattern, $value, $this->matches) === 1; return preg_match($this->pattern, $value, $this->matches) === 1;
} }
@ -71,7 +71,7 @@ class RegexValidator implements IValidator {
* *
* @return string|null The capturing group or Null if not set * @return string|null The capturing group or Null if not set
*/ */
public function getMatch (int|string $group): ?string { public function getMatch ($group): ?string {
return $this->getMatches()[$group] ?? null; return $this->getMatches()[$group] ?? null;
} }
/** /**
@ -81,7 +81,7 @@ class RegexValidator implements IValidator {
* *
* @return bool True if the capturing group exists and is not null * @return bool True if the capturing group exists and is not null
*/ */
public function hasMatch (int|string $group): bool { public function hasMatch ($group): bool {
return $this->getMatches()[$group] !== null; return $this->getMatches()[$group] !== null;
} }

@ -11,7 +11,7 @@ trait TIdenticalValidDefaultValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function getValidDefault (mixed $default): string|bool|int|float|array { public function getValidDefault ($default) {
return $default; return $default;
} }
} }

@ -32,7 +32,7 @@ trait TInternalValueValidator {
* *
* @return $this * @return $this
*/ */
protected function setValue ($value): static { protected function setValue ($value): self {
$this->value = $value; $this->value = $value;
return $this; return $this;
} }

@ -29,7 +29,7 @@ class TimeValidator extends AbstractDateTimeValidator {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function getValidDefault (mixed $default): string|bool|int|float|array { public function getValidDefault ($default) {
if ($default instanceof DateTimeInterface) { if ($default instanceof DateTimeInterface) {
return $default->format('H:i:s'); return $default->format('H:i:s');
} }

@ -7,9 +7,7 @@ use DateTimeInterface;
use jrosset\CliProgram\Monolog\ConsoleOutputWithMonolog; use jrosset\CliProgram\Monolog\ConsoleOutputWithMonolog;
use jrosset\CliProgram\Validation\CommandWithValidation; use jrosset\CliProgram\Validation\CommandWithValidation;
use jrosset\CliProgram\Validation\Validators\DateValidator; use jrosset\CliProgram\Validation\Validators\DateValidator;
use jrosset\CliProgram\Validation\Validators\EnumValidator;
use jrosset\CliProgram\Validation\Validators\IntegerValidator; use jrosset\CliProgram\Validation\Validators\IntegerValidator;
use jrosset\Tests\Lang;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -42,14 +40,6 @@ class Hello extends CommandWithValidation {
new DateValidator() new DateValidator()
); );
$this->addOption(
'lang',
'l',
InputArgument::OPTIONAL,
'The lang',
Lang::English,
new EnumValidator(Lang::class)
);
$this->addOption( $this->addOption(
'repeat', 'repeat',
'r', 'r',
@ -66,7 +56,7 @@ class Hello extends CommandWithValidation {
protected function execute (InputInterface $input, OutputInterface $output): int { protected function execute (InputInterface $input, OutputInterface $output): int {
$output->writeln('Command : ' . __CLASS__, OutputInterface::VERBOSITY_DEBUG); $output->writeln('Command : ' . __CLASS__, OutputInterface::VERBOSITY_DEBUG);
$text = $input->getOption('lang')->value; $text = 'Hello';
$repeat = $input->getOption('repeat'); $repeat = $input->getOption('repeat');
/** @var DateTimeInterface $day */ /** @var DateTimeInterface $day */

@ -1,9 +0,0 @@
<?php
namespace jrosset\Tests;
enum Lang: string {
case French = 'Bonjour';
case English = 'Good morning';
case American = 'Hello';
}
Loading…
Cancel
Save