modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2025-09-22 03:45:44 +04:00
parent 417b2bc693
commit e4d5860d8e
5 changed files with 66 additions and 83 deletions

View File

@ -5,6 +5,7 @@ use nulib\A;
use nulib\cl; use nulib\cl;
use nulib\php\func; use nulib\php\func;
use nulib\php\types\varray; use nulib\php\types\varray;
use nulib\php\types\vbool;
class ArgDef { class ArgDef {
const TYPE_SHORT = 0, TYPE_LONG = 1, TYPE_COMMAND = 2; const TYPE_SHORT = 0, TYPE_LONG = 1, TYPE_COMMAND = 2;
@ -17,18 +18,19 @@ class ArgDef {
$args = $params["args"] ?? null; $args = $params["args"] ?? null;
$args ??= $params["arg"] ?? null; $args ??= $params["arg"] ?? null;
if ($args === true) $args = 1; if ($args === true) $args = 1;
elseif ($args === "*") $args = [null];
elseif ($args === "+") $args = ["value", null];
if (is_int($args)) $args = array_fill(0, $args, "value"); if (is_int($args)) $args = array_fill(0, $args, "value");
$dest->args ??= cl::withn($args); $dest->args ??= cl::withn($args);
$dest->argsdesc ??= $params["argsdesc"] ?? null; $dest->argsdesc ??= $params["argsdesc"] ?? null;
$parent = $params["parent"] ?? null; $adds = varray::withn($params["add"] ?? null);
if ($parent !== null) { A::merge($dest->adds, $adds);
A::merge($parent["add"], $options); A::merge($dest->adds, $options);
A::merge($dest->parents, [$parent]); $removes = varray::withn($params["remove"] ?? null);
} else { A::merge($dest->removes, $removes);
$dest->addOptions($options); $dest->disabled = vbool::withn($params["disabled"] ?? null);
}
$dest->ensureArray ??= $params["ensure_array"] ?? null; $dest->ensureArray ??= $params["ensure_array"] ?? null;
$action = $params["action"] ?? null; $action = $params["action"] ?? null;
@ -61,8 +63,9 @@ class ArgDef {
$dest->help ??= $params["help"] ?? null; $dest->help ??= $params["help"] ?? null;
} }
protected static function merge_parse_def(ArgDef $dest, array $def): void { protected static function merge_parse_def(ArgDef $dest, array $def, ?ArgDefs $argDefs=null): void {
$defaults = $defs["defaults"] ?? null; $defaults = $defs["defaults"] ?? null;
if (is_string($defaults)) $defaults = $argDefs->getArgDef($defaults)->origDef;
if ($defaults !== null) self::merge_parse_def($dest, $defaults); if ($defaults !== null) self::merge_parse_def($dest, $defaults);
self::parse_def($dest, $def); self::parse_def($dest, $def);
@ -70,18 +73,20 @@ class ArgDef {
$merges = $defs["merges"] ?? null; $merges = $defs["merges"] ?? null;
$merge = $defs["merge"] ?? null; $merge = $defs["merge"] ?? null;
if ($merge !== null) $merges[] = $merge; if ($merge !== null) $merges[] = $merge;
if ($merges !== null) self::merge_parse_def($dest, $merges); if ($merges !== null) {
foreach ($merges as $merge) {
if (is_string($merge)) $merge = $argDefs->getArgDef($merge)->origDef;
if ($merge !== null) self::merge_parse_def($dest, $merge);
}
}
} }
function __construct(array $def) { function __construct(array $def, ?ArgDefs $argDefs=null) {
self::merge_parse_def($this, $def); $this->origDef = $def;
self::merge_parse_def($this, $def, $argDefs);
} }
protected ?array $options = []; protected array $origDef;
function getOptions(): array {
return array_keys($this->options);
}
public bool $isHelp = false; public bool $isHelp = false;
public bool $isRemains = false; public bool $isRemains = false;
@ -94,6 +99,26 @@ class ArgDef {
public ?int $maxArgs = null; public ?int $maxArgs = null;
public ?string $argsdesc = null; public ?string $argsdesc = null;
protected ?array $options = [];
function getOptions(): array {
return array_keys($this->options);
}
protected ?array $removes = null;
protected ?array $adds = null;
protected ?bool $disabled = null;
/** traiter le paramètre parent */
function processOptions(): void {
if ($this->disabled) {
$this->options = [];
} else {
$this->removeOptions($this->removes);
$this->addOptions($this->adds);
}
}
function addOptions(?array $options): void { function addOptions(?array $options): void {
if ($options === null) return; if ($options === null) return;
foreach ($options as $option) { foreach ($options as $option) {
@ -176,24 +201,6 @@ class ArgDef {
unset($this->options[$option]); unset($this->options[$option]);
} }
protected ?array $parents = null;
/** traiter le paramètre parent */
function processParents(?ArgDefs $argDefs=null): void {
$parents = $this->parents;
if ($parents === null) return;
foreach ($parents as $parent) {
$argDef = $parent[0] ?? null;
if (is_array($argDef)) $argDef = new self($argDef);
elseif (is_string($argDef)) $argDef = $argDefs->getArgDef($argDef);
else throw new ArgException("parent must be string or array");
if ($argDef === null) continue;
$this->options = $argDef->options;
$this->removeOptions(varray::withn($parent["remove"] ?? null));
$this->addOptions(varray::withn($parent["add"] ?? null));
}
}
/** mettre à jour le type d'option */ /** mettre à jour le type d'option */
protected function updateType(): void { protected function updateType(): void {
$haveShortOptions = false; $haveShortOptions = false;

View File

@ -29,7 +29,7 @@ abstract class ArgDefs {
# définition des options # définition des options
foreach ($defs as $def) { foreach ($defs as $def) {
$argDefs[] = new ArgDef($def); $argDefs[] = new ArgDef($def, $dest);
} }
} }

View File

@ -15,10 +15,10 @@ class SimpleArgDefs extends ArgDefs {
function __construct(array $defs) { function __construct(array $defs) {
self::merge_parse_defs($this, $defs, $argDefs); self::merge_parse_defs($this, $defs, $argDefs);
# calculer les héritages # calculer les fusions
foreach ($argDefs as $argDef) { foreach ($argDefs as $argDef) {
/** @var ArgDef $argDef */ /** @var ArgDef $argDef */
$argDef->processParents($this); $argDef->processOptions();
} }
# indexer les arguments # indexer les arguments

View File

@ -1,34 +1,10 @@
# cli # cli
* [ ] implémenter les arguments avancés avec le préfixe "++" sur la description * [ ] implémenter les arguments avancés avec le préfixe "++" sur la description
* [ ] pour le nombre d'arguments, supporter l'alias `*` pour `0..N` et `+` pour `1..N` * [x] pour le nombre d'arguments, supporter l'alias `*` pour `0..N` et `+` pour `1..N`
* [ ] transformer un schéma en définition d'arguments, un tableau en liste d'arguments, et vice-versa * [ ] transformer un schéma en définition d'arguments, un tableau en liste d'arguments, et vice-versa
actuellement, même si la surcharge d'option fonctionne, l'affichage de l'aide est incorrecte lors de la surcharge d'une définition d'option, certaines options sont supprimées. quand toutes les options sont supprimées, la définition disparait.
* possibilité de merger *une définition d'option*
* lors de la surcharge d'une définition d'option, certaines options sont supprimées. quand toutes les options sont supprimées, la définition disparait.
* possibilité de modifier une précédente définition, notamment en rajoutant "disabled" => true pour désactiver (supprimer) la définition
* cela implique d'avoir un moyen de sélectionner une précédente définition, e.g
~~~php
const ARGS = [
## exemple n°1
["-o", "--option"],
["extends" => "-o", "disabled" => true],
# effet: la définition -o,--option est supprimée
## exemple n°2
# étendre une précédente définition
["-a", "--first"],
["extends" => "-a", "extends_delete" => ["--first"], "--second"],
# résultat final: ["-a", "--second"]
## exemple n°3
# créer une définition à partir d'une autre
["merge" => ["-b", "--premier"], "merge_delete" => ["--premier"], "--deuxieme"],
# résultat final: ["-b", "--deuxieme"]
];
~~~
* pour faciliter l'implémentation de toutes ces fonctionnalités, faire une classe Option qui contient toutes les méthodes appropriées
faire une implémentation SimpleArgsParser qui ne supporte pas les commandes, uniquement les options faire une implémentation SimpleArgsParser qui ne supporte pas les commandes, uniquement les options
@ -36,16 +12,6 @@ puis faire une implémentation ArgsParser qui supporte les commandes, et les opt
## WIP ## WIP
"parent" est remplacé par "defaults", "merges", "merge"
"add" et "remove" sont au niveau de la définition
ainsi, ["extends" => [PARENT, "add" => A, "remove" => R]]
devient ["merge" => PARENT, "add" => A, "remove" => R]
supporter aussi "merge" => $string
NB: dans ce cas, "add" est peut-être inutile?
documenter que dans les cas simples, on peut tout simplement refaire la définition, e.g documenter que dans les cas simples, on peut tout simplement refaire la définition, e.g
~~~php ~~~php
[ [

View File

@ -10,7 +10,7 @@ class ArgDefTest extends TestCase {
bool $haveShortOptions, bool $haveLongOptions, bool $haveCommands, bool $haveShortOptions, bool $haveLongOptions, bool $haveCommands,
bool $haveArgs, ?int $minArgs, ?int $maxArgs, ?string $argsdesc bool $haveArgs, ?int $minArgs, ?int $maxArgs, ?string $argsdesc
) { ) {
$argDef->processParents(); $argDef->processOptions();
$argDef->processArgs(); $argDef->processArgs();
$argDef->processAction(); $argDef->processAction();
self::assertSame($options, $argDef->getOptions()); self::assertSame($options, $argDef->getOptions());
@ -117,16 +117,27 @@ class ArgDefTest extends TestCase {
["-o", "--longo"], ["-o", "--longo"],
true, true, false, true, true, false,
true, 1, PHP_INT_MAX, "VALUE [VALUEs...]"); true, 1, PHP_INT_MAX, "VALUE [VALUEs...]");
$argDef = new ArgDef(["-o", "--longo", "args" => "*"]);
self::assertArg($argDef,
["-o", "--longo"],
true, true, false,
true, 0, PHP_INT_MAX, "[VALUEs...]");
$argDef = new ArgDef(["-o", "--longo", "args" => "+"]);
self::assertArg($argDef,
["-o", "--longo"],
true, true, false,
true, 1, PHP_INT_MAX, "VALUE [VALUEs...]");
} }
function testParent() { function testMerge() {
$BASE = ["-o:", "--longo"]; $BASE = ["-o:", "--longo"];
$argDef = new ArgDef([ $argDef = new ArgDef([
"parent" => [$BASE, "merge" => $BASE,
"add" => ["-a", "--longa"], "add" => ["-a", "--longa"],
"remove" => ["-o", "--longo"], "remove" => ["-o", "--longo"],
],
]); ]);
self::assertArg($argDef, self::assertArg($argDef,
["-a", "--longa"], ["-a", "--longa"],
@ -134,10 +145,9 @@ class ArgDefTest extends TestCase {
false, 0, 0, ""); false, 0, 0, "");
$argDef = new ArgDef([ $argDef = new ArgDef([
"parent" => [$BASE, "merge" => $BASE,
"add" => ["-a", "--longa"], "add" => ["-a", "--longa"],
"remove" => ["-o", "--longo"], "remove" => ["-o", "--longo"],
],
"-x", "-x",
]); ]);
self::assertArg($argDef, self::assertArg($argDef,