modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2025-09-23 02:13:32 +04:00
parent 0fa1f5a182
commit 2e3b290d84
6 changed files with 151 additions and 88 deletions

View File

@ -7,7 +7,7 @@ use nulib\php\func;
use nulib\php\types\varray;
use nulib\php\types\vbool;
class ArgDef {
class ArgDef implements IArgo {
const TYPE_SHORT = 0, TYPE_LONG = 1, TYPE_COMMAND = 2;
const ARGS_NONE = 0, ARGS_MANDATORY = 1, ARGS_OPTIONAL = 2;
const ACTION_SET = 0, ACTION_INC = 1, ACTION_DEC = 2, ACTION_FUNC = 3;
@ -119,6 +119,10 @@ class ArgDef {
else return array_keys($this->options);
}
function isEmpty(): bool {
return $this->disabled || !boolval($this->options);
}
/** traiter le paramètre parent */
function processOptions(): void {
$this->removeOptions($this->removes);
@ -433,17 +437,16 @@ class ArgDef {
return [
...$this->getOptions(),
"empty" => $this->isEmpty(),
"help" => $this->help,
"have_short_options" => $this->haveShortOptions,
"have_long_options" => $this->haveLongOptions,
"is_command" => $this->isCommand,
"is_help" => $this->isHelp,
"is_remains" => $this->isRemains,
"ĥave_args" => $this->haveArgs,
"min_args" => $this->minArgs,
"max_args" => $this->maxArgs,
"args" => $this->args,
"argsdesc" => $this->argsdesc,
//"help" => $this->help,
//"have_short_options" => $this->haveShortOptions,
//"have_long_options" => $this->haveLongOptions,
//"is_command" => $this->isCommand,
//"is_help" => $this->isHelp,
//"is_remains" => $this->isRemains,
//"ĥave_args" => $this->haveArgs,
//"min_args" => $this->minArgs,
//"max_args" => $this->maxArgs,
//"argsdesc" => $this->argsdesc,
];
}
}

View File

@ -3,60 +3,61 @@ namespace nulib\app\cli;
use nulib\cl;
abstract class ArgDefs {
abstract class ArgDefs implements IArgo {
function __construct(array $defs) {
$this->defs = $defs;
$this->mergeParse($defs, $argDefs);
$this->addAll($argDefs);
$this->mergeParse($defs, $argos);
$this->setArgos($argos);
}
protected array $defs;
protected function mergeParse(array $defs, ?array &$argDefs, bool $parse=true): void {
protected function mergeParse(array $defs, ?array &$argos, bool $parse=true): void {
$defaults = $defs["defaults"] ?? null;
if ($defaults !== null) {
$this->mergeParse($defaults, $argDefs, false);
$this->parse($defaults, $argDefs);
$this->mergeParse($defaults, $argos, false);
$this->parse($defaults, $argos);
}
if ($parse) $this->parse($defs, $argDefs);
if ($parse) $this->parse($defs, $argos);
$merges = $defs["merges"] ?? null;
$merge = $defs["merge"] ?? null;
if ($merge !== null) $merges[] = $merge;
if ($merges !== null) {
foreach ($merges as $merge) {
$this->mergeParse($merge, $argDefs, false);
$this->parse($merge, $argDefs);
$this->mergeParse($merge, $argos, false);
$this->parse($merge, $argos);
}
}
}
protected function parse(array $defs, ?array &$argos): void {
[$defs, $params] = cl::split_assoc($defs);
foreach ($defs as $def) {
$argos[] = new ArgDef($def);
}
$this->parseParams($params);
}
protected function parseParams(?array $params): void {
}
protected function parse(array $defs, ?array &$argDefs): void {
[$defs, $params] = cl::split_assoc($defs);
foreach ($defs as $def) {
$argDefs[] = new ArgDef($def);
}
$this->parseParams($params);
protected array $argos;
function getArgos(): array {
return $this->argos;
}
protected array $all;
protected function addAll(?array $argDefs): void {
$this->all = $argDefs ?? [];
}
function all(): array {
return array_filter($this->all, function (ArgDef $argDef) {
return !$argDef->isEmpty();
protected function setArgos(?array $argos): void {
$argos ??= [];
$this->argos = array_filter($argos, function (IArgo $argo): bool {
return !$argo->isEmpty();
});
}
function isEmpty(): bool {
return !$this->all();
return !$this->getArgos();
}
function get(string $option): ?ArgDef {
@ -117,4 +118,10 @@ abstract class ArgDefs {
function normalize(array $args): array {
return $args;
}
function debugInfos(): array {
return array_map(function (IArgo $argo) {
return $argo->debugInfos();
}, $this->argos);
}
}

11
src/app/cli/IArgo.php Normal file
View File

@ -0,0 +1,11 @@
<?php
namespace nulib\app\cli;
/**
* Interface IArgo: une instance de ArgDef, ArgGroup ou ArgSection
*/
interface IArgo {
function isEmpty(): bool;
function debugInfos(): array;
}

View File

@ -55,57 +55,62 @@ class SimpleArgDefs extends ArgDefs {
protected array $index;
protected function addAll(?array $argDefs): void {
parent::addAll($argDefs);
$this->index = [];
if ($argDefs !== null) {
protected function setArgos(?array $argos): void {
$argos ??= [];
# calculer les options pour les objets déjà fusionnés puis indexer une
# première fois
foreach ($argDefs as $argDef) {
/** @var ArgDef $argDef */
if (!$argDef->isExtends()) {
$argDef->processOptions();
foreach ($argos as $argo) {
/** @var ArgDef $argo */
if (!$argo->isExtends()) {
$argo->processOptions();
}
}
$this->index = [];
foreach ($argDefs as $argDef) {
if ($argDef->isExtends()) continue;
$options = $argDef->getOptions();
foreach ($argos as $argo) {
if ($argo->isExtends()) continue;
$options = $argo->getOptions();
foreach ($options as $option) {
/** @var ArgDef $prevArgDef */
$prevArgDef = $this->index[$option] ?? null;
if ($prevArgDef !== null) $prevArgDef->removeOption($option);
$this->index[$option] = $argDef;
/** @var ArgDef $prevArgo */
$prevArgo = $this->index[$option] ?? null;
if ($prevArgo !== null) $prevArgo->removeOption($option);
$this->index[$option] = $argo;
}
}
# puis traiter les extensions d'objets, calculer les options pour ces
# objets et indexer pour la deuxième fois
foreach ($argDefs as $argDef) {
/** @var ArgDef $argDef */
if ($argDef->isExtends()) {
$argDef->processExtends($this);
foreach ($argos as $argo) {
/** @var ArgDef $argo */
if ($argo->isExtends()) {
$argo->processExtends($this);
}
}
$this->index = [];
foreach ($argDefs as $argDef) {
if ($argDef->isExtends()) continue;
$options = $argDef->getOptions();
foreach ($argos as $argo) {
if ($argo->isExtends()) continue;
$options = $argo->getOptions();
foreach ($options as $option) {
/** @var ArgDef $prevArgDef */
$prevArgDef = $this->index[$option] ?? null;
if ($prevArgDef !== null) $prevArgDef->removeOption($option);
$this->index[$option] = $argDef;
/** @var ArgDef $prevArgo */
$prevArgo = $this->index[$option] ?? null;
if ($prevArgo !== null) $prevArgo->removeOption($option);
$this->index[$option] = $argo;
}
}
# ne garder que les objets non vides
$argos = array_filter($argos, function(IArgo $argo): bool {
return !$argo->isEmpty();
});
# puis calculer nombre d'arguments et actions
foreach ($argDefs as $argDef) {
if ($argDef->isExtends()) continue;
$argDef->processArgs();
$argDef->processAction();
}
foreach ($argos as $argo) {
if ($argo->isExtends()) continue;
$argo->processArgs();
$argo->processAction();
}
$this->argos = $argos;
}
function get(string $option): ?ArgDef {
@ -260,4 +265,15 @@ class SimpleArgDefs extends ArgDefs {
}
return array_merge($options, ["--"], $remains);
}
function debugInfos(): array {
return [
"argos" => array_map(function (IArgo $argo) {
return $argo->debugInfos();
}, $this->argos),
"index" => array_map(function (IArgo $argo) {
return $argo->debugInfos();
}, $this->index),
];
}
}

View File

@ -4,8 +4,6 @@
* [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
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
puis faire une implémentation ArgsParser qui supporte les commandes, et les options dynamiques

View File

@ -157,6 +157,31 @@ class ArgDefTest extends TestCase {
false, 0, 0, "");
}
function testOverride() {
$argDefs = new SimpleArgDefs([
["-o", "--longx"],
"merge" => [
["-o", "--longo"],
],
]);
var_export($argDefs->debugInfos()); #XXX
$argDefs = new SimpleArgDefs([
["-o", "--longo"],
["-o", "--longx"],
]);
var_export($argDefs->debugInfos()); #XXX
$argDefs = new SimpleArgDefs([
["-o", "--longo"],
["-o"],
["--longo"],
]);
var_export($argDefs->debugInfos()); #XXX
self::assertTrue(true);
}
function testExtends() {
$ARGS1 = [
["-o:", "--longo",
@ -176,8 +201,11 @@ class ArgDefTest extends TestCase {
"help" => "help desta"
],
];
$argDefs1 = new SimpleArgDefs($ARGS1);
//$argDefs1 = new SimpleArgDefs($ARGS1);
//var_export($argDefs1->debugInfos()); #XXX
$argDefs2 = new SimpleArgDefs($ARGS2);
var_export($argDefs2->debugInfos()); #XXX
self::assertTrue(true);
}
}