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\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;

View File

@ -29,7 +29,7 @@ abstract class ArgDefs {
# définition des options
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) {
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

View File

@ -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
[

View File

@ -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,