Compare commits

...

1 Commits
master ... v2

Author SHA1 Message Date
Julien Rosset 7351f90e28 V2 4 years ago

@ -5,7 +5,8 @@
"minimum-stability": "dev",
"require": {
"php": ">= 7.4"
"php": ">= 7.4",
"ext-reflection": "*"
},
"autoload": {
"psr-4": {

@ -0,0 +1,114 @@
<?php
namespace jrosset\CommandLine\Argument;
/**
* Abstract base for arguments
*/
abstract class AbstractArgument implements IArgument {
/**
* @var string The variable name in parse output
*/
private string $varName;
/**
* @var mixed|null The default value for the argument. Null if none
*/
private $_default;
/**
* @var string The argument name in help
*/
private string $name;
/**
* @var string|null The argument description in help
*/
private ?string $description;
/**
* Create a new argument
*
* By default, the {@see AbstractArgument::$varName variable name} is the same as the {@see AbstractArgument::$name argument in help}
*
* @param string $name The argument name in help
* @param string|null $description The argument description in help
*/
protected function __construct (string $name, ?string $description) {
$this->setVarName($this->getName());
$this->setDefault();
$this->setName($name);
$this->setDescription($description);
}
/**
* @inheritDoc
*/
public function getVarName (): string {
return $this->varName;
}
/**
* Set the variable name in parse output
*
* @param string $varName The variable name
*
* @return $this
*/
public function setVarName (string $varName): self {
$this->varName = $varName;
return $this;
}
/**
* @inheritDoc
*/
public function getDefault () {
return $this->_default;
}
/**
* Set the default value for the argument. Null if none
*
* @param mixed $default The default value
*
* @return $this
*/
public function setDefault ($default = null): self {
$this->_default = $default;
return $this;
}
/**
* @inheritDoc
*/
public function getName (): string {
return $this->name;
}
/**
* Set the argument name in help
*
* @param string $name The argument name in help
*
* @return $this
*/
public function setName (string $name): self {
$this->name = $name;
return $this;
}
/**
* @inheritDoc
*/
public function getDescription (): ?string {
return $this->description;
}
/**
* Set the argument description in help
*
* @param string|null $description The argument description
*
* @return $this
*/
public function setDescription (?string $description): self {
$this->description = $description;
return $this;
}
}

@ -0,0 +1,23 @@
<?php
namespace jrosset\CommandLine\Argument;
use jrosset\CommandLine\ArrayClass;
/**
* A list of arguments
*
* @extends ArrayClass<IArgument>
*/
abstract class AbstractArgumentList extends ArrayClass {
/**
* Get the key of an element. Null if auto-generated
*
* @param IArgument $element The element
*
* @return int The key or Null
*/
protected function getKeyForElement ($element): int {
return $element->getVarName();
}
}

@ -1,126 +0,0 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\AbstractArgument.
*/
namespace jrosset\CommandLine\Argument;
/**
* Classe abstraite pour n'importe quel type de paramètre
*
* @package CommandLine\Argument
*/
abstract class ArgumentAbstract implements IArgument {
/**
* @var string Le nom de la variable de retour de l'argument.
*/
protected string $varName;
/**
* @var string Le nom de l'argument.
*/
protected string $name;
/**
* @var string|null La description de l'argument.
*/
protected ?string $description;
/**
* @var mixed|null La valeur par défaut. Null si aucune.
*/
protected $_default = null;
/**
* Crée un nouvel argument.
*
* @param string $name Le nom de l'argument
* @param string|null $description La description de l'argument
*/
protected function __construct (string $name, ?string $description) {
$this->setName($name);
$this->setDescription($description);
}
/**
* @inheritDoc
*/
public function getVarName (): string {
return $this->varName;
}
/**
* Définit le nom de la variable de retour de l'argument.
*
* @param string $varName Le nom
*
* @return $this
*
* @see $name
*/
public function setVarName (string $varName): self {
$this->varName = $varName;
return $this;
}
/**
* @inheritDoc
*/
public function getName (): string {
return $this->name;
}
/**
* Définit le nom de l'argument.
*
* @param string $name Le nom
* @param boolean $replaceVarName Remplacer également le nom de la variable de retour ?
*
* @return $this
*
* @see $name
*/
public function setName (string $name, bool $replaceVarName = true): self {
$this->name = $name;
if ($replaceVarName) {
$this->setVarName($name);
}
return $this;
}
/**
* @inheritDoc
*/
public function getDescription (): ?string {
return $this->description;
}
/**
* Définit la description de l'argument.
*
* @param string|null $description La description
*
* @return $this
*
* @see $description
*/
public function setDescription (?string $description): self {
$this->description = $description;
return $this;
}
/**
* @inheritDoc
*/
public function getDefault () {
return $this->_default;
}
/**
* Définit le valeur par défaut
*
* @param mixed|null $default La valeur par défaut.
*
* @return $this
*
* @see $_default
*/
public function setDefault ($default = null): self {
$this->_default = $default;
return $this;
}
}

@ -1,50 +1,33 @@
<?php
/**
* Déclaration de l'interface CommandLine\Argument\IArgument
*/
namespace jrosset\CommandLine\Argument;
use jrosset\CommandLine\Exception\IncorrectParse;
/**
* Interface que tout argument doit implémenter
*
* @package CommandLine\Argument
* Interface of all arguments
*/
interface IArgument {
/**
* Le nom de la variable de sortie l'argument
* The variable name in parse output
*
* @return string Le nom
* @return string The variable name
*/
public function getVarName (): string;
/**
* Le nom de l'argument
*
* @return string Le nom
*/
public function getName (): string;
/**
* La valeur par défaut de l'argument. Null si pas de valeur par défaut
* The default value for the argument. Null if none
*
* @return mixed|null La valeur par défaut
* @return mixed|null The default value
*/
public function getDefault();
/**
* La description de l'argument
* The argument name in help
*
* @return string|null La description
* @return string Le argument name
*/
public function getDescription (): ?string;
public function getName (): string;
/**
* Parse les arguments.
*
* @param $args array La liste des arguments encore à traiter (par ordre de réception)
* The argument description in help
*
* @return ParseResult|null Le résultat du parsage. Null si rien parsé
* @throws IncorrectParse Echec du parsage de l'argument
* @return string|null The argument description
*/
public function parse (array $args): ?ParseResult;
public function getDescription (): ?string;
}

@ -1,19 +1,15 @@
<?php
/**
* Déclaration de l'interface CommandLine\Argument\IArgumentValueDescription
*/
namespace jrosset\CommandLine\Argument;
/**
* Interface à implementer par les arguments qui souhaitent détailler la valeur attendue
*
* @package CommandLine\Argument
* Interface for argument expected value description
*/
interface IArgumentValueDescription {
/**
* La description de la valeur de d'argument.
* The expected value description in help
*
* @return string La description.
* @return string The expected value description
*/
public function getValueDescription (): string;
}

@ -0,0 +1,101 @@
<?php
namespace jrosset\CommandLine\Argument\Option;
use jrosset\CommandLine\Argument\AbstractArgument;
/**
* Abstract base for option arguments: --XXX or -X
*/
abstract class AbstractOptionArgument extends AbstractArgument implements IOptionArgument {
/**
* @var string|null The short tag (the -X form). Null if none
*/
private ?string $tagShort;
/**
* @var string The long tag (the --XXX form)
*/
private string $tagLong;
/**
* Create a new option argument
*
* By default, the {@see AbstractArgument::$varName variable name} is the same as the {@see AbstractArgument::$name argument in help}
*
* @param string $name The argument name in help
* @param string|null $description The argument description in help
* @param string|null $tagLong The long tag. If null, deduce from argument name <b>$name</b> (see {@see AbstractOptionArgument::convertNameToTagLong()}
* @param string|null $tagShort the short tag
*/
public function __construct (string $name, ?string $description, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description);
$this->setTagLong($tagLong ?? static::convertNameToTagLong($name));
$this->setTagShort($tagShort);
}
/**
* Convert a variable name to a long tag
*
* Performs the following tasks :
* 1. The underscores are replaced by a caret
* 2. The upper case letters are replaced by a caret followed with the lower case letter
*
* @param string $name The name to convert
*
* @return string The corresponding long tag
*/
public static function convertNameToTagLong (string $name): string {
return preg_replace_callback(
'/[A-Z_]/',
function ($matches) {
return '-' . ($matches[0] === '_' ? '' : '' . mb_strtolower($matches[0]));
},
$name
);
}
/**
* @inheritDoc
*/
public function getTagShort (): ?string {
return $this->tagShort;
}
/**
* Set the short tag. Null if none
*
* @param string|null $tagShort The short tag
*
* @return $this
*/
public function setTagShort (string $tagShort = null): self {
$this->tagShort = $tagShort;
return $this;
}
/**
* Is a short tag defined ?
*
* @return boolean True if a short tag is defined, else False
*/
public function hasTagShort (): bool {
return $this->getTagShort() !== null;
}
/**
* @inheritDoc
*/
public function getTagLong (): string {
return $this->tagLong;
}
/**
* Set the long tag
*
* @param string $tagLong The long tag
*
* @return $this
*/
public function setTagLong (string $tagLong): self {
$this->tagLong = $tagLong;
return $this;
}
}

@ -1,58 +1,43 @@
<?php
/**
* Déclare la classe CommandLine\Argument\Option\Flag.
*/
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\ParseResult;
/**
* Option de type "flag" contenant True ou False
*
* Si fourni, retournera la valeur inverse de {@see getDefault() getDefault}
*
* @package CommandLine\Argument\Option
* @see FlagReverse
* A "flag" option argument
*
* The output value is a boolean
*/
class Flag extends OptionAbstract {
class Flag extends AbstractOptionArgument {
/**
* Crée un nouvel argument de type option
* Create a new flag option argument
*
* By default, the {@see AbstractArgument::$varName variable name} is the same as the {@see AbstractArgument::$name argument in help}
*
* @param string $name Le nom
* @param bool $default La valeur par défaut
* @param string|null $description La description
* @param string|null $tagLong Le tag long
* @param string|null $tagShort Le tag court
* @param string $name The argument name in help
* @param string|null $description The argument name in documentation
* @param bool $default The argument default value
* @param string|null $tagLong The long tag. If null, deduce from argument name <b>$name</b> (see {@see AbstractOptionArgument::convertNameToTagLong()}
* @param string|null $tagShort The short tag
*/
public function __construct (string $name, bool $default, ?string $description, ?string $tagLong = null, ?string $tagShort = null) {
public function __construct (string $name, ?string $description, bool $default, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description, $tagLong, $tagShort);
$this->setDefault($default);
}
/**
* @inheritDoc
*/
public function parse (array $args): ?ParseResult {
if ($this->_parseTag($args[0])) {
return new ParseResult(true, 1);
}
return null;
}
/**
* Définit la valeur par défaut
* Set default value for the argument
*
* @param boolean $default La valeur par défaut.
* @param boolean $default The default value for the argument (boolean)
*
* @return $this
*
* @throws InvalidArgumentException If the default value provided is not valid (boolean)
*/
public function setDefault ($default = null): self {
public function setDefault ($default = false): self {
if (!is_bool($default)) {
throw new InvalidArgumentException('La valeur par défaut DOIT être un booléen');
throw new InvalidArgumentException('The default value must be a boolean');
}
parent::setDefault($default);

@ -1,55 +0,0 @@
<?php
/**
* Déclare la classe CommandLine\Argument\Option\OptionFlagWithReverse.
*/
namespace jrosset\CommandLine\Argument\Option;
/**
* Option de type "flag" : vaut True ou False avec son tag inversé.
*
* Le tag long inversé est automatiquement généré en préfixant avec "no-" sauf si l'initial commence déjà par "no-".
* Le tag court inversé est fait de la même manière, mais avec le préfixe "n".
*
* Exemples :
* - "--force" donne "--no-force"
* - "-f" donne "-nf"
* - "--no-stop" devient "--stop"
*
* @package CommandLine\Argument\Option
*/
class FlagWithReverse extends Flag implements IArgumentOptionSecondary {
public function getOthersOptions (): array {
$tagShort = null;
if ($this->hasTagShort()) {
if (substr($this->getTagShort(), 0, 1) == 'n') {
$tagShort = substr($this->getTagShort(), 1);
}
else {
$tagShort = 'n' . $this->getTagShort();
}
}
if (substr($this->getTagLong(), 0, 3) == 'no-') {
$tagLong = substr($this->getTagLong(), 3);
}
else {
$tagLong = 'no-' . $this->getTagLong();
}
$name = $this->getName();
if (substr($name, 0, 3) == 'no') {
$name = strtolower(substr($name, 2, 1)) . substr($name, 3);
}
else {
$name = 'no' . strtoupper(substr($name, 0, 1)) . substr($name, 1);
}
$description = '[INVERSE] ' . $this->getDescription();
$reverse = new Flag($name, !$this->getDefault(), $description, $tagLong, $tagShort);
$reverse->setVarName($this->getVarName());
return array($reverse);
}
}

@ -1,46 +0,0 @@
<?php
/**
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentOption
*/
namespace jrosset\CommandLine\Argument\Option;
use jrosset\CommandLine\Argument\IArgument;
/**
* Interface à implémenter si l'argument est de type "option"
*
* @package CommandLine\Argument\Option
*/
interface IArgumentOption extends IArgument {
/**
* La tag court.
*
* @return string|null Le tag court.
*
* @see $_tagShort
*/
public function getTagShort (): ?string;
/**
* Le tag long.
*
* @return string Le tag long.
*
* @see $_tagLong
*/
public function getTagLong (): string;
/**
* Est-ce que l'argument est autorisé plusieurs fois ?
*
* @return boolean True si l'argument est autorisé plusieurs fois, sinon False
*/
public function allowMultiple (): bool;
/**
* Est-ce que l'argument met fin au parsage ?
*
* Exemple : --help = affiche l'aide et stoppe le programme
*
* @return boolean True si la présence de l'argument mat fin au parsage, sinon False.
*/
public function isStoppingParse (): bool;
}

@ -1,19 +0,0 @@
<?php
/**
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentSecondary.
*/
namespace jrosset\CommandLine\Argument\Option;
/**
* Interface à implémenter si l'argument "option" auto-déclare d'autres arguments
*
* @package CommandLine\Argument\Option
*/
interface IArgumentOptionSecondary {
/**
* La liste des arguments auto-déclarés.
*
* @return IArgumentOption[] La liste des arguments
*/
public function getOthersOptions (): array;
}

@ -0,0 +1,23 @@
<?php
namespace jrosset\CommandLine\Argument\Option;
use jrosset\CommandLine\Argument\IArgument;
/**
* Interface of option arguments: --XXX or -X
*/
interface IOptionArgument extends IArgument {
/**
* The short tag (the -X form). Null if none
*
* @return string|null The short tag
*/
public function getTagShort (): ?string;
/**
* The long tag (the --XXX form)
*
* @return string The long tag
*/
public function getTagLong (): string;
}

@ -1,188 +0,0 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\Option\OptionAbstract.
*/
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\ArgumentAbstract;
/**
* Classe abstraite pour les arguments de type "option" : --xxx / -x
*
* @package CommandLine\Argument\Option
*/
abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOption {
/**
* @var string|null L'argument court (cas d'un seul "-"). Null si aucun.
*/
protected ?string $tagShort;
/**
* @var string L'argument long (cas d'un "--").
*/
protected string $tagLong;
/**
* @var boolean Est-ce que l'argument est autorisé plusieurs fois ?
*/
protected bool $multiple = false;
/**
* @var boolean Est-ce que l'argument met fin au parsage ?
*/
protected bool $isStoppingParse = false;
/**
* Crée un nouvel argument de type option.
*
* @param string $name Le nom.
* @param string|null $description La description.
* @param string|null $tagLong Le tag long.
* @param string|null $tagShort Le tag court.
*/
public function __construct (string $name, ?string $description, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description);
$this->setTagLong($tagLong);
$this->setTagShort($tagShort);
}
/**
* Est-ce la valeur correspond au tag court ou long ?
*
* Utilisé par les classes enfants pour savoir si le tag correspond.
*
* @param string $arg La valeur à examiner.
*
* @return boolean True si le tag correspond, sinon False.
*/
protected function _parseTag (string $arg): bool {
if ($this->hasTagShort()) {
if ($arg == '-' . $this->getTagShort()) {
return true;
}
}
return $arg == '--' . $this->getTagLong();
}
/**
* Est-ce que la liste de valeur contient un argument de type "option" ?
*
* @param string[] $args La liste de valeurs à tester
*
* @return string|false La valeur qui une option au False si aucune correspondance
*/
public static function containsOption (array $args) {
foreach ($args as $arg) {
if (preg_match('@^--?[a-zA-Z0-9_-]+@', $arg)) {
return $arg;
}
}
return false;
}
public function getTagShort (): ?string {
return $this->tagShort;
}
/**
* Définit le tag court.
*
* @param string|null $tagShort Le tage court.
*
* @return $this
*
* @see $tagShort
*/
public function setTagShort (string $tagShort = null): self {
$this->tagShort = $tagShort;
return $this;
}
/**
* Est-ce que l'argument existe en forme courte ?
*
* @return boolean True si existe en forme courte, sinon False.
*/
public function hasTagShort (): bool {
return !is_null($this->tagShort);
}
public function getTagLong (): string {
return $this->tagLong;
}
/**
* Définit le tag long.
*
* Si non fourni, est déduit du {@see $name nom de l'argument} :
* - Les "_" sont remplacés par "-"
* - Les lettres majuscules sont remplacées par "-" suivit de la lettre en minuscule
*
* @param string|null $tagLong Le tag long.
*
* @return $this
*
* @see $tagLong
*/
public function setTagLong (string $tagLong = null): self {
if (is_null($tagLong)) {
$this->tagLong = preg_replace_callback(
'/[A-Z_]/',
function ($matches) {
if ($matches[0] == '_') {
return '-';
}
else {
return '-' . strtolower($matches[0]);
}
},
$this->getName()
);
}
else {
$this->tagLong = $tagLong;
}
return $this;
}
public function allowMultiple (): bool {
return $this->multiple;
}
/**
* Définit si l'argument est autorisé plusieurs fois ou non.
*
* @param boolean $multiple Argument autorisé plusieurs fois ?
*
* @return $this
* @see $_optional
*/
public function setMultiple (bool $multiple): self {
if (!is_bool($multiple)) {
throw new InvalidArgumentException('La multiplicité n\'est pas un booléen');
}
$this->multiple = $multiple;
return $this;
}
public function isStoppingParse (): bool {
return $this->isStoppingParse;
}
/**
* Définit si l'argument met fin au parsage ou non.
*
* @param boolean $stoppingParse Met fin au parsage ?
*
* @return $this
* @see $_optional
*/
public function setStoppingParse (bool $stoppingParse): self {
if (!is_bool($stoppingParse)) {
throw new InvalidArgumentException('La stoppabilité n\'est pas un booléen');
}
$this->isStoppingParse = $stoppingParse;
return $this;
}
}

@ -0,0 +1,20 @@
<?php
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\AbstractArgumentList;
/**
* A list of value arguments
*/
class OptionArgumentList extends AbstractArgumentList {
/**
* @inheritDoc
*/
protected function checkArrayElementType ($key, $element): void {
if (!$element instanceof IOptionArgument) {
throw new InvalidArgumentException('The "' . $key . '" element is not a ' . IOptionArgument::class . ' instance');
}
}
}

@ -1,91 +1,158 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\Option\Value
*/
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\IArgumentValueDescription;
use jrosset\CommandLine\Argument\Parser\IValueParser;
use jrosset\CommandLine\Argument\ParseResult;
use jrosset\CommandLine\Exception\IncorrectParse;
use RuntimeException;
use jrosset\CommandLine\Argument\Parser\IParser;
use UnexpectedValueException;
/**
* Option contenant une valeur
*
* @package CommandLine\Argument\Option
* Option argument with possible values
*/
class Value extends OptionAbstract implements IArgumentValueDescription {
class Value extends AbstractOptionArgument implements IArgumentValueDescription {
/**
* @var IParser The values parser
*/
private IParser $valuesParser;
/**
* @var int The minimum number of values
*/
private int $valueOccurMin;
/**
* @var IValueParser Parseur pour la valeur
* @var int|null The maximum number of values. Null if unlimited
*/
protected IValueParser $valueParser;
private ?int $valueOccurMax;
/**
* Crée un nouvel argument de type option
* Create a new option argument
*
* @param string $name Le nom
* @param string|null $description La description
* @param IValueParser $valueParser Le parseur de valeur
* @param string|null $tagLong Le tag long
* @param string|null $tagShort Le tag court
* By default, the {@see AbstractArgument::$varName variable name} is the same as the {@see AbstractArgument::$name argument in help}
*
* @param string $name The argument name in help
* @param string|null $description The argument name in documentation
* @param IParser $valuesParser The value parser
* @param string|null $tagLong The long tag. If null, deduce from argument name <b>$name</b> (see {@see AbstractOptionArgument::convertNameToTagLong()}
* @param string|null $tagShort The short tag
*/
public function __construct (string $name, ?string $description, IValueParser $valueParser, ?string $tagLong = null, ?string $tagShort = null) {
public function __construct (string $name, ?string $description, IParser $valuesParser, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description, $tagLong, $tagShort);
$this->setValueParser($valueParser);
$this->setValuesParser($valuesParser);
$this->setValueOccurMin(1);
$this->setValueOccurMax(1);
}
/**
* @inheritDoc
*/
public function parse (array $args): ?ParseResult {
try {
if (!$this->_parseTag($args[0])) {
return null;
}
if (count($args) < 2 || is_null($args[1])) {
throw new IncorrectParse('La seconde valeur de l\'argument manquante');
}
public function getValueDescription (): string {
return $this->valuesParser->getValueDescription();
}
return new ParseResult($this->valueParser->parseValue($args[1]), 2);
}
catch (RuntimeException $e) {
throw new IncorrectParse('Échec du parsage de la valeur "' . $args[0] . '"', 0, $e);
}
/**
* The values parser
*
* @return IParser The values parser
*/
public function getValuesParser (): IParser {
return $this->valuesParser;
}
/**
* Set the values parser
*
* @param IParser $valuesParser The values parser
*
* @return $this
*/
public function setValuesParser (IParser $valuesParser): self {
$this->valuesParser = $valuesParser;
return $this;
}
/**
* @inheritDoc
* Is the value optional ?
*
* @return bool Is the value optional ?
*/
public function getValueDescription (): string {
return $this->valueParser->getValueDescription();
public function isValueOptional (): bool {
return $this->getValueOccurMin() === 0;
}
/**
* Set if the value is optional
*
* @param bool $optional Is the value optional ?
*
* @return $this
*/
public function setValueOptional (bool $optional): self {
$this->setValueOccurMin($optional ? 0 : 1);
return $this;
}
/**
* Le parseur de valeur.
* The minimum number of values
*
* @return IValueParser Le parseur.
* @return int The minimum number of values
*/
public function getValueOccurMin (): int {
return $this->valueOccurMin;
}
/**
* Set the minimum number of values
*
* @param int $valueOccurMin The minimum number of values
*
* @return $this
*
* @see $valueParser
* @throws InvalidArgumentException If the minimum number of values provided is not valid (strictly positive integer)
* @throws UnexpectedValueException If the minimum number of values provided is strictly greater than the maximum
*/
public function setValueOccurMin (int $valueOccurMin): self {
if (!is_numeric($valueOccurMin) || floor($valueOccurMin) != $valueOccurMin || ($valueOccurMin = (int)$valueOccurMin) < 0) {
throw new InvalidArgumentException('The minimum number of values must be a strictly positive integer');
}
$valueOccurMax = $this->getValueOccurMax();
if ($valueOccurMax !== null && $valueOccurMin > $valueOccurMax) {
throw new UnexpectedValueException('The minimum number of values provided is strictly greater than the maximum');
}
$this->valueOccurMin = $valueOccurMin;
return $this;
}
/**
* The maximum number of values. Null if unlimited
*
* @noinspection PhpUnused
* @return int|null The maximum number of value
*/
public function getValueParser (): IValueParser {
return $this->valueParser;
public function getValueOccurMax (): ?int {
return $this->valueOccurMax;
}
/**
* Définit le parseur de valeur
* Set the maximum number of values. Null if unlimited
*
* @param IValueParser $valueParser Le parseur
* @param int|null $valueOccurMax The maximum number of values
*
* @return $this
*
* @see $valueParser
* @throws InvalidArgumentException If the maximum number of values provided is not valid (strictly positive integer)
* @throws UnexpectedValueException If the maximum number of values provided is strictly lower than the minimum
*/
public function setValueParser (IValueParser $valueParser): self {
$this->valueParser = $valueParser;
public function setValueOccurMax (?int $valueOccurMax): self {
if ($valueOccurMax !== null) {
if (!is_numeric($valueOccurMax) || floor($valueOccurMax) != $valueOccurMax || ($valueOccurMax = (int)$valueOccurMax) < 0) {
throw new InvalidArgumentException('The maximum number of values must be a strictly positive integer');
}
if ($valueOccurMax < $this->getValueOccurMin()) {
throw new UnexpectedValueException('The maximum number of values is strictly lower than the minimum');
}
}
$this->valueOccurMax = $valueOccurMax;
return $this;
}
}

@ -1,80 +0,0 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\ParseResult.
*/
namespace jrosset\CommandLine\Argument;
/**
* Résultat du parsage d'un argument
*
* @package CommandLine\Argument
*/
class ParseResult {
/**
* @var int Le nombre d'argument consumé.
*/
protected int $consume;
/**
* @var mixed La valeur.
*/
protected $value;
/**
* ArgumentParseResult constructor.
*
* @param mixed $value La valeur.
* @param int $consume Le nombre d'argument consumé.
*/
public function __construct ($value, int $consume = 1) {
$this->setValue($value);
$this->setConsume($consume);
}
/**
* Le nombre d'argument consumé.
*
* @return int Le nombre d'argument consumé.
*
* @see $consume
*/
public function getConsume (): int {
return $this->consume;
}
/**
* Définit le nombre d'argument consumé.
*
* @param $consume int Le nombre d'argument consumé.
*
* @return $this
*
* @see $consume
*/
public function setConsume (int $consume): self {
$this->consume = $consume;
return $this;
}
/**
* La valeur.
*
* @return mixed La valeur.
*
* @see $value
*/
public function getValue() {
return $this->value;
}
/**
* Définit les valeurs définies.
*
* @param mixed $value La valeur.
*
* @return $this
*
* @see $value
*/
public function setValue ($value): self {
$this->value = $value;
return $this;
}
}

@ -15,7 +15,7 @@ use RangeException;
*
* @package CommandLine\Argument\Parser
*/
class BooleanParser implements IValueParser {
class BooleanParser implements IParser {
/**
* @inheritDoc
*/

@ -14,7 +14,7 @@ use RangeException;
*
* @noinspection PhpUnused
*/
class DecimalParser implements IValueParser {
class DecimalParser implements IParser {
/**
* @var double|null La valeur minimum autorisée. Null si pas de limite.
*/

@ -14,7 +14,7 @@ use RangeException;
*
* @noinspection PhpUnused
*/
class EnumParser implements IValueParser {
class EnumParser implements IParser {
/**
* @var string[] Liste des valeurs autorisées
*/

@ -1,6 +1,6 @@
<?php
/**
* Déclare l'interface CommandLine\Argument\Parser\IValueParser
* Déclare l'interface CommandLine\Argument\Parser\IParser
*/
namespace jrosset\CommandLine\Argument\Parser;
@ -9,7 +9,7 @@ namespace jrosset\CommandLine\Argument\Parser;
*
* @package CommandLine\Argument\Parser
*/
interface IValueParser {
interface IParser {
/**
* Vérifie et transforme une valeur.
*

@ -13,7 +13,7 @@ use RangeException;
*
* @package CommandLine\Argument\Parser
*/
class IntegerParser implements IValueParser {
class IntegerParser implements IParser {
/**
* @var int|null La valeur minimum autorisée. Null si pas de limite.
*/

@ -20,7 +20,7 @@ use UnexpectedValueException;
*
* @package CommandLine\Argument\Parser
*/
class PathParser implements IValueParser {
class PathParser implements IParser {
/**
* @var string[] Les expressions régulières pour identifier un chemin
*/

@ -15,7 +15,7 @@ use RangeException;
*
* @noinspection PhpUnused
*/
class RegexParser implements IValueParser {
class RegexParser implements IParser {
/**
* @var string La regex à respecter
*/

@ -11,7 +11,7 @@ namespace jrosset\CommandLine\Argument\Parser;
*
* @noinspection PhpUnused
*/
class StringParser implements IValueParser {
class StringParser implements IParser {
/**
* @inheritDoc
*/

@ -0,0 +1,117 @@
<?php
namespace jrosset\CommandLine\Argument\Value;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\AbstractArgument;
use UnexpectedValueException;
/**
* Abstract base for value arguments
*/
abstract class AbstractValueArgument extends AbstractArgument implements IValueArgument {
/**
* @var int The minimum number of values
*/
protected int $occurMin = 1;
/**
* @var int|null The maximum number of values. Null if unlimited
*/
protected ?int $occurMax = 1;
/**
* Create a new value argument
*
* @param string $name The argument name in help
* @param string|null $description The argument description in help
* @param boolean $optional Optional argument ?
* @param mixed $default The default value
*/
protected function __construct (string $name, ?string $description, bool $optional = false, $default = null) {
parent::__construct($name, $description);
$this->setOptional($optional);
$this->setDefault($default);
}
/**
* Is the argument optional ?
*
* @return bool Is the argument optional ?
*/
public function isOptional (): bool {
return $this->getOccurMin() === 0;
}
/**
* Set if the argument is optional
*
* @param bool $optional Is the argument optional ?
*
* @return $this
*/
public function setOptional (bool $optional): self {
$this->setOccurMin($optional ? 0 : 1);
return $this;
}
/**
* @inheritDoc
*/
public function getOccurMin (): int {
return $this->occurMin;
}
/**
* Set the minimum number of occurrence of values
*
* @param int $occurMin The minimum number of occurrence of values
*
* @return $this
*
* @throws InvalidArgumentException If the minimum number of occurrence of values provided is not valid (strictly positive integer)
* @throws UnexpectedValueException If the minimum number of occurrence of values provided is strictly greater than the maximum
*/
public function setOccurMin (int $occurMin): self {
if (!is_numeric($occurMin) || floor($occurMin) != $occurMin || ($occurMin = (int)$occurMin) < 0) {
throw new InvalidArgumentException('The minimum number of values must be a strictly positive integer');
}
$occurMax = $this->getOccurMax();
if ($occurMax !== null && $occurMin > $occurMax) {
throw new UnexpectedValueException('The minimum number of values provided is strictly greater than the maximum');
}
$this->occurMin = $occurMin;
return $this;
}
/**
* @inheritDoc
*/
public function getOccurMax (): ?int {
return $this->occurMax;
}
/**
* Set the maximum number of occurrence of values. Null if unlimited
*
* @param int|null $occurMax The maximum number of occurrence of values
*
* @return $this
*
* @throws InvalidArgumentException If the maximum number of occurrence of values provided is not valid (strictly positive integer)
* @throws UnexpectedValueException If the maximum number of occurrence of values provided is strictly lower than the minimum
*/
public function setOccurMax (?int $occurMax): self {
if ($occurMax !== null) {
if (!is_numeric($occurMax) || floor($occurMax) != $occurMax || ($occurMax = (int)$occurMax) < 0) {
throw new InvalidArgumentException('The maximum number of values must be a strictly positive integer');
}
if ($occurMax < $this->getOccurMin()) {
throw new UnexpectedValueException('The maximum number of values is strictly lower than the minimum');
}
}
$this->occurMax = $occurMax;
return $this;
}
}

@ -1,77 +0,0 @@
<?php
/**
* Déclaration de CommandLine\Argument\Value\FixedValue
*/
namespace jrosset\CommandLine\Argument\Value;
use jrosset\CommandLine\Argument\IArgumentValueDescription;
use jrosset\CommandLine\Argument\ParseResult;
/**
* Argument devant correspondre une valeur fixe
*
* @package CommandLine\Argument
*
* @noinspection PhpUnused
*/
class FixedValue extends ValueAbstract implements IArgumentValueDescription {
/**
* @var string La valeur que doit avoir l'argument
*/
protected string $value;
/**
* Crée un nouvel argument de type valeur
*
* @param string $varName Le nom de la variable
* @param string $value La valeur
* @param string|null $description La description
* @param boolean $optional Valeur optionnelle ?
*/
public function __construct (string $varName, string $value, ?string $description, bool $optional) {
parent::__construct($value, $description, $optional);
$this->setVarName($varName);
$this->setValue($value);
}
/**
* @inheritDoc
*/
public function parse (array $args): ?ParseResult {
if ($args[0] == $this->getValue()) {
return new ParseResult($this->getValue(), 1);
}
return null;
}
/**
* @inheritDoc
*/
public function getValueDescription (): string {
return '"' . $this->getValue() . '"';
}
/**
* La valeur.
*
* @return string La valeur.
*
* @see $value
*/
public function getValue (): string {
return $this->value;
}
/**
* Définit la valeur
*
* @param string $value La valeur
*
* @return $this
* @see $value
*/
public function setValue (string $value): self {
$this->value = $value;
return $this;
}
}

@ -1,31 +0,0 @@
<?php
/**
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentValue
*/
namespace jrosset\CommandLine\Argument\Value;
use jrosset\CommandLine\Argument\IArgument;
/**
* Interface à implémenter si l'argument est de type "valeur"
*
* @package CommandLine\Argument\value
*/
interface IArgumentValue extends IArgument {
/**
* Le nombre minimum d'occurence.
*
* Généralement 0 (falcultatif) ou 1 (obligatoire).
*
* @return int Le nombre minimum d'occurence
*/
public function getOccurMin (): int;
/**
* Le nombre maximum d'occurence.
*
* Généralement 1 ou Null (illimité).
*
* @return int|null Le nombre maximum d'occurence
*/
public function getOccurMax (): ?int;
}

@ -0,0 +1,23 @@
<?php
namespace jrosset\CommandLine\Argument\Value;
use jrosset\CommandLine\Argument\IArgument;
/**
* Interface of value arguments
*/
interface IValueArgument extends IArgument {
/**
* The minimum number of occurrence of argument
*
* @return int The minimum number of occurrence of values
*/
public function getOccurMin (): int;
/**
* The maximum number of occurrence of values. Null if unlimited
*
* @return int|null The maximum of occurrence number of value
*/
public function getOccurMax (): ?int;
}

@ -1,82 +1,61 @@
<?php
/**
* Déclaration de CommandLine\Argument\Value\Value
*/
namespace jrosset\CommandLine\Argument\Value;
use jrosset\CommandLine\Argument\IArgumentValueDescription;
use jrosset\CommandLine\Argument\Parser\IValueParser;
use jrosset\CommandLine\Argument\ParseResult;
use jrosset\CommandLine\Exception\IncorrectParse;
use RangeException;
use jrosset\CommandLine\Argument\Parser\IParser;
/**
* Argument de type "valeur"
*
* @package CommandLine\Argument\Value
*/
class Value extends ValueAbstract implements IArgumentValueDescription {
class Value extends AbstractValueArgument implements IArgumentValueDescription {
/**
* @var IValueParser Parseur pour la valeur
* @var IParser The values parser
*/
protected IValueParser $valueParser;
private IParser $valuesParser;
/**
* Crée un nouvel argument de type valeur
* Create a new value argument
*
* @param string $name Le nom
* @param string|null $description La description
* @param IValueParser $valueParser Le parseur de valeur.
* @param boolean $optional Valeur optionnelle ?
*/
public function __construct (string $name, ?string $description, IValueParser $valueParser, bool $optional) {
parent::__construct($name, $description, $optional);
$this->setValueParser($valueParser);
}
/**
* @inheritDoc
* By default, the {@see AbstractArgument::$varName variable name} is the same as the {@see AbstractArgument::$name argument in help}
*
* @param string $name The argument name in help
* @param string|null $description The argument name in documentation
* @param IParser $valuesParser The value parser
* @param boolean $optional Optional argument ?
* @param mixed $default The default value
*/
public function parse (array $args): ?ParseResult {
try {
return new ParseResult($this->valueParser->parseValue($args[0]), 1);
}
catch (RangeException $e) {
throw new IncorrectParse('Échec du parsage de la valeur "' . $args[0] . '"', 0, $e);
}
public function __construct (string $name, ?string $description, IParser $valuesParser, bool $optional = false, $default = null) {
parent::__construct($name, $description, $optional, $default);
$this->setValuesParser($valuesParser);
}
/**
* @inheritDoc
*/
public function getValueDescription (): string {
return $this->valueParser->getValueDescription();
return $this->valuesParser->getValueDescription();
}
/**
* Le parseur de valeur.
* The values parser
*
* @return IValueParser Le parseur.
*
* @see $valueParser
*
* @noinspection PhpUnused
* @return IParser The values parser
*/
public function getValueParser (): IValueParser {
return $this->valueParser;
public function getValuesParser (): IParser {
return $this->valuesParser;
}
/**
* Définit le parseur de valeur
* Set the values parser
*
* @param IValueParser $valueParser Le parseur
* @param IParser $valuesParser The values parser
*
* @return $this
*
* @see $valueParser
*/
public function setValueParser (IValueParser $valueParser): self {
$this->valueParser = $valueParser;
public function setValuesParser (IParser $valuesParser): self {
$this->valuesParser = $valuesParser;
return $this;
}
}

@ -1,127 +0,0 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\Value\ValueArgument.
*/
namespace jrosset\CommandLine\Argument\Value;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\ArgumentAbstract;
/**
* Classe abstraite pour les paramètres de type "valeur"
*
* @package CommandLine\Argument\Value
*/
abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue {
/**
* @var int Le nombre minimum d'occurence.
*/
protected int $occurMin = 1;
/**
* @var int|null Le nombre maximum d'occurence. Null si illimité
*/
protected ?int $occurMax = 1;
/**
* Crée un nouvel argument.
*
* @param string $name Le nom de l'argument
* @param string|null $description La description de l'argument
* @param boolean $optional Argument optionel ?
*/
protected function __construct (string $name, ?string $description, bool $optional) {
parent::__construct($name, $description);
$this->setOptional($optional);
}
/**
* Est-ce que l'argument est facultatif ?
*
* @return bool Est-ce que l'argument est facultatif ?
*
* @noinspection PhpUnused
*/
public function isOptional (): bool {
return $this->getOccurMin() === 0;
}
/**
* Définit si l'argument est facultatif ou non.
*
* @param bool $optional Argument facultatif ?
*
* @return $this
*/
public function setOptional (bool $optional): self {
$this->setOccurMin($optional ? 0 : 1);
return $this;
}
/**
* @inheritDoc
*/
public function getOccurMin (): int {
return $this->occurMin;
}
/**
* Définit le nombre minimum d'occurence.
*
* @param int $occurMin Le nombre minimum
*
* @return $this
* @see $occurMin
*/
public function setOccurMin (int $occurMin): self {
if (!is_numeric($occurMin)) {
throw new InvalidArgumentException('Le nombre minimum d\'ocurrence n\'est pas un entier');
}
if (floor($occurMin) != $occurMin) {
throw new InvalidArgumentException('Le nombre minimum d\'ocurrence n\'est pas un entier');
}
$int = (int)$occurMin;
if ($int < 0) {
throw new InvalidArgumentException('Le nombre minimum d\'ocurrence n\'est pas un entier positif');
}
$this->occurMin = $int;
return $this;
}
/**
* @inheritDoc
*/
public function getOccurMax (): ?int {
return $this->occurMax;
}
/**
* Définit le nombre maximum d'occurence.
*
* @param int|null $occurMax Le nombre maximum. Null si illimité
*
* @return $this
* @see $occurMax
*/
public function setOccurMax (?int $occurMax): self {
if (!is_null($occurMax)) {
if (!is_numeric($occurMax)) {
throw new InvalidArgumentException('Le nombre maximum d\'ocurrence n\'est pas un entier');
}
if (floor($occurMax) != $occurMax) {
throw new InvalidArgumentException('Le nombre maximum d\'ocurrence n\'est pas un entier');
}
$occurMax = (int)$occurMax;
if ($occurMax <= 0) {
throw new InvalidArgumentException('Le nombre maximum d\'ocurrence n\'est pas un entier strictement positif');
}
}
$this->occurMax = $occurMax;
return $this;
}
}

@ -0,0 +1,20 @@
<?php
namespace jrosset\CommandLine\Argument\Value;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\AbstractArgumentList;
/**
* A list of value arguments
*/
class ValueArgumentList extends AbstractArgumentList {
/**
* @inheritDoc
*/
protected function checkArrayElementType ($key, $element): void {
if (!$element instanceof IValueArgument) {
throw new InvalidArgumentException('The "' . $key . '" element is not a ' . IValueArgument::class . ' instance');
}
}
}

@ -0,0 +1,130 @@
<?php
namespace jrosset\CommandLine;
use InvalidArgumentException;
/**
* An object-oriented class for an array
*
* @template T
*/
class ArrayClass {
/**
* @var T[] The internal array
*/
private array $array;
/**
* Create an empty array
*/
public function __construct () {
$this->setAll([]);
}
/**
* Get all elements of the array
*
* @return T[] all elements of the array
*/
public function getAll (): array {
return $this->array;
}
/**
* <b>Replace</b> all elements of the array
*
* @param T[] $array The new list of elements
*
* @return $this
*
* @throws InvalidArgumentException If an element of the array is not valid
*
* @see ArrayClass::add()
*/
public function setAll (array $array): self {
self::checkArrayType($array);
$this->array = [];
foreach ($array as $element) {
$this->add($element);
}
return $this;
}
/**
* Add one or an array of elements
*
* @param T|T[] $elements The element(s) to add
*
* @return $this
*
* @throws InvalidArgumentException If an element of the array is not valid
*/
public function add ($elements): self {
if (!is_array($elements)) {
$elements = [$elements];
}
$this->checkArrayType($elements);
$realArray = [];
foreach ($elements as $element) {
$key = $this->getKeyForElement($element);
if ($key === null) {
$realArray[] = $element;
}
else {
$realArray[$key] = $element;
}
}
$this->array = array_merge($this->array, $realArray);
return $this;
}
/**
* Check if a element exists from his key
*
* @param int|string $elementKey The element key to check
*
* @return bool True if the element exists, else False
*/
public function exists ($elementKey): bool {
return isset($this->getAll()[$elementKey]);
}
/**
* Check if all elements of the parameter array are valid
*
* @param T[] $array The array to check
*
* @throws InvalidArgumentException If an element of the array is not valid
*
* @see ArrayClass::$checker
*/
protected function checkArrayType (array $array): void {
foreach ($array as $arrayKey => $arrayElement) {
$this->checkArrayElementType($arrayKey, $arrayElement);
}
}
/**
* Check if the element of the array is valid
*
* @param int|string $key The key of the element
* @param T $element The element to check
*
* @throws InvalidArgumentException If the element is not valid
*/
protected function checkArrayElementType ($key, $element): void {}
/**
* Get the key of an element. Null if auto-generated
*
* @param T $element The element
*
* @return int|string|null The key or Null
* @noinspection PhpReturnDocTypeMismatchInspection
*/
protected function getKeyForElement ($element) {
return null;
}
}

@ -1,18 +1,15 @@
<?php
/**
* Déclaration de la classe CommandLine\CommandLine
*/
namespace jrosset\CommandLine;
use InvalidArgumentException;
use jrosset\CommandLine\Argument\IArgument;
use jrosset\CommandLine\Argument\IArgumentValueDescription;
use jrosset\CommandLine\Argument\Option\IArgumentOption;
use jrosset\CommandLine\Argument\Option\OptionAbstract;
use jrosset\CommandLine\Argument\Option\IOptionArgument;
use jrosset\CommandLine\Argument\Option\AbstractOptionArgument;
use jrosset\CommandLine\Argument\ParseResult;
use jrosset\CommandLine\Argument\Value\IArgumentValue;
use jrosset\CommandLine\Argument\Value\ValueAbstract;
use jrosset\CommandLine\Argument\Value\IValueArgument;
use jrosset\CommandLine\Argument\Value\AbstractValueArgument;
use jrosset\CommandLine\Exception\IncorrectParse;
use jrosset\CommandLine\Exception\MissingArgument;
use jrosset\CommandLine\Exception\TooMuchValues;
@ -22,65 +19,47 @@ use stdClass;
use Throwable;
/**
* Une ligne de commande (description, arguments, etc.)
*
* A la base, chaque type d'argument doit au minimum implémenter {@see IArgument}.
* Mais il faut implémenter l'un des deux grands types d'arguments :
* - {@see IArgumentOption} (implémentation de base avec {@see OptionAbstract}) Options : commencent par un "-" (version courte) ou "--" (version longue)
* - {@see IArgumentValue} (implémentation de base avec {@see ValueAbstract} ) Valeurs : une valeur directe
*
* Le traitement de la ligne de commande est généralement faite dans cet ordre :
* - Création ligne de commande : définition des propriétés du script lui-même (nom, description, etc.)
* - Définition des arguments
* - Parsage des arguments du script : {@see CommandLine::parse() fonction parse}
* - Traitement des valeurs extraites des arguments du script (résultat de la {@see CommandLine::parse() fonction parse})
*
* @package CommandLine
* The command line
*/
class CommandLine {
/**
* Chaine de caractère se substituant à la tabulation pour la construction de l'aide (help).
* Argument name for help auto-generated argument
*/
const TAB = ' ';
protected const ARGUMENT_OPTION_HELP = 'help';
/**
* Nom de l'argument auto-généré pour l'affichage de l'aide.
*
* @see CommandLine::addDefaultArguments()
* @see CommandLine::generateHelp()
* Argument name for version auto-generated argument
*/
const ARGUMENT_OPTION_HELP = 'help';
protected const ARGUMENT_OPTION_VERSION = 'version';
/**
* Nom de l'argument auto-généré pour l'affichage de la version.
*
* @see CommandLine::addDefaultArguments()
* @see CommandLine::getVersion()
* @var string Indentation string used in help
*/
const ARGUMENT_OPTION_VERSION = 'version';
private string $helpIndent = ' ';
/**
* @var string|null La commande de lancement du script (si non fourni, égal au {@see CommandeLine::_programName nom du programme})
* @var string|null The command to launch the current command line.
* If null, equal to programme name
*/
protected ?string $command;
private ?string $command;
/**
* @var string Le nom du programme
* @var string The program name
*/
protected string $programName;
private string $programName;
/**
* @var string Description du programme
* @var string The program description
*/
protected string $description;
private string $description;
/**
* @var string|null La version du programme.
* @var string|null The program version
*/
protected ?string $version;
private ?string $version;
/**
* @var IArgumentOption[] Liste des options de la ligne de commande
* @var IOptionArgument[] Liste des options de la ligne de commande
*/
protected array $argumentsOptions = array();
/**
* @var IArgumentValue[] Liste _ordonnée_ des arguments "valeur" de la ligne de commande
* @var IValueArgument[] Liste _ordonnée_ des arguments "valeur" de la ligne de commande
*/
protected array $argumentsValues = array();
@ -199,7 +178,7 @@ class CommandLine {
/**
* La liste des arguments "value"
*
* @return IArgumentValue[] La liste des valeurs
* @return IValueArgument[] La liste des valeurs
* @see CommandLine::$argumentsValues
*/
public function getValues (): array {
@ -211,7 +190,7 @@ class CommandLine {
* *Attention* : cette fonction _remplace_ la liste des valeurs.
* Pour seulement en ajouter, utiliser {@see CommandLine::addValues()}
*
* @param IArgumentValue[] $values La nouvelle liste de valeurs
* @param IValueArgument[] $values La nouvelle liste de valeurs
*
* @return $this
* @see CommandLine::$argumentsValues
@ -227,13 +206,13 @@ class CommandLine {
*
* Pour ajouter une seule valeur, il est conseillé d'utiliser {@see CommandLine::addValue()}
*
* @param IArgumentValue[]|IArgumentValue $values La liste des valeurs à ajouter
* @param IValueArgument[]|IValueArgument $values La liste des valeurs à ajouter
*
* @return $this
* @see CommandLine::$argumentsValues
*/
public function addValues ($values): self {
if (!is_array($values) && $values instanceof IArgumentValue) {
if (!is_array($values) && $values instanceof IValueArgument) {
$values = array($values);
}
self::_checkValueList($values);
@ -246,12 +225,12 @@ class CommandLine {
*
* Pour ajouter plusieurs valeurs à la fois, il est conseillé d'utiliser {@see CommandLine::addValues()}
*
* @param IArgumentValue $value La valeur à ajouter
* @param IValueArgument $value La valeur à ajouter
*
* @return $this
* @see CommandLine::$argumentsValues
*/
public function addValue (IArgumentValue $value): self {
public function addValue (IValueArgument $value): self {
return $this->addValues(array($value));
}
/**
@ -278,14 +257,14 @@ class CommandLine {
* @return bool True si c'est bien un argument "value", sinon False
*/
public static function isValue ($argument): bool {
return $argument instanceof IArgumentValue;
return $argument instanceof IValueArgument;
}
/**
* Vérifie que la liste d'arguments "value" est valide
*
* Doit être un tableau et chaque élément doit implémenter {@see IArgumentValue}
* Doit être un tableau et chaque élément doit implémenter {@see IValueArgument}
*
* @param IArgumentValue[] $values Les valeurs à vérifier
* @param IValueArgument[] $values Les valeurs à vérifier
*/
protected static function _checkValueList (array $values) {
if (!is_array($values)) {
@ -293,7 +272,7 @@ class CommandLine {
}
foreach ($values as $key => $value) {
if (!self::isValue($value)) {
throw new InvalidArgumentException('La valeur ' . $key . ' n\'est pas valide (n\'implémente pas IArgumentValue)');
throw new InvalidArgumentException('La valeur ' . $key . ' n\'est pas valide (n\'implémente pas IValueArgument)');
}
}
}
@ -301,7 +280,7 @@ class CommandLine {
/**
* La liste des arguments "option"
*
* @return IArgumentOption[] La liste des options
* @return IOptionArgument[] La liste des options
* @see CommandLine::$argumentsOptions
*/
public function getOptions (): array {
@ -313,7 +292,7 @@ class CommandLine {
* *Attention* : cette fonction _remplace_ la liste des options.
* Pour seulement en ajouter, utiliser {@see CommandLine::addOptions()}
*
* @param IArgumentOption[] $options La nouvelle liste d'options
* @param IOptionArgument[] $options La nouvelle liste d'options
*
* @return $this
* @see CommandLine::$argumentsOptions
@ -329,13 +308,13 @@ class CommandLine {
*
* Pour ajouter une seule option, il est conseillé d'utiliser {@see CommandLine::addOption()}
*
* @param IArgumentOption[]|IArgumentOption $options La liste d'options à ajouter
* @param IOptionArgument[]|IOptionArgument $options La liste d'options à ajouter
*
* @return $this
* @see CommandLine::$argumentsOptions
*/
public function addOptions ($options): self {
if (!is_array($options) && $options instanceof IArgumentOption) {
if (!is_array($options) && $options instanceof IOptionArgument) {
$options = array($options);
}
self::_checkOptionList($options);
@ -348,12 +327,12 @@ class CommandLine {
*
* Pour ajouter plusieurs options à la fois, il est conseillé d'utiliser {@see CommandLine::addOptions()}
*
* @param IArgumentOption $option L'options à ajouter
* @param IOptionArgument $option L'options à ajouter
*
* @return $this
* @see CommandLine::$argumentsOptions
*/
public function addOption (IArgumentOption $option): self {
public function addOption (IOptionArgument $option): self {
return $this->addOptions(array($option));
}
/**
@ -380,14 +359,14 @@ class CommandLine {
* @return bool True si c'est bien un argument "option", sinon False
*/
public static function isOption ($argument): bool {
return $argument instanceof IArgumentOption;
return $argument instanceof IOptionArgument;
}
/**
* Vérifie que la liste d'arguments "option" est valide
*
* Doit être un tableau et chaque élément doit implémenter {@see IArgumentOption}
* Doit être un tableau et chaque élément doit implémenter {@see IOptionArgument}
*
* @param IArgumentOption[] $options Les options à vérifier
* @param IOptionArgument[] $options Les options à vérifier
*/
protected static function _checkOptionList (array $options) {
if (!is_array($options)) {
@ -395,7 +374,7 @@ class CommandLine {
}
foreach ($options as $key => $option) {
if (!self::isOption($option)) {
throw new InvalidArgumentException('L\'option ' . $key . ' n\'est pas valide (n\'implémente pas IArgumentOption)');
throw new InvalidArgumentException('L\'option ' . $key . ' n\'est pas valide (n\'implémente pas IOptionArgument)');
}
}
}
@ -414,7 +393,7 @@ class CommandLine {
* *Attention* : cette fonction _remplace_ la liste des arguments.
* Pour seulement en ajouter, utiliser {@see CommandLine::addArguments()}
*
* @param IArgumentValue[] $arguments La nouvelle liste d'arguments
* @param IValueArgument[] $arguments La nouvelle liste d'arguments
*
* @return $this
*/
@ -434,7 +413,7 @@ class CommandLine {
* @return $this
*/
public function addArguments ($arguments): self {
if (!is_array($arguments) && $arguments instanceof IArgumentValue) {
if (!is_array($arguments) && $arguments instanceof IValueArgument) {
$arguments = array($arguments);
}
self::_checkValueList($arguments);
@ -460,11 +439,11 @@ class CommandLine {
}
if (self::isOption($argument)) {
/** @var IArgumentOption $argument */
/** @var IOptionArgument $argument */
$this->addOption($argument);
}
elseif (self::isValue($argument)) {
/** @var IArgumentValue $argument */
/** @var IValueArgument $argument */
$this->addValue($argument);
}
else {
@ -749,12 +728,12 @@ class CommandLine {
/**
* La syntax d'un argument "value"
*
* @param IArgumentValue $value L'argument
* @param IValueArgument $value L'argument
*
* @return string La syntax de l'argument
* @see generateHelp()
*/
protected static function getSyntaxOfValue (IArgumentValue $value): string {
protected static function getSyntaxOfValue (IValueArgument $value): string {
$syntax = '';
$min = $value->getOccurMin();
@ -789,7 +768,7 @@ class CommandLine {
/**
* Génère l'aide d'une liste d'arguments "value"
*
* @param IArgumentValue[] $values La liste des valeurs
* @param IValueArgument[] $values La liste des valeurs
*
* @return string[] L'aide de chaque valeur
*/
@ -859,11 +838,11 @@ class CommandLine {
$entry[] = preg_replace(
'@\r?\n@',
'$0' . self::TAB . implode(self::TAB, $spaces),
'$0' . self::HELP_INDENT . implode(self::HELP_INDENT, $spaces),
$value->getDescription()
);
$entries[] = self::TAB . implode(self::TAB, $entry);
$entries[] = self::HELP_INDENT . implode(self::HELP_INDENT, $entry);
}
return $entries;
@ -871,7 +850,7 @@ class CommandLine {
/**
* Génère l'aide d'une liste d'arguments "option"
*
* @param IArgumentOption[] $options La liste des options
* @param IOptionArgument[] $options La liste des options
*
* @return string[] L'aide de chaque option
*/
@ -944,11 +923,11 @@ class CommandLine {
$entry[] = preg_replace(
'@\r?\n@',
'$0' . self::TAB . implode(self::TAB, $spaces),
'$0' . self::HELP_INDENT . implode(self::HELP_INDENT, $spaces),
$option->getDescription()
);
$entries[] = self::TAB . implode(self::TAB, $entry);
$entries[] = self::HELP_INDENT . implode(self::HELP_INDENT, $entry);
}
return $entries;
@ -983,11 +962,11 @@ class CommandLine {
$entry[] = str_pad($code, $pads->codes, ' ', STR_PAD_RIGHT);
$entry[] = preg_replace(
'@\r?\n@',
'$0' . self::TAB . str_repeat(' ', $pads->codes) . self::TAB,
'$0' . self::HELP_INDENT . str_repeat(' ', $pads->codes) . self::HELP_INDENT,
$description
);
$entries[] = self::TAB . implode(self::TAB, $entry);
$entries[] = self::HELP_INDENT . implode(self::HELP_INDENT, $entry);
}
return $entries;
@ -1065,7 +1044,7 @@ class CommandLine {
return $out;
}
if (($arg = OptionAbstract::containsOption($argv)) !== false) {
if (($arg = AbstractOptionArgument::containsOption($argv)) !== false) {
throw new IncorrectParse('Option inconnue : ' . $arg);
}
@ -1080,7 +1059,7 @@ class CommandLine {
/**
* @var int $ordre
* @var IArgumentValue $value
* @var IValueArgument $value
*/
foreach ($values as $ordre => $value) {
$min = $value->getOccurMin();
@ -1147,7 +1126,7 @@ class CommandLine {
$nb = 0;
/**
* @var int $ordre
* @var IArgumentValue $argument
* @var IValueArgument $argument
*/
foreach (array_values($this->getValues()) as $ordre => $argument) {
if ($ordre <= $ordre_start) {
@ -1169,7 +1148,7 @@ class CommandLine {
*
* @param string[] $argv La liste des arguments du script
* @param stdClass $out Les valeurs de sortie
* @param IArgumentOption[] $options La liste des options
* @param IOptionArgument[] $options La liste des options
* @param boolean $stop Arrêt du parsage ?
*
* @throws IncorrectParse Si le parsage d'une des options échoue
@ -1210,14 +1189,14 @@ class CommandLine {
*
* @param string[] $argv Liste des arguments du script
* @param stdClass $out Les valeurs de sortie
* @param IArgumentValue $value L'argument "value" à parser
* @param IValueArgument $value L'argument "value" à parser
* @param int $xTimes Le nombre de fois à parser
* @param int $offset L'offset pour le n° d'occurence
*
* @throws MissingArgument Si l'argument n'est pas en quantité suffisante
* @throws IncorrectParse Si l'argument échoue à se parser
*/
protected static function _parseXTimes (array &$argv, stdClass &$out, IArgumentValue $value, int $xTimes, int $offset = 0) {
protected static function _parseXTimes (array &$argv, stdClass &$out, IValueArgument $value, int $xTimes, int $offset = 0) {
if ($xTimes > count($argv)) {
throw new MissingArgument('L\'argument ' . $value->getName() . ' est en quantité insuffisante (' . count($argv) . ' / ' . $xTimes . ')');
}

@ -0,0 +1,21 @@
<?php
namespace jrosset\CommandLine\ReturnCode;
/**
* Interface for a return code
*/
interface IReturnCode {
/**
* The returned code
*
* @return int The returned code
*/
public function getCode (): int;
/**
* The description of the return code
*
* @return string|null The description of the return code
*/
public function getDescription (): ?string;
}

@ -0,0 +1,64 @@
<?php
namespace jrosset\CommandLine\ReturnCode;
/**
* A return code
*/
class ReturnCode implements IReturnCode {
/**
* @var int The returned code
*/
private int $code;
/**
* @var string|null The description of the return code
*/
private ?string $description;
/**
* Create a new return code
*
* @param int $code The returned code
* @param string|null $description The description of the return code
*/
public function __construct (int $code, ?string $description = null) {
$this->setCode($code);
$this->setDescription($description);
}
/**
* @inheritDoc
*/
public function getCode (): int {
return $this->code;
}
/**
* Set the returned code
*
* @param int $code The returned code
*
* @return $this
*/
public function setCode (int $code): self {
$this->code = $code;
return $this;
}
/**
* @inheritDoc
*/
public function getDescription (): ?string {
return $this->description;
}
/**
* Set the description of the return code
*
* @param string|null $description The description of the return code
*
* @return $this
*/
public function setDescription (?string $description): self {
$this->description = $description;
return $this;
}
}

@ -0,0 +1,35 @@
<?php
namespace jrosset\CommandLine\ReturnCode;
use InvalidArgumentException;
use jrosset\CommandLine\ArrayClass;
use ReflectionClass;
use ReflectionException;
/**
* A list of return codes
*
* @extends ArrayClass<IReturnCode>
*/
class ReturnCodeList extends ArrayClass {
/**
* @inheritDoc
*/
protected function checkArrayElementType ($key, $element): void {
if (!$element instanceof IReturnCode) {
throw new InvalidArgumentException('The "' . $key . '" element is not a ' . IReturnCode::class . ' instance');
}
}
/**
* Get the key of an element. Null if auto-generated
*
* @param IReturnCode $element The element
*
* @return int The key or Null
*/
protected function getKeyForElement ($element): int {
return $element->getCode();
}
}
Loading…
Cancel
Save