Initial commit
commit
b89af5c6da
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State />
|
||||
<State>
|
||||
<id>PHP</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>SQL</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>SqlResolveInspection</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ScopeChooserConfigurable.UI">
|
||||
<settings>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,115 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="AUTODETECT_INDENTS" value="false" />
|
||||
<option name="RIGHT_MARGIN" value="190" />
|
||||
<HTMLCodeStyleSettings>
|
||||
<option name="HTML_ATTRIBUTE_WRAP" value="4" />
|
||||
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||
<option name="HTML_ELEMENTS_TO_INSERT_NEW_LINE_BEFORE" value="body,div,p,form,h1,h2,h3,br" />
|
||||
<option name="HTML_DO_NOT_INDENT_CHILDREN_OF" value="html" />
|
||||
<option name="HTML_DONT_ADD_BREAKS_IF_INLINE_CONTENT" value="title,h1,h2,h3,h4,h5,h6" />
|
||||
<option name="HTML_NEWLINE_BEFORE_FIRST_ATTRIBUTE" value="When multiline" />
|
||||
<option name="HTML_NEWLINE_AFTER_LAST_ATTRIBUTE" value="When multiline" />
|
||||
</HTMLCodeStyleSettings>
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="SPACE_BEFORE_ASYNC_ARROW_LPAREN" value="false" />
|
||||
</JSCodeStyleSettings>
|
||||
<JSON>
|
||||
<option name="PROPERTY_ALIGNMENT" value="1" />
|
||||
<option name="ARRAY_WRAPPING" value="5" />
|
||||
</JSON>
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="ALIGN_KEY_VALUE_PAIRS" value="true" />
|
||||
<option name="ALIGN_PHPDOC_PARAM_NAMES" value="true" />
|
||||
<option name="ALIGN_PHPDOC_COMMENTS" value="true" />
|
||||
<option name="CONCAT_SPACES" value="false" />
|
||||
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
<option name="ELSE_IF_STYLE" value="COMBINE" />
|
||||
<option name="VARIABLE_NAMING_STYLE" value="CAMEL_CASE" />
|
||||
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
|
||||
<option name="ALIGN_CLASS_CONSTANTS" value="true" />
|
||||
<option name="BLANK_LINES_AROUND_CONSTANTS" value="1" />
|
||||
<option name="BLANK_LINES_AFTER_FUNCTION" value="0" />
|
||||
<option name="KEEP_BLANK_LINES_AFTER_LBRACE" value="0" />
|
||||
<option name="SPACE_BETWEEN_TERNARY_QUEST_AND_COLON" value="true" />
|
||||
</PHPCodeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<option name="SPACE_WITHIN_BRACKETS" value="true" />
|
||||
<option name="SPACE_WITHIN_BRACES" value="true" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="RIGHT_MARGIN" value="160" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="0" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="3" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="BLANK_LINES_BEFORE_PACKAGE" value="0" />
|
||||
<option name="BLANK_LINES_AROUND_FIELD" value="1" />
|
||||
<option name="BLANK_LINES_AROUND_METHOD" value="0" />
|
||||
<option name="CLASS_BRACE_STYLE" value="1" />
|
||||
<option name="METHOD_BRACE_STYLE" value="1" />
|
||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||
<option name="INDENT_BREAK_FROM_CASE" value="false" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
|
||||
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
|
||||
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
|
||||
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="5" />
|
||||
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
|
||||
<arrangement>
|
||||
<groups>
|
||||
<group>
|
||||
<type>GETTERS_AND_SETTERS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
<group>
|
||||
<type>DEPENDENT_METHODS</type>
|
||||
<order>BREADTH_FIRST</order>
|
||||
</group>
|
||||
</groups>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" autoUpload="On explicit save action" autoUploadExternalChanges="true">
|
||||
<option name="myAutoUpload" value="ON_EXPLICIT_SAVE" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PhpComposerExtensionStubsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlNamedArgumentsInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlResolveInspection" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/CommandLine.iml" filepath="$PROJECT_DIR$/.idea/CommandLine.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="C:/php/includes/fidit" />
|
||||
</include_path>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="24e3f692-8ba3-4d0b-8b1d-a659bb49096c" name="Default Changelist" comment="" />
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ComposerSettings">
|
||||
<execution>
|
||||
<executable />
|
||||
</execution>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="PhpWorkspaceProjectConfiguration">
|
||||
<include_path>
|
||||
<path value="C:/php/includes/fidit" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="ProjectId" id="1QkOgOmQabXBt6Ca0XPelUAw9zz" />
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="true" />
|
||||
<property name="last_opened_file_path" value="C:/php/includes/fidit" />
|
||||
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="terminal" />
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="SshConsoleOptionsProvider">
|
||||
<option name="myEncoding" value="UTF-8" />
|
||||
<option name="myConnectionType" value="NONE" />
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="24e3f692-8ba3-4d0b-8b1d-a659bb49096c" name="Default Changelist" comment="" />
|
||||
<created>1568311237973</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1568311237973</updated>
|
||||
<workItem from="1568311245294" duration="835000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\AbstractArgument.
|
||||
*/
|
||||
namespace CommandLine\Argument;
|
||||
|
||||
use Fidit\v3\AutoProperty;
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Classe abstraite pour n'importe quel type de paramètre
|
||||
*
|
||||
* @property string $varName {@see $_varName $_varName }
|
||||
* @property string $name {@see $_name $_name }
|
||||
* @property string|null $description {@see $_description $_description}
|
||||
* @property mixed|null $default {@see $_default $_default }
|
||||
*
|
||||
* @package CommandLine\Argument
|
||||
*/
|
||||
abstract class ArgumentAbstract extends AutoProperty implements IArgument {
|
||||
/**
|
||||
* @var string Le nom de la variable de retour de l'argument.
|
||||
*/
|
||||
protected $_varName;
|
||||
/**
|
||||
* @var string Le nom de l'argument.
|
||||
*/
|
||||
protected $_name;
|
||||
/**
|
||||
* @var string|null La description de l'argument.
|
||||
*/
|
||||
protected $_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 ($name, $description) {
|
||||
$this->setName($name, true);
|
||||
$this->setDescription($description);
|
||||
}
|
||||
|
||||
public function getVarName() {
|
||||
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($varName) {
|
||||
$this->_varName = $varName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
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($name, $replaceVarName = true) {
|
||||
$this->_name = $name;
|
||||
if($replaceVarName)
|
||||
$this->setVarName($name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return $this->_description;
|
||||
}
|
||||
/**
|
||||
* Définit la description de l'argument.
|
||||
*
|
||||
* @param string|null $description La description
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see $_description
|
||||
*/
|
||||
public function setDescription($description) {
|
||||
$this->_description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
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) {
|
||||
$this->_default = $default;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface CommandLine\Argument\IArgument
|
||||
*/
|
||||
namespace CommandLine\Argument;
|
||||
|
||||
use CommandLine\Exception\IncorrectParse;
|
||||
|
||||
/**
|
||||
* Interface que tout argument doit implémenter
|
||||
*
|
||||
* @package CommandLine\Argument
|
||||
*/
|
||||
interface IArgument {
|
||||
/**
|
||||
* Le nom de la variable de sortie l'argument
|
||||
*
|
||||
* @return string Le nom
|
||||
*/
|
||||
public function getVarName();
|
||||
/**
|
||||
* Le nom de l'argument
|
||||
*
|
||||
* @return string Le nom
|
||||
*/
|
||||
public function getName();
|
||||
/**
|
||||
* La valeur par défaut de l'argument. Null si pas de valeur par défaut
|
||||
*
|
||||
* @return mixed|null La valeur par défaut
|
||||
*/
|
||||
public function getDefault();
|
||||
|
||||
/**
|
||||
* La description de l'argument
|
||||
*
|
||||
* @return string|null La description
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Parse les arguments.
|
||||
*
|
||||
* @param $args array La liste des arguments encore à traiter (par ordre de réception)
|
||||
*
|
||||
* @return ParseResult|null Le résultat du parsage. Null si rien parsé
|
||||
*
|
||||
* @throws IncorrectParse Echec du parsage de l'argument
|
||||
*/
|
||||
public function parse($args);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface CommandLine\Argument\IArgumentValueDescription
|
||||
*/
|
||||
namespace CommandLine\Argument;
|
||||
|
||||
/**
|
||||
* Interface à implementer par les arguments qui souhaitent détailler la valeur attendue
|
||||
*
|
||||
* @package CommandLine\Argument
|
||||
*/
|
||||
interface IArgumentValueDescription {
|
||||
/**
|
||||
* La description de la valeur de d'argument.
|
||||
*
|
||||
* @return string La description.
|
||||
*/
|
||||
public function getValueDescription();
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclare la classe CommandLine\Argument\Option\Flag.
|
||||
*/
|
||||
namespace CommandLine\Argument\Option;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Argument\ArgumentAbstract;
|
||||
use CommandLine\Argument\ParseResult;
|
||||
|
||||
/**
|
||||
* Option de type "flag" contenant True ou False.
|
||||
*
|
||||
* Si fourni, retournera la valeur inverse de {@see getDefault() getDefault}
|
||||
*
|
||||
* @see FlagReverse
|
||||
*
|
||||
* @package CommandLine\Argument\Option
|
||||
*/
|
||||
class Flag extends OptionAbstract {
|
||||
/**
|
||||
* Crée un nouvel argument de type option.
|
||||
*
|
||||
* @param string $name Le nom.
|
||||
* @param boolean $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.
|
||||
*
|
||||
* @throws InvalidArgument Si l'un des paramètres n'est pas correct
|
||||
*/
|
||||
public function __construct ($name, $default, $description, $tagLong = null, $tagShort = null) {
|
||||
parent::__construct($name, $description, $tagLong, $tagShort);
|
||||
$this->setDefault($default);
|
||||
}
|
||||
|
||||
public function parse ($args) {
|
||||
if($this->_parseTag($args[0]))
|
||||
return new ParseResult(true, 1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définit le valeur par défaut
|
||||
*
|
||||
* @param boolean $default La valeur par défaut.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas un booléen.
|
||||
*/
|
||||
public function setDefault ($default = null) {
|
||||
if(is_null($default) || !is_bool($default))
|
||||
throw new InvalidArgument($default, 'La valeur par défaut DOIT être un booléen');
|
||||
|
||||
parent::setDefault($default);
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclare la classe CommandLine\Argument\Option\OptionFlagWithReverse.
|
||||
*/
|
||||
namespace 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 () {
|
||||
$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);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentOption
|
||||
*/
|
||||
namespace CommandLine\Argument\Option;
|
||||
|
||||
use 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();
|
||||
/**
|
||||
* Le tag long.
|
||||
*
|
||||
* @return string Le tag long.
|
||||
*
|
||||
* @see $_tagLong
|
||||
*/
|
||||
public function getTagLong();
|
||||
|
||||
/**
|
||||
* Est-ce que l'argument est autorisé plusieurs fois ?
|
||||
*
|
||||
* @return boolean True si l'argument est autorisé plusieurs fois, sinon False
|
||||
*/
|
||||
public function allowMultiple();
|
||||
/**
|
||||
* 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();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentSecondary.
|
||||
*/
|
||||
namespace CommandLine\Argument\Option;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @throws InvalidArgument
|
||||
*/
|
||||
public function getOthersOptions();
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Option\OptionAbstract.
|
||||
*/
|
||||
namespace CommandLine\Argument\Option;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Argument\ArgumentAbstract;
|
||||
|
||||
/**
|
||||
* Classe abstraite pour les arguments de type "option" : --xxx / -x
|
||||
*
|
||||
* NOTE : les arguments de type "option" ne peuvent autoriser plusieurs valeurs ({@see $default $default} = 1).
|
||||
*
|
||||
* @property string|null $tagShort {@see $_tagShort $_tagShort }
|
||||
* @property string|null $tagLong {@see $_tagLong $_tagLong }
|
||||
* @property boolean $multiple {@see $_multiple $_multiple }
|
||||
* @property boolean $isStoppingParse {@see $_isStoppingParse $_isStoppingParse}
|
||||
*
|
||||
* @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 $_tagShort;
|
||||
/**
|
||||
* @var string L'argument long (cas d'un "--").
|
||||
*/
|
||||
protected $_tagLong;
|
||||
|
||||
/**
|
||||
* @var boolean Est-ce que l'argument est autorisé plusieurs fois ?
|
||||
*/
|
||||
protected $_multiple = false;
|
||||
/**
|
||||
* @var boolean Est-ce que l'argument met fin au parsage ?
|
||||
*/
|
||||
protected $_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 ($name, $description, $tagLong = null, $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($arg) {
|
||||
if($this->hasTagShort()) {
|
||||
if ($arg == '-'.$this->getTagShort())
|
||||
return true;
|
||||
}
|
||||
|
||||
return $arg == '--'.$this->getTagLong();
|
||||
}
|
||||
|
||||
public function getTagShort() {
|
||||
return $this->_tagShort;
|
||||
}
|
||||
/**
|
||||
* Définit le tag court.
|
||||
*
|
||||
* @param string|null $tagShort Le tage court.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see $_tagShort
|
||||
*/
|
||||
public function setTagShort($tagShort = null) {
|
||||
$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() {
|
||||
return !is_null($this->_tagShort);
|
||||
}
|
||||
|
||||
public function getTagLong() {
|
||||
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($tagLong = null) {
|
||||
$this->_tagLong = $tagLong;
|
||||
|
||||
if(is_null($this->_tagLong)) {
|
||||
$this->_tagLong = preg_replace_callback(
|
||||
'/[A-Z_]/',
|
||||
function ($matches) {
|
||||
if($matches[0] == '_')
|
||||
return '-';
|
||||
else
|
||||
return '-'.strtolower($matches[0]);
|
||||
},
|
||||
$this->getName()
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowMultiple() {
|
||||
return $this->_multiple;
|
||||
}
|
||||
/**
|
||||
* Définit si l'argument est autorisé plusieurs fois ou non.
|
||||
*
|
||||
* @param boolean $multiple Argument autorisé plusieurs fois ?
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas un booléen
|
||||
*
|
||||
* @see $_optional
|
||||
*/
|
||||
public function setMultiple($multiple) {
|
||||
if (!is_bool($multiple))
|
||||
throw new InvalidArgument($multiple, 'La valeur n\'est pas un booléen');
|
||||
|
||||
$this->_multiple = $multiple;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isStoppingParse() {
|
||||
return $this->_isStoppingParse;
|
||||
}
|
||||
/**
|
||||
* Définit si l'argument met fin au parsage ou non.
|
||||
*
|
||||
* @param boolean $stoppingParse Met fin au parsage ?
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas un booléen
|
||||
*
|
||||
* @see $_optional
|
||||
*/
|
||||
public function setStoppingParse($stoppingParse) {
|
||||
if (!is_bool($stoppingParse))
|
||||
throw new InvalidArgument($stoppingParse, 'La valeur n\'est pas un booléen');
|
||||
|
||||
$this->_isStoppingParse = $stoppingParse;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Option\Value
|
||||
*/
|
||||
namespace CommandLine\Argument\Option;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Exception\IncorrectParse;
|
||||
use CommandLine\Argument\IArgumentValueDescription;
|
||||
use CommandLine\Argument\Parser\IValueParser;
|
||||
use CommandLine\Argument\ParseResult;
|
||||
|
||||
/**
|
||||
* Option contenant une valeur.
|
||||
*
|
||||
* @property IValueParser $valueParser Le parseur de valeur.
|
||||
*
|
||||
* @package CommandLine\Argument\Option
|
||||
*/
|
||||
class Value extends OptionAbstract implements IArgumentValueDescription {
|
||||
/**
|
||||
* @var IValueParser Parseur pour la valeur
|
||||
*/
|
||||
protected $_valueParser;
|
||||
|
||||
/**
|
||||
* Crée un nouvel argument de type option.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @throws \Fidit\v3\Exception\InvalidArgument Si l'un des paramètres n'est pas correct
|
||||
*/
|
||||
public function __construct ($name, $description, IValueParser $valueParser, $tagLong = null, $tagShort = null) {
|
||||
parent::__construct($name, $description, $tagLong, $tagShort);
|
||||
$this->setValueParser($valueParser);
|
||||
}
|
||||
|
||||
public function parse ($args) {
|
||||
try {
|
||||
if(!$this->_parseTag($args[0]))
|
||||
return null;
|
||||
|
||||
if(count($args) < 2 || is_null($args[1]))
|
||||
throw new IncorrectParse($this,null, 'Seconde valeur de l\'argument manquante');
|
||||
|
||||
return new ParseResult($this->_valueParser->parseValue($args[1]), 2);
|
||||
}
|
||||
catch (InvalidArgument $e) {
|
||||
throw IncorrectParse::createFromInvalidArgument($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return $this->_valueParser->getValueDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Le parseur de valeur.
|
||||
*
|
||||
* @return IValueParser Le parseur.
|
||||
*
|
||||
* @see $_valueParser
|
||||
*/
|
||||
public function getValueParser() {
|
||||
return $this->_valueParser;
|
||||
}
|
||||
/**
|
||||
* Définit le parseur de valeur
|
||||
*
|
||||
* @param IValueParser $valueParser Le parseur
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see $_valueParser
|
||||
*/
|
||||
public function setValueParser(IValueParser $valueParser) {
|
||||
$this->_valueParser = $valueParser;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\ParseResult.
|
||||
*/
|
||||
namespace CommandLine\Argument;
|
||||
|
||||
use Fidit\v3\AutoProperty;
|
||||
|
||||
/**
|
||||
* Résultat du parsage d'un argument
|
||||
*
|
||||
* @property int $consume {@see $_consume $_consume}
|
||||
* @property mixed $value {@see $_value $_value }
|
||||
*
|
||||
* @package CommandLine\Argument
|
||||
*/
|
||||
class ParseResult extends AutoProperty {
|
||||
/**
|
||||
* @var int Le nombre d'argument consumé.
|
||||
*/
|
||||
protected $_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, $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() {
|
||||
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($consume) {
|
||||
$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) {
|
||||
$this->_value = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\BooleanParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Parseur vers un booléen
|
||||
*
|
||||
* Les valeurs suivantes sont acceptées :
|
||||
* - true , 1, oui, vrai
|
||||
* - false, 0, non, faux
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class BooleanParser implements IValueParser {
|
||||
public function parseValue ($arg) {
|
||||
if(!in_array($arg, array(
|
||||
'true' , '1', 'oui', 'vrai',
|
||||
'false', '0', 'non', 'faux',
|
||||
)))
|
||||
throw new InvalidArgument($arg, 'La valeur n\'est pas un booléen valide');
|
||||
|
||||
return in_array($arg, array('true' , '1', 'oui', 'vrai'));
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return 'boolean';
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\DecimalParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Parseur vers un réel
|
||||
*
|
||||
* @property double|null $valueMin {@see $_valueMin $_valueMin}
|
||||
* @property double|null $valueMax {@see $_valueMax $_valueMax}
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class DecimalParser implements IValueParser {
|
||||
/**
|
||||
* @var double|null La valeur minimum autorisée. Null si pas de limite.
|
||||
*/
|
||||
protected $_valueMin = null;
|
||||
/**
|
||||
* @var double|null La valeur maximum autorisée. Null si pas de limite
|
||||
*/
|
||||
protected $_valueMax = null;
|
||||
|
||||
/**
|
||||
* Crée un nouveau parseur
|
||||
*
|
||||
* @param double|null $valueMin La valeur minimum autorisée
|
||||
* @param double|null $valueMax La valeur maximum autorisée
|
||||
*
|
||||
* @throws InvalidArgument Si l'un des paramètre est invalide.
|
||||
*/
|
||||
public function __construct ($valueMin = null, $valueMax = null) {
|
||||
$this->setValueMin($valueMin);
|
||||
$this->setValueMax($valueMax);
|
||||
}
|
||||
|
||||
public function parseValue ($arg) {
|
||||
if (!$this->_isDecimal($arg))
|
||||
throw new InvalidArgument($arg, 'La valeur n\'est pas un réel valide');
|
||||
|
||||
$int = (int)$arg;
|
||||
|
||||
if ($this->hasValueMin()) {
|
||||
if ($int < $this->getValueMin())
|
||||
throw new InvalidArgument($int, 'La valeur est inférieure au minimum : ' . $this->getValueMin());
|
||||
}
|
||||
if ($this->hasValueMax()) {
|
||||
if ($int > $this->getValueMax())
|
||||
throw new InvalidArgument($int, 'La valeur est supérieur au maximum : ' . $this->getValueMax());
|
||||
}
|
||||
|
||||
return $int;
|
||||
}
|
||||
|
||||
protected function _isDecimal($val) {
|
||||
if(!is_numeric($val))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return ($this->hasValueMin() ? $this->getValueMin().' <= ' : '').'decimal'.($this->hasValueMax() ? ' <= '.$this->getValueMax() : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* La valeur minimumm autorisée
|
||||
*
|
||||
* @return double|null La valeur minimum.
|
||||
*
|
||||
* @see $_valueMin
|
||||
*/
|
||||
public function getValueMin() {
|
||||
return $this->_valueMin;
|
||||
}
|
||||
/**
|
||||
* Définit la valeur minimum autorisée.
|
||||
*
|
||||
* @param double|null $valueMin La valeur minimum.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur minimum n'est ni null, ni un entier
|
||||
*/
|
||||
public function setValueMin($valueMin = null) {
|
||||
if(!is_null($valueMin) && !$this->_isDecimal($valueMin))
|
||||
throw new InvalidArgument($valueMin, 'La valeur n\'est pas un entier ou null');
|
||||
|
||||
$this->_valueMin = (int)$valueMin;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Est-ce qu'il existe une limite minimum ?
|
||||
*
|
||||
* @return boolean True s'il existe une limite, sinon False
|
||||
*/
|
||||
public function hasValueMin() {
|
||||
return !is_null($this->getValueMin());
|
||||
}
|
||||
|
||||
/**
|
||||
* La valeur maximum autorisée
|
||||
*
|
||||
* @return double|null La valeur maximum.
|
||||
*
|
||||
* @see $_valueMax
|
||||
*/
|
||||
public function getValueMax() {
|
||||
return $this->_valueMax;
|
||||
}
|
||||
/**
|
||||
* Définit la valeur maximum autorisée.
|
||||
*
|
||||
* @param double|null $valueMax La valeur maximum.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur maximum n'est ni null, ni un entier
|
||||
*/
|
||||
public function setValueMax($valueMax = null) {
|
||||
if(!is_null($valueMax) && !$this->_isDecimal($valueMax))
|
||||
throw new InvalidArgument($valueMax, 'La valeur n\'est pas un entier ou null');
|
||||
|
||||
$this->_valueMax = (int)$valueMax;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Est-ce qu'il existe une limite maximum ?
|
||||
*
|
||||
* @return boolean True s'il existe une limite, sinon False
|
||||
*/
|
||||
public function hasValueMax() {
|
||||
return !is_null($this->getValueMax());
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\EnumParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Parseur vers une liste de valeurs possible (chaine de caractère).
|
||||
*
|
||||
* @property string[] $values {@see $_values $_values}
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class EnumParser implements IValueParser {
|
||||
/**
|
||||
* @var string[] Liste des valeurs autorisées
|
||||
*/
|
||||
protected $_values;
|
||||
|
||||
/**
|
||||
* Crée un nouveau parseur.
|
||||
*
|
||||
* @param string[] $values La liste des valeurs autorisées.
|
||||
*
|
||||
* @throws InvalidArgument Si l'un des paramètres n'est pas correct
|
||||
*/
|
||||
public function __construct ($values) {
|
||||
$this->setValues($values);
|
||||
}
|
||||
|
||||
public function parseValue ($arg) {
|
||||
if(!in_array($arg, $this->_values))
|
||||
throw new InvalidArgument($arg, 'La valeur ne fait partie de liste des valeurs autorisées : '.implode(', ', $this->getValues()));
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return 'enum('.implode(',', $this->getValues()).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* La liste des valeurs autoriséees.
|
||||
*
|
||||
* @return string[] La liste des valeurs
|
||||
*
|
||||
* @see $_values
|
||||
*/
|
||||
public function getValues() {
|
||||
return $this->_values;
|
||||
}
|
||||
/**
|
||||
* Définit la liste des valeurs autorisées.
|
||||
*
|
||||
* @param string[] $values La liste des valeurs
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la liste n'est pas un tableau ou si celui-ci est vide
|
||||
*
|
||||
* @see $_values
|
||||
*/
|
||||
public function setValues($values) {
|
||||
if(!is_array($values))
|
||||
throw new InvalidArgument($values, 'La liste de valeurs n\'est pas un tableau');
|
||||
|
||||
if(count($values) == 0)
|
||||
throw new InvalidArgument($values, 'La liste de valeurs doit avoir au moins un élément');
|
||||
|
||||
$this->_values = $values;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclare l'interface CommandLine\Argument\Parser\IValueParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Interface pour les parseurs
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
interface IValueParser {
|
||||
/**
|
||||
* Vérifie et transforme une valeur.
|
||||
*
|
||||
* @param string $val La valeur à transformer.
|
||||
*
|
||||
* @return mixed La valeur transformée.
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas valide.
|
||||
*/
|
||||
public function parseValue($val);
|
||||
|
||||
/**
|
||||
* La description des contraintes de la valeur.
|
||||
*
|
||||
* @return string La description.
|
||||
*/
|
||||
public function getValueDescription();
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\IntegerParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Parseur vers un entier.
|
||||
*
|
||||
* @property int|null $valueMin {@see $_valueMin $_valueMin}
|
||||
* @property int|null $valueMax {@see $_valueMax $_valueMax}
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class IntegerParser implements IValueParser {
|
||||
/**
|
||||
* @var int|null La valeur minimum autorisée. Null si pas de limite.
|
||||
*/
|
||||
protected $_valueMin = null;
|
||||
/**
|
||||
* @var int|null La valeur maximum autorisée. Null si pas de limite
|
||||
*/
|
||||
protected $_valueMax = null;
|
||||
|
||||
/**
|
||||
* Crée un nouveau parseur
|
||||
*
|
||||
* @param int|null $valueMin La valeur minimum autorisée
|
||||
* @param int|null $valueMax La valeur maximum autorisée
|
||||
*
|
||||
* @throws InvalidArgument Si l'un des paramètre est invalide.
|
||||
*/
|
||||
public function __construct ($valueMin = null, $valueMax = null) {
|
||||
$this->setValueMin($valueMin);
|
||||
$this->setValueMax($valueMax);
|
||||
}
|
||||
|
||||
public function parseValue ($arg) {
|
||||
if(!$this->_isInt($arg))
|
||||
throw new InvalidArgument($arg, 'La valeur n\'est pas un entier valide');
|
||||
|
||||
$int = (int)$arg;
|
||||
|
||||
if($this->hasValueMin()) {
|
||||
if($int < $this->getValueMin())
|
||||
throw new InvalidArgument($int, 'La valeur est inférieure au minimum : '.$this->getValueMin());
|
||||
}
|
||||
if($this->hasValueMax()) {
|
||||
if($int > $this->getValueMax())
|
||||
throw new InvalidArgument($int, 'La valeur est supérieur au maximum : '.$this->getValueMax());
|
||||
}
|
||||
|
||||
return $int;
|
||||
}
|
||||
|
||||
protected function _isInt($val) {
|
||||
if(!is_numeric($val))
|
||||
return false;
|
||||
|
||||
if(floor($val) != $val)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return ($this->hasValueMin() ? $this->getValueMin().' <= ' : '').'integer'.($this->hasValueMax() ? ' <= '.$this->getValueMax() : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* La valeur minimumm autorisée
|
||||
*
|
||||
* @return int|null La valeur minimum.
|
||||
*
|
||||
* @see $_valueMin
|
||||
*/
|
||||
public function getValueMin() {
|
||||
return $this->_valueMin;
|
||||
}
|
||||
/**
|
||||
* Définit la valeur minimum autorisée.
|
||||
*
|
||||
* @param int|null $valueMin La valeur minimum.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur minimum n'est ni null, ni un entier
|
||||
*/
|
||||
public function setValueMin($valueMin = null) {
|
||||
if(!is_null($valueMin) && !$this->_isInt($valueMin))
|
||||
throw new InvalidArgument($valueMin, 'La valeur n\'est pas un entier ou null');
|
||||
|
||||
$this->_valueMin = (int)$valueMin;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Est-ce qu'il existe une limite minimum ?
|
||||
*
|
||||
* @return boolean True s'il existe une limite, sinon False
|
||||
*/
|
||||
public function hasValueMin() {
|
||||
return !is_null($this->getValueMin());
|
||||
}
|
||||
|
||||
/**
|
||||
* La valeur maximum autorisée
|
||||
*
|
||||
* @return int|null La valeur maximum.
|
||||
*
|
||||
* @see $_valueMax
|
||||
*/
|
||||
public function getValueMax() {
|
||||
return $this->_valueMax;
|
||||
}
|
||||
/**
|
||||
* Définit la valeur maximum autorisée.
|
||||
*
|
||||
* @param int|null $valueMax La valeur maximum.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur maximum n'est ni null, ni un entier
|
||||
*/
|
||||
public function setValueMax($valueMax = null) {
|
||||
if(!is_null($valueMax) && !$this->_isInt($valueMax))
|
||||
throw new InvalidArgument($valueMax, 'La valeur n\'est pas un entier ou null');
|
||||
|
||||
$this->_valueMax = (int)$valueMax;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Est-ce qu'il existe une limite maximum ?
|
||||
*
|
||||
* @return boolean True s'il existe une limite, sinon False
|
||||
*/
|
||||
public function hasValueMax() {
|
||||
return !is_null($this->getValueMax());
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\RegexParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Parseur vers une chaine de caractère correspondant à un motif
|
||||
*
|
||||
* Renvoie la liste des groupes capturants
|
||||
*
|
||||
* @property string $regex {@see $_regex $_regex}
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class RegexParser implements IValueParser {
|
||||
/**
|
||||
* @var string La regex à respecter
|
||||
*/
|
||||
protected $_regex = '';
|
||||
|
||||
/**
|
||||
* Crée un nouveau parseur
|
||||
*
|
||||
* @param string $regex Le motif à respecter
|
||||
*/
|
||||
public function __construct ($regex) {
|
||||
$this->setRegex($regex);
|
||||
}
|
||||
|
||||
public function parseValue ($arg) {
|
||||
if(!preg_match($this->regex, $arg, $matches))
|
||||
throw new InvalidArgument($arg, 'La valeur ne correspond pas au motif attendu');
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return $this->getRegex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Le motif à respecter
|
||||
*
|
||||
* @return string Le motif
|
||||
*
|
||||
* @see $_regex
|
||||
*/
|
||||
public function getRegex() {
|
||||
return $this->_regex;
|
||||
}
|
||||
/**
|
||||
* Modifie le motif à respecter
|
||||
*
|
||||
* @param string $regex Le nouveau motif
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRegex($regex = null) {
|
||||
$this->_regex = $regex;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Parser\StringParser
|
||||
*/
|
||||
namespace CommandLine\Argument\Parser;
|
||||
|
||||
/**
|
||||
* Parseur vers une chaine de caractères
|
||||
*
|
||||
* @package CommandLine\Argument\Parser
|
||||
*/
|
||||
class StringParser implements IValueParser {
|
||||
public function parseValue ($arg) {
|
||||
return $arg;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return 'string';
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de CommandLine\Argument\Value\FixedValue
|
||||
*/
|
||||
namespace CommandLine\Argument\Value;
|
||||
|
||||
use CommandLine\Argument\IArgumentValueDescription;
|
||||
use CommandLine\Argument\ParseResult;
|
||||
|
||||
/**
|
||||
* Argument devant correspondre une valeur fixe
|
||||
*
|
||||
* @property string $value {@see $_value $_value}.
|
||||
*
|
||||
* @package CommandLine\Argument
|
||||
*/
|
||||
class FixedValue extends ValueAbstract implements IArgumentValueDescription {
|
||||
/**
|
||||
* @var string La valeur que doit avoir l'argument
|
||||
*/
|
||||
protected $_value;
|
||||
|
||||
/**
|
||||
* Crée un nouvel argument de type valeur
|
||||
*
|
||||
* @param int $position La position
|
||||
* @param string $varName Le nom de la variable
|
||||
* @param string $value La valeur
|
||||
* @param string|null $description La description
|
||||
* @param boolean $optional Valeur optionnelle ?
|
||||
*
|
||||
* @throws \Fidit\v3\Exception\InvalidArgument Si l'un des paramètres n'est pas correct
|
||||
*/
|
||||
public function __construct ($varName, $value, $description, $optional = false) {
|
||||
parent::__construct($value, $description, $optional);
|
||||
$this->setVarName($varName);
|
||||
$this->setValue($value);
|
||||
}
|
||||
|
||||
public function parse ($args) {
|
||||
if($args[0] == $this->getValue())
|
||||
return new ParseResult($this->getValue(), 1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return '"'.$this->getValue().'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* La valeur.
|
||||
*
|
||||
* @return string La valeur.
|
||||
*
|
||||
* @see $_value
|
||||
*/
|
||||
public function getValue() {
|
||||
return $this->_value;
|
||||
}
|
||||
/**
|
||||
* Définit la valeur
|
||||
*
|
||||
* @param string $value La valeur
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see $_value
|
||||
*/
|
||||
public function setValue($value) {
|
||||
$this->_value = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface CommandLine\Argument\Option\IArgumentValue
|
||||
*/
|
||||
namespace CommandLine\Argument\Value;
|
||||
|
||||
use 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();
|
||||
/**
|
||||
* Le nombre maximum d'occurence.
|
||||
*
|
||||
* Généralement 1 ou Null (illimité).
|
||||
*
|
||||
* @return int|null Le nombre maximum d'occurence
|
||||
*/
|
||||
public function getOccurMax();
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de CommandLine\Argument\Value\Value
|
||||
*/
|
||||
namespace CommandLine\Argument\Value;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Exception\IncorrectParse;
|
||||
use CommandLine\Argument\IArgumentValueDescription;
|
||||
use CommandLine\Argument\Parser\IValueParser;
|
||||
use CommandLine\Argument\ParseResult;
|
||||
|
||||
/**
|
||||
* Argument de type "valeur"
|
||||
*
|
||||
* @property IValueParser $valueParser Le parseur de valeur.
|
||||
*
|
||||
* @package CommandLine\Argument\Value
|
||||
*/
|
||||
class Value extends ValueAbstract implements IArgumentValueDescription {
|
||||
/**
|
||||
* @var IValueParser Parseur pour la valeur
|
||||
*/
|
||||
protected $_valueParser;
|
||||
|
||||
/**
|
||||
* Crée un nouvel argument de type valeur
|
||||
*
|
||||
* @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 ($name, $description, IValueParser $valueParser, $optional = false) {
|
||||
parent::__construct($name, $description, $optional);
|
||||
|
||||
$this->setValueParser($valueParser);
|
||||
}
|
||||
|
||||
public function parse ($args) {
|
||||
try {
|
||||
return new ParseResult($this->_valueParser->parseValue($args[0]), 1);
|
||||
}
|
||||
catch(InvalidArgument $e) {
|
||||
throw IncorrectParse::createFromInvalidArgument($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
public function getValueDescription () {
|
||||
return $this->_valueParser->getValueDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Le parseur de valeur.
|
||||
*
|
||||
* @return IValueParser Le parseur.
|
||||
*
|
||||
* @see $_valueParser
|
||||
*/
|
||||
public function getValueParser() {
|
||||
return $this->_valueParser;
|
||||
}
|
||||
/**
|
||||
* Définit le parseur de valeur
|
||||
*
|
||||
* @param IValueParser $valueParser Le parseur
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see $_valueParser
|
||||
*/
|
||||
public function setValueParser(IValueParser $valueParser) {
|
||||
$this->_valueParser = $valueParser;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Argument\Value\ValueArgument.
|
||||
*/
|
||||
namespace CommandLine\Argument\Value;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Argument\ArgumentAbstract;
|
||||
use CommandLine\Argument\Value\IArgumentValue;
|
||||
|
||||
/**
|
||||
* Classe abstraite pour les paramètres de type "valeur"
|
||||
*
|
||||
* @property int $occurMin {@see $_occurMin $_occurMin}
|
||||
* @property int|null $occurMax {@see $_occurMax $_occurMax}
|
||||
*
|
||||
* @package CommandLine\Argument\Value
|
||||
*/
|
||||
abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue {
|
||||
/**
|
||||
* @var int Le nombre minimum d'occurence.
|
||||
*/
|
||||
protected $_occurMin = 1;
|
||||
/**
|
||||
* @var int|null Le nombre maximum d'occurence.
|
||||
*/
|
||||
protected $_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 ($name, $description, $optional = false) {
|
||||
parent::__construct($name, $description);
|
||||
|
||||
$this->setOptional($optional);
|
||||
}
|
||||
|
||||
public function getOccurMin() {
|
||||
return $this->_occurMin;
|
||||
}
|
||||
/**
|
||||
* Définit le nombre minimum d'occurence.
|
||||
*
|
||||
* @param int $occurMin Le nombre minimum
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas un entier positif.
|
||||
*
|
||||
* @see $_occurMin
|
||||
*/
|
||||
public function setOccurMin($occurMin) {
|
||||
if (!is_numeric($occurMin))
|
||||
throw new InvalidArgument($occurMin, 'La valeur n\'est pas un entier');
|
||||
|
||||
if (floor($occurMin) != $occurMin)
|
||||
throw new InvalidArgument($occurMin, 'La valeur n\'est pas un entier');
|
||||
|
||||
$int = (int)$occurMin;
|
||||
if($int < 0)
|
||||
throw new InvalidArgument($occurMin, 'La valeur n\'est pas un entier positif');
|
||||
|
||||
$this->_occurMin = $int;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Définit si l'argument est facultatif ou non.
|
||||
*
|
||||
* @param bool $optional Argument facultatif ?
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOptional($optional = false) {
|
||||
try {
|
||||
$this->setOccurMin($optional ? 0 : 1);
|
||||
}
|
||||
catch(InvalidArgument $e) {}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOccurMax() {
|
||||
return $this->_occurMax;
|
||||
}
|
||||
/**
|
||||
* Définit le nombre mawimum d'occurence.
|
||||
*
|
||||
* @param int|null $occurMax Le nombre maximum
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si la valeur n'est pas Null ou un entier strictement positif.
|
||||
*
|
||||
* @see $_occurMax
|
||||
*/
|
||||
public function setOccurMax($occurMax) {
|
||||
if (!is_null($occurMax)) {
|
||||
if (!is_numeric($occurMax))
|
||||
throw new InvalidArgument($occurMax, 'La valeur n\'est pas un entier');
|
||||
|
||||
if (floor($occurMax) != $occurMax)
|
||||
throw new InvalidArgument($occurMax, 'La valeur n\'est pas un entier');
|
||||
|
||||
$occurMax = (int)$occurMax;
|
||||
if ($occurMax <= 0)
|
||||
throw new InvalidArgument($occurMax, 'La valeur n\'est pas un entier strictement positif');
|
||||
}
|
||||
|
||||
$this->_occurMax = $occurMax;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,871 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\CommandLine
|
||||
*/
|
||||
|
||||
namespace CommandLine;
|
||||
|
||||
use CommandLine\Argument\IArgument;
|
||||
use CommandLine\Argument\Option\OptionAbstract;
|
||||
use CommandLine\Argument\Value\ValueAbstract;
|
||||
use CommandLine\Exception\IException;
|
||||
use CommandLine\Exception\TooMuchValues;
|
||||
use CommandLine\Argument\IArgumentValueDescription;
|
||||
use CommandLine\Argument\Option\IArgumentOption;
|
||||
use CommandLine\Argument\Option\IArgumentOptionSecondary;
|
||||
use CommandLine\Argument\Value\IArgumentValue;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
class CommandLine {
|
||||
/**
|
||||
* Chaine de caractère se substituant à la tabulation pour la construction de l'aide (help).
|
||||
*/
|
||||
const TAB = ' ';
|
||||
|
||||
/**
|
||||
* Nom de l'argument auto-généré pour l'affichage de l'aide.
|
||||
*
|
||||
* @see CommandLine::addDefaultArguments()
|
||||
* @see CommandLine::generateHelp()
|
||||
*/
|
||||
const ARGUMENT_OPTION_HELP = 'help';
|
||||
/**
|
||||
* Nom de l'argument auto-généré pour l'affichage de la version.
|
||||
*
|
||||
* @see CommandLine::addDefaultArguments()
|
||||
* @see CommandLine::getVersion()
|
||||
*/
|
||||
const ARGUMENT_OPTION_VERSION = 'version';
|
||||
|
||||
/**
|
||||
* @var string|null La commande de lancement du script (si non fourni, égal au {@see CommandeLine::_programName nom du programme})
|
||||
*/
|
||||
protected $_command;
|
||||
/**
|
||||
* @var string Le nom du programme
|
||||
*/
|
||||
protected $_programName;
|
||||
/**
|
||||
* @var string Description du programme
|
||||
*/
|
||||
protected $_description;
|
||||
/**
|
||||
* @var string|null La version du programme.
|
||||
*/
|
||||
protected $_version;
|
||||
|
||||
/**
|
||||
* @var IArgumentOption[] Liste des options de la ligne de commande
|
||||
*/
|
||||
protected $_arguments_options = array();
|
||||
/**
|
||||
* @var IArgumentValue[] Liste _ordonnée_ des arguments "valeur" de la ligne de commande
|
||||
*/
|
||||
protected $_arguments_values = array();
|
||||
|
||||
/**
|
||||
* Crée un ligne de commande
|
||||
*
|
||||
* @param string $programName Le nom du programme
|
||||
* @param string $mainDescription La description du programme
|
||||
* @param string|null $command La commande de lancement du programme
|
||||
* @param string|null $version La version du programme
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct ($programName, $mainDescription, $command = null, $version = null) {
|
||||
$this->setProgramName($programName);
|
||||
$this->setDescription($mainDescription);
|
||||
$this->setCommand($command);
|
||||
$this->setVersion($version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute les options communes à la plupart des programmes
|
||||
*
|
||||
* Voici la liste des options générées :
|
||||
* - Aide : --help ou -h
|
||||
* - Version : --version ou -v (voir $shortForVersion)
|
||||
*
|
||||
* @param bool $shortForVersion L'option pour la version existe également au format "court" (-v)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDefaultArguments ($shortForVersion = true) {
|
||||
if(!$this->existsOption(self::ARGUMENT_OPTION_HELP)) {
|
||||
$this->addOption(
|
||||
(new Argument\Option\Flag(self::ARGUMENT_OPTION_HELP, false, 'Affiche cette aide', 'help', 'h'))
|
||||
->setStoppingParse(true)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->existsOption(self::ARGUMENT_OPTION_HELP) && !is_null($this->getVersion())) {
|
||||
$this->addOption(
|
||||
(new Argument\Option\Flag(self::ARGUMENT_OPTION_VERSION,false,'Affiche la version','version',$shortForVersion ? 'v' : null))
|
||||
->setStoppingParse(true)
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Auto-lance les fonctions correspondantes aux options communes.
|
||||
*
|
||||
* @param stdClass $values Les valeurs du parsage
|
||||
* @param boolean $exitAtEnd Terminer le script à la fin de la fonction correspondante ?
|
||||
*/
|
||||
public function treatDefaultArguments ($values, $exitAtEnd = true) {
|
||||
if ($values->{self::ARGUMENT_OPTION_HELP} === true) {
|
||||
$this->showHelp($exitAtEnd);
|
||||
}
|
||||
|
||||
if ($values->{self::ARGUMENT_OPTION_VERSION} === true) {
|
||||
$this->showVersion($exitAtEnd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traite la ligne de commande du script actuel pour en sortir les valeurs.
|
||||
*
|
||||
* @return stdClass Les valeurs extraites.
|
||||
* @throws IException Quand toutes les solutions ne correspond pas
|
||||
* @throws Exception Autre erreur
|
||||
*/
|
||||
public function parse () {
|
||||
$argv = $_SERVER['argv'];
|
||||
array_shift($argv); // Supprime le 1er paramètre : le nom du script PHP
|
||||
|
||||
return $this->parseExplicit($argv);
|
||||
}
|
||||
/**
|
||||
* Traite une ligne de commande pour en sortir les valeurs.
|
||||
*
|
||||
* @param string[] $argv La liste des arguments.
|
||||
*
|
||||
* @return stdClass Les valeurs extraites.
|
||||
* @throws IException Quand toutes les solutions ne correspond pas
|
||||
* @throws Exception Autre erreur
|
||||
*/
|
||||
public function parseExplicit ($argv) {
|
||||
ksort($this->_solutions, SORT_NUMERIC);
|
||||
foreach ($this->_solutions as $ordre => $solution) {
|
||||
$argv_loop = $argv;
|
||||
try {
|
||||
$values = $solution->parseExplicit($argv_loop, $this->_optionsCommon);
|
||||
}
|
||||
catch (IException $e) {
|
||||
if ($ordre >= ($this->getNextSolutionOrder() - 1)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
if (count($argv) > 0) {
|
||||
throw new TooMuchValues($argv, 'Trop de valeurs');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche la version du programme
|
||||
*
|
||||
* @param boolean $exitAtEnd Terminer le script à la fin de la fonction ?
|
||||
*/
|
||||
public function showVersion ($exitAtEnd = true) {
|
||||
echo $this->getVersion() . "\n";
|
||||
|
||||
if ($exitAtEnd) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Affiche l'aide du programme.
|
||||
*
|
||||
* @param boolean $exitAtEnd Terminer le script à la fin de la fonction ?
|
||||
*/
|
||||
public function showHelp ($exitAtEnd = true) {
|
||||
echo $this->generateHelp() . "\n";
|
||||
|
||||
if ($exitAtEnd) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Génère l'aide du programme.
|
||||
*
|
||||
* @return string Le texte de l'aide.
|
||||
*/
|
||||
public function generateHelp () {
|
||||
ksort($this->_solutions);
|
||||
|
||||
$help = array();
|
||||
|
||||
$help[] = $this->getProgramName() . (is_null($this->getVersion()) ? '' : ', version ' . $this->getVersion());
|
||||
$help[] = $this->getDescription();
|
||||
$help[] = '';
|
||||
|
||||
foreach ($this->_solutions as $solution) {
|
||||
$syntax = array(
|
||||
$this->getCommand(),
|
||||
count($this->_optionsCommon) > 0 || count($solution->getOptions()) > 0 ? '[OPTIONS]' : '',
|
||||
);
|
||||
$syntax = array_merge($syntax, array_map(array(__CLASS__, '_getSyntaxOfArgument'), $solution->getArguments()));
|
||||
|
||||
$help[] = implode(' ', $syntax);
|
||||
|
||||
$help[] = self::TAB . 'Arguments :';
|
||||
$help = array_merge($help, self::_getArgumentsListing($solution->getArguments()));
|
||||
$help[] = '';
|
||||
|
||||
$help[] = self::TAB . 'Options :';
|
||||
$help = array_merge($help, self::_getOptionsListing(array_merge($this->_optionsCommon, $solution->getOptions())));
|
||||
$help[] = '';
|
||||
}
|
||||
$help[] = '';
|
||||
|
||||
return implode("\n", $help);
|
||||
}
|
||||
|
||||
/**
|
||||
* La syntax d'un argument
|
||||
*
|
||||
* @param IArgumentValue $argument L'argument
|
||||
*
|
||||
* @return string La syntax de l'argument
|
||||
* @see generateHelp()
|
||||
*/
|
||||
protected static function _getSyntaxOfArgument (IArgumentValue $argument) {
|
||||
$syntax = '';
|
||||
|
||||
$min = $argument->getOccurMin();
|
||||
$max = $argument->getOccurMax();
|
||||
if (is_null($max)) {
|
||||
$max = -1;
|
||||
}
|
||||
|
||||
if ($min == 0) {
|
||||
$syntax .= '[';
|
||||
}
|
||||
|
||||
$syntax .= $argument->getName();
|
||||
for ($curr = 2; $curr <= $min; $curr++) {
|
||||
$syntax .= ' ' . $argument->getName() . $curr;
|
||||
}
|
||||
|
||||
if ($max === -1 || $max > 1) {
|
||||
if ($min < 2) {
|
||||
$syntax .= ' [' . $argument->getName() . '2]';
|
||||
}
|
||||
|
||||
$syntax .= ' ... [' . $argument->getName() . ($max === -1 ? 'N' : $max) . ']';
|
||||
}
|
||||
|
||||
if ($min == 0) {
|
||||
$syntax .= ']';
|
||||
}
|
||||
|
||||
return $syntax;
|
||||
}
|
||||
/**
|
||||
* Transforme une liste d'argument en un liste de leur descriptif complet (pour l'aide).
|
||||
*
|
||||
* @param IArgumentValue[] $arguments La liste des arguments
|
||||
*
|
||||
* @return string[] Les descriptifs complet des arguments
|
||||
*/
|
||||
protected static function _getArgumentsListing ($arguments) {
|
||||
/*
|
||||
* Calcul des différents padding
|
||||
*/
|
||||
// Initialisation
|
||||
$pads = new stdClass;
|
||||
$pads->name = 0;
|
||||
$pads->occurMin = 0;
|
||||
$pads->occurMax = 0;
|
||||
$pads->valueDescription = 0;
|
||||
|
||||
// Lecture des arguments
|
||||
foreach ($arguments as $argument) {
|
||||
$pads->name = max($pads->name, strlen($argument->getName()));
|
||||
|
||||
$max = $argument->getOccurMax();
|
||||
$pads->occurMin = max($pads->occurMin, strlen($argument->getOccurMin()));
|
||||
$pads->occurMax = max($pads->occurMax, strlen(is_null($max) ? 'N' : $max));
|
||||
|
||||
if ($argument instanceof IArgumentValueDescription) {
|
||||
$pads->valueDescription = max($pads->valueDescription, strlen($argument->getValueDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Génération des descriptifs
|
||||
*/
|
||||
$entries = array();
|
||||
foreach ($arguments as $argument) {
|
||||
$label = str_pad($argument->getName(), $pads->name, ' ', STR_PAD_RIGHT);
|
||||
|
||||
$max = $argument->getOccurMax();
|
||||
|
||||
$occur = '';
|
||||
$occur .= str_pad($argument->getOccurMin(), $pads->occurMin, ' ', STR_PAD_LEFT);
|
||||
$occur .= ' => ';
|
||||
$occur .= str_pad(is_null($max) ? 'N' : $max, $pads->occurMax, ' ', STR_PAD_RIGHT);
|
||||
|
||||
$valueDescription = str_pad(
|
||||
$argument instanceof IArgumentValueDescription ? $argument->getValueDescription() : '',
|
||||
$pads->valueDescription,
|
||||
' ',
|
||||
STR_PAD_RIGHT
|
||||
);
|
||||
|
||||
$entries[] = self::TAB . self::TAB . implode(self::TAB, array(
|
||||
$label,
|
||||
$occur,
|
||||
$valueDescription,
|
||||
preg_replace(
|
||||
/** @lang RegExp */ '@\r?\n@',
|
||||
'$0' . self::TAB . self::TAB . implode(self::TAB, array(
|
||||
str_pad('', $pads->name, ' '),
|
||||
str_pad('',
|
||||
$pads->occurMin + 4 + $pads->occurMax,
|
||||
' '
|
||||
),
|
||||
str_pad('', $pads->valueDescription, ' '),
|
||||
'',
|
||||
)
|
||||
),
|
||||
$argument->getDescription()
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
/**
|
||||
* Transforme une liste d'options en un liste de leur descriptif complet (pour l'aide).
|
||||
*
|
||||
* @param IArgumentOption[] $options La liste des options
|
||||
*
|
||||
* @return string[] Les descriptifs complet des options
|
||||
*/
|
||||
protected static function _getOptionsListing ($options) {
|
||||
/*
|
||||
* Calcul des différents padding
|
||||
*/
|
||||
// Initialisation
|
||||
$pads = new stdClass;
|
||||
$pads->tagShort = 0;
|
||||
$pads->tagLong = 0;
|
||||
$pads->valueDescription = 0;
|
||||
|
||||
// Lecture des arguments
|
||||
foreach ($options as $option) {
|
||||
$short = $option->getTagShort();
|
||||
if (!is_null($short)) {
|
||||
$pads->tagShort = max($pads->tagShort, strlen($short));
|
||||
}
|
||||
$pads->tagLong = max($pads->tagLong, strlen($option->getTagLong()));
|
||||
|
||||
if ($option instanceof IArgumentValueDescription) {
|
||||
$pads->valueDescription = max($pads->valueDescription, strlen($option->getValueDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
// Les tags ont une taille suplémentaire incompressible
|
||||
$pads->tagShort += 1;
|
||||
$pads->tagLong += 2;
|
||||
|
||||
/*
|
||||
* Génération des descriptifs
|
||||
*/
|
||||
$entries = array();
|
||||
foreach ($options as $option) {
|
||||
$short = $option->getTagShort();
|
||||
|
||||
$label = '';
|
||||
$label .= str_pad(is_null($short) ? '' : '-' . $short, $pads->tagShort, ' ', STR_PAD_RIGHT);
|
||||
$label .= ' ';
|
||||
$label .= str_pad('--' . $option->getTagLong(), $pads->tagLong, ' ', STR_PAD_RIGHT);
|
||||
$label .= $option->allowMultiple() ? ' *' : ($option->isStoppingParse() ? ' X' : ' ');
|
||||
|
||||
$valueDescription = str_pad(
|
||||
$option instanceof IArgumentValueDescription ? $option->getValueDescription() : '',
|
||||
$pads->valueDescription,
|
||||
' ',
|
||||
STR_PAD_RIGHT
|
||||
);
|
||||
|
||||
$entries[] = self::TAB . self::TAB . implode(self::TAB, array(
|
||||
$label,
|
||||
$valueDescription,
|
||||
preg_replace(
|
||||
/** @lang RegExp */ '@\r?\n@',
|
||||
'$0' . self::TAB . self::TAB . implode(self::TAB, array(
|
||||
str_pad('', $pads->tagShort + 1 + $pads->tagLong
|
||||
+ 2, ' '
|
||||
),
|
||||
str_pad('', $pads->valueDescription, ' '),
|
||||
'',
|
||||
)
|
||||
),
|
||||
$option->getDescription()
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Le nom du programme.
|
||||
*
|
||||
* @return string Le nom.
|
||||
* @see CommandLine::$_programName
|
||||
*/
|
||||
public function getProgramName () {
|
||||
return $this->_programName;
|
||||
}
|
||||
/**
|
||||
* Modifie le nom du programme.
|
||||
*
|
||||
* @param string $programName Le nouveau nom
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_programName
|
||||
*/
|
||||
public function setProgramName ($programName) {
|
||||
$this->_programName = $programName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* La commande de lancement du programme
|
||||
*
|
||||
* NULL = {@see CommandLine::$_programName Nom du programme}
|
||||
*
|
||||
* @return string|null La commande
|
||||
* @see CommandLine::$_command
|
||||
*/
|
||||
public function getCommand () {
|
||||
return $this->_command;
|
||||
}
|
||||
/**
|
||||
* Modifie la commande de lancement du programme
|
||||
*
|
||||
* @param string|null $command La nouvelle commande
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_command
|
||||
*/
|
||||
public function setCommand ($command) {
|
||||
$this->_command = $command;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* La description du programme
|
||||
*
|
||||
* @return string La description
|
||||
* @see CommandLine::$_description
|
||||
*/
|
||||
public function getDescription () {
|
||||
return $this->_description;
|
||||
}
|
||||
/**
|
||||
* Modifie la description du programme.
|
||||
*
|
||||
* @param string $description La nouvelle description.
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_description
|
||||
*/
|
||||
public function setDescription ($description) {
|
||||
$this->_description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* La version du programme
|
||||
*
|
||||
* @return string|null La version
|
||||
* @see CommandLine::$_version
|
||||
*/
|
||||
public function getVersion () {
|
||||
return $this->_version;
|
||||
}
|
||||
/**
|
||||
* Modifie la version du programme.
|
||||
*
|
||||
* @param string|null $version La nouvelle version.
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_version
|
||||
*/
|
||||
public function setVersion ($version) {
|
||||
$this->_version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* La liste des arguments "option"
|
||||
*
|
||||
* @return IArgumentOption[] La liste des options
|
||||
* @see CommandLine::$_arguments_options
|
||||
*/
|
||||
public function getOptions () {
|
||||
return $this->_arguments_options;
|
||||
}
|
||||
/**
|
||||
* Modifie la liste des arguments "option"
|
||||
*
|
||||
* *Attention* : cette fonction _remplace_ la liste des options.
|
||||
* Pour seulement en ajouter, utiliser {@see CommandLine::addOptions()}
|
||||
*
|
||||
* @param IArgumentOption[] $options La nouvelle liste d'options
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_options
|
||||
*/
|
||||
public function setOptions ($options) {
|
||||
self::_checkOptionList($options);
|
||||
|
||||
$this->_arguments_options = $options;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Ajoute des arguments "option" à ceux existants
|
||||
*
|
||||
* Pour ajouter une seule option, il est conseillé d'utiliser {@see CommandLine::addOption()}
|
||||
*
|
||||
* @param IArgumentOption[]|IArgumentOption $options La liste d'options à ajouter
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_options
|
||||
*/
|
||||
public function addOptions ($options) {
|
||||
if (!is_array($options) && $options instanceof IArgumentOption) {
|
||||
$options = array($options);
|
||||
}
|
||||
self::_checkOptionList($options);
|
||||
|
||||
$this->_arguments_options = array_merge($this->_arguments_options, $options);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Ajoute un seul argument "option" à ceux existants
|
||||
*
|
||||
* Pour ajouter plusieurs options à la fois, il est conseillé d'utiliser {@see CommandLine::addOptions()}
|
||||
*
|
||||
* @param IArgumentOption $option L'options à ajouter
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_options
|
||||
*/
|
||||
public function addOption ($option) {
|
||||
return $this->addOptions(array($option));
|
||||
}
|
||||
/**
|
||||
* Est-ce que l'argument "option" existe déjà ?
|
||||
*
|
||||
* @param string $optionName Le nom de l'option
|
||||
*
|
||||
* @return bool True si l'option existe déjà, sinon False
|
||||
*/
|
||||
public function existsOption ($optionName) {
|
||||
foreach ($this->_arguments_options as $option) {
|
||||
if ($option->getName() == $optionName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Est-ce que c'est un argument "option" ?
|
||||
*
|
||||
* @param mixed $argument L'argument à tester
|
||||
*
|
||||
* @return bool True si c'est bien un argument "option", sinon False
|
||||
*/
|
||||
public static function isOption ($argument) {
|
||||
return $argument instanceof IArgumentOption;
|
||||
}
|
||||
/**
|
||||
* Vérifie que la liste d'arguments "option" est valide
|
||||
*
|
||||
* Doit être un tableau et chaque élément doit implémenter {@see IArgumentOption}
|
||||
*
|
||||
* @param IArgumentOption[] $options Les options à vérifier
|
||||
*/
|
||||
protected static function _checkOptionList ($options) {
|
||||
if (!is_array($options)) {
|
||||
throw new InvalidArgumentException('La liste des options n\'est pas un tableau');
|
||||
}
|
||||
foreach ($options as $key => $option) {
|
||||
if (!self::isOption($option)) {
|
||||
throw new InvalidArgumentException('L\'option ' . $key . ' n\'est pas valide (n\'implémente pas IArgumentOption)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* La liste des arguments "value"
|
||||
*
|
||||
* @return IArgumentValue[] La liste des valeurs
|
||||
* @see CommandLine::$_arguments_values
|
||||
*/
|
||||
public function getValues () {
|
||||
return $this->_arguments_values;
|
||||
}
|
||||
/**
|
||||
* Modifie la liste des arguments "value"
|
||||
*
|
||||
* *Attention* : cette fonction _remplace_ la liste des valeurs.
|
||||
* Pour seulement en ajouter, utiliser {@see CommandLine::addValues()}
|
||||
*
|
||||
* @param IArgumentValue[] $values La nouvelle liste de valeurs
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_values
|
||||
*/
|
||||
public function setValues ($values) {
|
||||
self::_checkValueList($values);
|
||||
|
||||
$this->_arguments_values = $values;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Ajoute des arguments "value" à celles existantes
|
||||
*
|
||||
* Pour ajouter une seule valeur, il est conseillé d'utiliser {@see CommandLine::addValue()}
|
||||
*
|
||||
* @param IArgumentValue[]|IArgumentValue $values La liste des valeurs à ajouter
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_values
|
||||
*/
|
||||
public function addValues ($values) {
|
||||
if (!is_array($values) && $values instanceof IArgumentValue) {
|
||||
$values = array($values);
|
||||
}
|
||||
self::_checkValueList($values);
|
||||
|
||||
$this->_arguments_values = array_merge($this->_arguments_values, $values);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Ajoute un seul argument "value" à celles existantes
|
||||
*
|
||||
* Pour ajouter plusieurs valeurs à la fois, il est conseillé d'utiliser {@see CommandLine::addValues()}
|
||||
*
|
||||
* @param IArgumentValue $value La valeur à ajouter
|
||||
*
|
||||
* @return $this
|
||||
* @see CommandLine::$_arguments_values
|
||||
*/
|
||||
public function addValue ($value) {
|
||||
return $this->addValues(array($value));
|
||||
}
|
||||
/**
|
||||
* Est-ce que l'argument "value" existe déjà ?
|
||||
*
|
||||
* @param string $valueName Le nom de la valeur
|
||||
*
|
||||
* @return bool True si la valeur existe déjà, sinon False
|
||||
*/
|
||||
public function existsValue ($valueName) {
|
||||
foreach ($this->_arguments_values as $option) {
|
||||
if ($option->getName() == $valueName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Est-ce que c'est un argument "value" ?
|
||||
*
|
||||
* @param mixed $argument L'argument à tester
|
||||
*
|
||||
* @return bool True si c'est bien un argument "value", sinon False
|
||||
*/
|
||||
public static function isValue ($argument) {
|
||||
return $argument instanceof IArgumentValue;
|
||||
}
|
||||
/**
|
||||
* Vérifie que la liste d'arguments "value" est valide
|
||||
*
|
||||
* Doit être un tableau et chaque élément doit implémenter {@see IArgumentValue}
|
||||
*
|
||||
* @param IArgumentValue[] $values Les valeurs à vérifier
|
||||
*/
|
||||
protected static function _checkValueList ($values) {
|
||||
if (!is_array($values)) {
|
||||
throw new InvalidArgumentException('La liste des valeurs n\'est pas un tableau');
|
||||
}
|
||||
foreach ($values as $key => $value) {
|
||||
if (!self::isValue($value)) {
|
||||
throw new InvalidArgumentException('La valeur ' . $key . ' n\'est pas valide (n\'implémente pas IArgumentValue)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* La liste de tous les arguments ("value" et "option")
|
||||
*
|
||||
* @return IArgument[] La liste des arguments
|
||||
*/
|
||||
public function getArguments () {
|
||||
return array_merge($this->getValues(), $this->getOptions());
|
||||
}
|
||||
/**
|
||||
* Modifie la liste de tous les arguments ("value" et "option")
|
||||
*
|
||||
* *Attention* : cette fonction _remplace_ la liste des arguments.
|
||||
* Pour seulement en ajouter, utiliser {@see CommandLine::addArguments()}
|
||||
*
|
||||
* @param IArgumentValue[] $arguments La nouvelle liste d'arguments
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setArguments ($arguments) {
|
||||
$this->setOptions(array());
|
||||
$this->setValues(array());
|
||||
|
||||
return $this->addArguments($arguments);
|
||||
}
|
||||
/**
|
||||
* Ajoute des arguments "value" à celles existantes
|
||||
*
|
||||
* Pour ajouter un seul argument, il est conseillé d'utiliser {@see CommandLine::addArgument()}
|
||||
*
|
||||
* @param IArgument[]|IArgument $arguments La liste des arguments à ajouter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addArguments ($arguments) {
|
||||
if (!is_array($arguments) && $arguments instanceof IArgumentValue) {
|
||||
$arguments = array($arguments);
|
||||
}
|
||||
self::_checkValueList($arguments);
|
||||
|
||||
foreach ($arguments as $argument) {
|
||||
$this->addArgument($argument);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Ajoute un seul argument ("value" ou "option") à ceux existants
|
||||
*
|
||||
* Pour ajouter plusieurs arguments à la fois, il est conseillé d'utiliser {@see CommandLine::addArguments()}
|
||||
*
|
||||
* @param IArgument $argument L'argument à ajouter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addArgument ($argument) {
|
||||
if (!self::isArgument($argument)) {
|
||||
throw new InvalidArgumentException('L\'argument n\'est pas valide (n\'implémente pas IArgument)');
|
||||
}
|
||||
|
||||
if (self::isOption($argument)) {
|
||||
$this->addOption($argument);
|
||||
}
|
||||
elseif (self::isValue($argument)) {
|
||||
$this->addValue($argument);
|
||||
}
|
||||
else {
|
||||
$type = '';
|
||||
try {
|
||||
$reflex = new ReflectionClass($argument);
|
||||
foreach ($reflex->getInterfaces() as $interface) {
|
||||
if ($interface->implementsInterface(IArgument::class)) {
|
||||
$type = $interface->getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ReflectionException $e) {
|
||||
$type = '<inconnu>';
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('L\'argument n\'est pas d\'un type géré : ' . $type);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Est-ce que l'argument ("value" ou "option") existe déjà ?
|
||||
*
|
||||
* @param string $argumentName Le nom de l'argument
|
||||
*
|
||||
* @return bool True si l'argument existe déjà, sinon False
|
||||
*/
|
||||
public function existsArgument ($argumentName) {
|
||||
$arguments = $this->getArguments();
|
||||
foreach ($arguments as $argument) {
|
||||
if ($argument->getName() == $argumentName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Est-ce que c'est un argument ("value" ou "option") ?
|
||||
*
|
||||
* @param mixed $argument L'argument à tester
|
||||
*
|
||||
* @return bool True si c'est bien un argument, sinon False
|
||||
*/
|
||||
public static function isArgument ($argument) {
|
||||
return $argument instanceof IArgument;
|
||||
}
|
||||
/**
|
||||
* Vérifie que la liste d'arguments ("value" et "option") est valide
|
||||
*
|
||||
* Doit être un tableau et chaque élément doit implémenter {@see IArgument}
|
||||
*
|
||||
* @param IArgument[] $arguments Les arguments à vérifier
|
||||
*/
|
||||
protected static function _checkArgumentList ($arguments) {
|
||||
if (!is_array($arguments)) {
|
||||
throw new InvalidArgumentException('La liste des arguments n\'est pas un tableau');
|
||||
}
|
||||
foreach ($arguments as $key => $argument) {
|
||||
if (!self::isArgument($argument)) {
|
||||
throw new InvalidArgumentException('L\'argument ' . $key . ' n\'est pas valide (n\'implémente pas IArgument)');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'interface d'exception CommandLine\Exception\IException.
|
||||
*/
|
||||
namespace CommandLine\Exception;
|
||||
|
||||
/**
|
||||
* Interface pour toutes les exceptions du module.
|
||||
*
|
||||
* @package CommandLine\Exception
|
||||
*/
|
||||
interface IException {}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'exception CommandLine\Exception\IncorrectParse.
|
||||
*/
|
||||
namespace CommandLine\Exception;
|
||||
|
||||
use CommandLine\Argument\IArgument;
|
||||
use LogicException;
|
||||
|
||||
/**
|
||||
* Exception levée quand le parsage d'un argument échoue
|
||||
*
|
||||
* Exemples :
|
||||
* - Valeur incorrecte
|
||||
* - Valeur manquante
|
||||
*
|
||||
* @package CommandLine\Exception
|
||||
*
|
||||
* @see IArgument::parse()
|
||||
*/
|
||||
class IncorrectParse extends LogicException implements IException {}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'exception CommandLine\Exception\MissingArgument
|
||||
*/
|
||||
namespace CommandLine\Exception;
|
||||
|
||||
use CommandLine\Solution;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception levée quand un argument est manquant lors d'un parsage d'une solution
|
||||
*
|
||||
* @package CommandLine\Exception
|
||||
*
|
||||
* @see Solution::parseExplicit()
|
||||
*/
|
||||
class MissingArgument extends RuntimeException implements IException {}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de l'exception CommandLine\Exception\TooMushValues
|
||||
*/
|
||||
namespace CommandLine\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception levée quand il y a des valeurs en trop lors d'un parsage d'une solution
|
||||
*
|
||||
* @package CommandLine\Exception
|
||||
*/
|
||||
class TooMuchValues extends RuntimeException implements IException {}
|
@ -0,0 +1,2 @@
|
||||
# PHPCommandLine
|
||||
Command line management library in PHP (CLI)
|
@ -0,0 +1,279 @@
|
||||
<?php
|
||||
/**
|
||||
* Déclaration de la classe CommandLine\Solution
|
||||
*/
|
||||
namespace CommandLine;
|
||||
|
||||
use Fidit\v3\Exception\InvalidArgument;
|
||||
use CommandLine\Exception\IncorrectParse;
|
||||
use CommandLine\Exception\MissingArgument;
|
||||
use CommandLine\Exception\TooMuchValues;
|
||||
use CommandLine\Argument\IArgument;
|
||||
use CommandLine\Argument\Option\IArgumentOption;
|
||||
use CommandLine\Argument\Option\IArgumentOptionSecondary;
|
||||
use CommandLine\Argument\ParseResult;
|
||||
use CommandLine\Argument\Value\IArgumentValue;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Représente *une* solution d'une ligne de commande.
|
||||
*
|
||||
* @package CommandLine
|
||||
*/
|
||||
class Solution {
|
||||
/**
|
||||
* @var IArgumentValue[] Liste des arguments de la ligne de commande
|
||||
*/
|
||||
protected $_arguments = array();
|
||||
|
||||
/**
|
||||
* @var IArgumentOption[] Liste des options de la ligne de commande
|
||||
*/
|
||||
protected $_options = array();
|
||||
|
||||
/**
|
||||
* Crée un nouvelle solution.
|
||||
*/
|
||||
public function __construct () {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute un argument
|
||||
*
|
||||
* @param int $order Ordre de l'argument.
|
||||
* @param IArgumentValue $argument L'argument
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si les arguments secondaires (le cas échéant) sont invalides.
|
||||
*
|
||||
* @see $_arguments
|
||||
*/
|
||||
public function addArgument ($order, IArgumentValue $argument) {
|
||||
if(is_null($order) || !is_numeric($order))
|
||||
throw new InvalidArgument($order, 'L\'ordre n\'est pas un nombre');
|
||||
if(array_key_exists($order, $this->_arguments))
|
||||
throw new InvalidArgument($order, 'Cet ordre est déjà utilisé pour un autre argument');
|
||||
|
||||
$this->_arguments[$order] = $argument;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Liste des arguments de la solution.
|
||||
*
|
||||
* @return IArgumentValue[] Les arguments.
|
||||
*/
|
||||
public function getArguments () {
|
||||
ksort($this->_arguments);
|
||||
return $this->_arguments;
|
||||
}
|
||||
/**
|
||||
* Le prochain ordre disponible pour un argument
|
||||
*
|
||||
* @return int La prochaine position
|
||||
*/
|
||||
public function getNextOrder () {
|
||||
$keys = array_keys($this->_arguments);
|
||||
if(count($keys) < 1)
|
||||
return 1;
|
||||
|
||||
return max($keys) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une option
|
||||
*
|
||||
* @param IArgumentOption $option L'option
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgument Si les arguments secondaires (le cas échéant) sont invalides.
|
||||
*
|
||||
* @see $_options
|
||||
*/
|
||||
public function addOption (IArgumentOption $option) {
|
||||
if(array_key_exists($option->getName(), $this->_options))
|
||||
throw new InvalidArgument($option, 'Il existe déjà une autre option avec le même nom');
|
||||
|
||||
$this->_options[$option->getName()] = $option;
|
||||
|
||||
if($option instanceof IArgumentOptionSecondary) {
|
||||
foreach($option->getOthersOptions() as $option_second)
|
||||
$this->addOption($option_second);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Liste des options de la solution.
|
||||
*
|
||||
* @return IArgumentOption[] Les options.
|
||||
*/
|
||||
public function getOptions () {
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traite la solution pour en sortir les valeurs.
|
||||
*
|
||||
* @param string[] $argv La liste des arguments
|
||||
* @param IArgumentOption[] $common_options La liste des options communes
|
||||
*
|
||||
* @return stdClass Les valeurs extraites.
|
||||
* @throws MissingArgument Quand un argument est manquant ou en quantité insuffisante
|
||||
* @throws InvalidArgument Quand un argument n'arrive pas à parser sa valeur
|
||||
* @throws TooMuchValues Quand la solution ne consumme pas la totalité des arguments
|
||||
*/
|
||||
public function parseExplicit ($argv, $common_options) {
|
||||
$stop = false;
|
||||
/** @var IArgumentOption[] $options */$options = array_merge($common_options, $this->getOptions());
|
||||
|
||||
$values = $this->_parseOptions($argv, $options, $stop);
|
||||
if($stop)
|
||||
return $values;
|
||||
|
||||
$arguments = $this->getArguments();
|
||||
foreach($arguments as $ordre => $argument) {
|
||||
$min = $argument->getOccurMin();
|
||||
self::_parseXTimes($argv, $values, $argument, $min);
|
||||
|
||||
$max = $argument->getOccurMax();
|
||||
if(is_null($max) || $max > $min) {
|
||||
$nbArgs = $this->_getNbArgumentRestant($ordre);
|
||||
if($nbArgs >= 0 && count($argv) > $nbArgs) {
|
||||
$nbParse = count($argv) - $nbArgs;
|
||||
if(!is_null($max))
|
||||
$nbParse = min($nbParse, $max - $min);
|
||||
|
||||
self::_parseXTimes($argv, $values, $argument, $nbParse, $min);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($argv))
|
||||
throw new TooMuchValues($argv, 'Trop de paramètres');
|
||||
|
||||
// Valeurs par défaut
|
||||
foreach($options as $option) {
|
||||
if(!isset($values->{$option->getVarName()}))
|
||||
$values->{$option->getVarName()} = $option->getDefault();
|
||||
}
|
||||
foreach($arguments as $argument) {
|
||||
if(!isset($values->{$argument->getVarName()}))
|
||||
$values->{$argument->getVarName()} = $argument->getDefault();
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
/**
|
||||
* Parse des options.
|
||||
*
|
||||
* @param string[] $argv La liste des arguments
|
||||
* @param IArgumentOption[] $options La liste des options
|
||||
* @param boolean $stop Arrêt du parsage ?
|
||||
*
|
||||
* @return stdClass Les options extraites
|
||||
* @throws IncorrectParse Si le parsage d'une des options échoue
|
||||
*/
|
||||
protected static function _parseOptions (&$argv, $options, &$stop) {
|
||||
$values = new stdClass();
|
||||
$stop = false;
|
||||
|
||||
foreach($options as $option) {
|
||||
do {
|
||||
$argv_option = $argv;
|
||||
|
||||
$find = false;
|
||||
while(count($argv_option) > 0) {
|
||||
$result = $option->parse($argv_option);
|
||||
|
||||
if(!is_null($result)) {
|
||||
if($option->isStoppingParse())
|
||||
$values = new stdClass();
|
||||
|
||||
self::_setValue($values, $option, $result, $option->allowMultiple() ? 2 : 1);
|
||||
|
||||
if($option->isStoppingParse()) {
|
||||
$stop = true;
|
||||
return $values;
|
||||
}
|
||||
|
||||
array_splice($argv, count($argv) - count($argv_option), $result->getConsume());
|
||||
$find = true;
|
||||
break;
|
||||
}
|
||||
|
||||
array_shift($argv_option);
|
||||
}
|
||||
} while(count($argv_option) > 1 && (!$find || $option->allowMultiple()));
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse un argument X fois
|
||||
*
|
||||
* @param string[] $argv Liste des arguments
|
||||
* @param stdClass $values Les valeurs de sortie
|
||||
* @param IArgumentValue $argument L'argument à 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 (&$argv, &$values, $argument, $xTimes, $offset = 0) {
|
||||
if($xTimes > count($argv))
|
||||
throw new MissingArgument($argument, 'L\'argument est en quantité insuffisante (' . count($argv) . ' / ' . $xTimes . ')');
|
||||
|
||||
for($curr = 1; $curr <= $xTimes; $curr++) {
|
||||
$result = $argument->parse($argv);
|
||||
if(is_null($result))
|
||||
throw new MissingArgument($argument, 'L\'occurence n° ' . ($offset + $curr) . ' de l\'argument ne correspond pas');
|
||||
|
||||
self::_setValue($values, $argument, $result, $argument->getOccurMax());
|
||||
$argv = array_slice($argv, $result->getConsume());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ajoute le résultat d'un argument aux valeurs de sortie
|
||||
*
|
||||
* @param stdClass $values Les valeurs de sortie, auxquelles ajouter la résultat
|
||||
* @param IArgument $argument L'argument actuel
|
||||
* @param ParseResult $result Le résultat de l'argument
|
||||
* @param int|null $max Le nombre max de valeur autorisé
|
||||
*/
|
||||
protected static function _setValue (&$values, $argument, $result, $max) {
|
||||
if(is_null($max) || $max > 1) {
|
||||
if(!isset($values->{$argument->getVarName()}))
|
||||
$values->{$argument->getVarName()} = array();
|
||||
|
||||
$values->{$argument->getVarName()}[] = $result->getValue();
|
||||
}
|
||||
else
|
||||
$values->{$argument->getVarName()} = $result->getValue();
|
||||
}
|
||||
/**
|
||||
* Calcule le nombre d'argument restant à honorer.
|
||||
*
|
||||
* @param int $ordre_start L'ordre de l'argument en cours
|
||||
*
|
||||
* @return int Le nombre d'argument restant, ou -1 si un argument "illimité"
|
||||
*/
|
||||
protected function _getNbArgumentRestant ($ordre_start) {
|
||||
$nb = 0;
|
||||
foreach($this->getArguments() as $ordre => $argument) {
|
||||
if($ordre <= $ordre_start)
|
||||
continue;
|
||||
|
||||
$max = $argument->getOccurMax();
|
||||
if(is_null($max))
|
||||
return -1;
|
||||
|
||||
$nb += $max;
|
||||
}
|
||||
|
||||
return $nb;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue