From e4d5860d8ee167eb8d1c49aeabe0977228304b86 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 22 Sep 2025 03:45:44 +0400 Subject: [PATCH] modifs.mineures sans commentaires --- src/app/cli/ArgDef.php | 75 +++++++++++++++++++---------------- src/app/cli/ArgDefs.php | 2 +- src/app/cli/SimpleArgDefs.php | 4 +- src/app/cli/TODO.md | 38 +----------------- tests/app/cli/ArgDefTest.php | 30 +++++++++----- 5 files changed, 66 insertions(+), 83 deletions(-) diff --git a/src/app/cli/ArgDef.php b/src/app/cli/ArgDef.php index 94a0b48..6036578 100644 --- a/src/app/cli/ArgDef.php +++ b/src/app/cli/ArgDef.php @@ -5,6 +5,7 @@ use nulib\A; use nulib\cl; use nulib\php\func; use nulib\php\types\varray; +use nulib\php\types\vbool; class ArgDef { const TYPE_SHORT = 0, TYPE_LONG = 1, TYPE_COMMAND = 2; @@ -17,18 +18,19 @@ class ArgDef { $args = $params["args"] ?? null; $args ??= $params["arg"] ?? null; if ($args === true) $args = 1; + elseif ($args === "*") $args = [null]; + elseif ($args === "+") $args = ["value", null]; if (is_int($args)) $args = array_fill(0, $args, "value"); $dest->args ??= cl::withn($args); $dest->argsdesc ??= $params["argsdesc"] ?? null; - $parent = $params["parent"] ?? null; - if ($parent !== null) { - A::merge($parent["add"], $options); - A::merge($dest->parents, [$parent]); - } else { - $dest->addOptions($options); - } + $adds = varray::withn($params["add"] ?? null); + A::merge($dest->adds, $adds); + A::merge($dest->adds, $options); + $removes = varray::withn($params["remove"] ?? null); + A::merge($dest->removes, $removes); + $dest->disabled = vbool::withn($params["disabled"] ?? null); $dest->ensureArray ??= $params["ensure_array"] ?? null; $action = $params["action"] ?? null; @@ -61,8 +63,9 @@ class ArgDef { $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; + if (is_string($defaults)) $defaults = $argDefs->getArgDef($defaults)->origDef; if ($defaults !== null) self::merge_parse_def($dest, $defaults); self::parse_def($dest, $def); @@ -70,18 +73,20 @@ class ArgDef { $merges = $defs["merges"] ?? null; $merge = $defs["merge"] ?? null; 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) { - self::merge_parse_def($this, $def); + function __construct(array $def, ?ArgDefs $argDefs=null) { + $this->origDef = $def; + self::merge_parse_def($this, $def, $argDefs); } - protected ?array $options = []; - - function getOptions(): array { - return array_keys($this->options); - } + protected array $origDef; public bool $isHelp = false; public bool $isRemains = false; @@ -94,6 +99,26 @@ class ArgDef { public ?int $maxArgs = 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 { if ($options === null) return; foreach ($options as $option) { @@ -176,24 +201,6 @@ class ArgDef { 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 */ protected function updateType(): void { $haveShortOptions = false; diff --git a/src/app/cli/ArgDefs.php b/src/app/cli/ArgDefs.php index 9165ba4..55c61ad 100644 --- a/src/app/cli/ArgDefs.php +++ b/src/app/cli/ArgDefs.php @@ -29,7 +29,7 @@ abstract class ArgDefs { # définition des options foreach ($defs as $def) { - $argDefs[] = new ArgDef($def); + $argDefs[] = new ArgDef($def, $dest); } } diff --git a/src/app/cli/SimpleArgDefs.php b/src/app/cli/SimpleArgDefs.php index 78fb85e..e4e990f 100644 --- a/src/app/cli/SimpleArgDefs.php +++ b/src/app/cli/SimpleArgDefs.php @@ -15,10 +15,10 @@ class SimpleArgDefs extends ArgDefs { function __construct(array $defs) { self::merge_parse_defs($this, $defs, $argDefs); - # calculer les héritages + # calculer les fusions foreach ($argDefs as $argDef) { /** @var ArgDef $argDef */ - $argDef->processParents($this); + $argDef->processOptions(); } # indexer les arguments diff --git a/src/app/cli/TODO.md b/src/app/cli/TODO.md index 9e2118c..a2bfd9d 100644 --- a/src/app/cli/TODO.md +++ b/src/app/cli/TODO.md @@ -1,34 +1,10 @@ # cli * [ ] 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 -actuellement, même si la surcharge d'option fonctionne, l'affichage de l'aide est incorrecte -* 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 +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. 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 -"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 ~~~php [ diff --git a/tests/app/cli/ArgDefTest.php b/tests/app/cli/ArgDefTest.php index cad22c5..0171f1e 100644 --- a/tests/app/cli/ArgDefTest.php +++ b/tests/app/cli/ArgDefTest.php @@ -10,7 +10,7 @@ class ArgDefTest extends TestCase { bool $haveShortOptions, bool $haveLongOptions, bool $haveCommands, bool $haveArgs, ?int $minArgs, ?int $maxArgs, ?string $argsdesc ) { - $argDef->processParents(); + $argDef->processOptions(); $argDef->processArgs(); $argDef->processAction(); self::assertSame($options, $argDef->getOptions()); @@ -117,16 +117,27 @@ class ArgDefTest extends TestCase { ["-o", "--longo"], true, true, false, 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"]; $argDef = new ArgDef([ - "parent" => [$BASE, - "add" => ["-a", "--longa"], - "remove" => ["-o", "--longo"], - ], + "merge" => $BASE, + "add" => ["-a", "--longa"], + "remove" => ["-o", "--longo"], ]); self::assertArg($argDef, ["-a", "--longa"], @@ -134,10 +145,9 @@ class ArgDefTest extends TestCase { false, 0, 0, ""); $argDef = new ArgDef([ - "parent" => [$BASE, - "add" => ["-a", "--longa"], - "remove" => ["-o", "--longo"], - ], + "merge" => $BASE, + "add" => ["-a", "--longa"], + "remove" => ["-o", "--longo"], "-x", ]); self::assertArg($argDef,