modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									b0f5de5e9f
								
							
						
					
					
						commit
						ce86cfe354
					
				
							
								
								
									
										194
									
								
								src/app/cli/Arg.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/app/cli/Arg.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | ||||
| <?php | ||||
| namespace nulib\app\cli; | ||||
| 
 | ||||
| use nulib\A; | ||||
| use nulib\cl; | ||||
| use nulib\php\types\varray; | ||||
| 
 | ||||
| class Arg { | ||||
|   const TYPE_SHORT = 0, TYPE_LONG = 1, TYPE_COMMAND = 2; | ||||
|   const ARGS_NONE = 0, ARGS_MANDATORY = 1, ARGS_OPTIONAL = 2; | ||||
| 
 | ||||
|   function __construct(array $def) { | ||||
|     [$options, $params] = cl::split_assoc($def); | ||||
| 
 | ||||
|     $args = $params["args"] ?? null; | ||||
|     $args ??= $params["arg"] ?? null; | ||||
|     if ($args === true) $args = 1; | ||||
|     if (is_int($args)) $args = array_fill(0, $args, "value"); | ||||
|     $this->_args = cl::withn($args); | ||||
| 
 | ||||
|     $this->argsdesc = $params["argsdesc"] ?? null; | ||||
| 
 | ||||
|     $extends = $params["extends"] ?? null; | ||||
|     if ($extends !== null) { | ||||
|       A::merge($extends["add"], $options); | ||||
|       $this->extends = $extends; | ||||
|       $this->processExtends(); | ||||
|       #XXX à terme, processExtends() est appelé par ArgsParser après le
 | ||||
|       # chargement de tous les arguments, parce que [arg] peut-être une
 | ||||
|       # référence e.g ["extends" => ["arg" => "-o", "add" => ["--longo"]]]
 | ||||
|     } else { | ||||
|       $this->addOptions($options); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   protected ?array $options = []; | ||||
| 
 | ||||
|   function getOptions(): array { | ||||
|     return array_keys($this->options); | ||||
|   } | ||||
| 
 | ||||
|   public bool $haveShortOptions = false; | ||||
|   public bool $haveLongOptions = false; | ||||
|   public bool $haveCommands = false; | ||||
| 
 | ||||
|   public bool $haveArgs = false; | ||||
|   public ?int $minArgs = null; | ||||
|   public ?int $maxArgs = null; | ||||
|   public ?string $argsdesc = null; | ||||
| 
 | ||||
|   function addOptions(?array $options): void { | ||||
|     if ($options === null) return; | ||||
|     foreach ($options as $option) { | ||||
|       if (substr($option, 0, 2) === "--") { | ||||
|         $type = self::TYPE_LONG; | ||||
|         if (preg_match('/^--([^:-]+)(::?)?$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $args = $ms[2] ?? null; | ||||
|           $option = "--$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid long option"); | ||||
|         } | ||||
|       } elseif (substr($option, 0, 1) === "-") { | ||||
|         $type = self::TYPE_SHORT; | ||||
|         if (preg_match('/^-([^:-])(::?)?$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $args = $ms[2] ?? null; | ||||
|           $option = "-$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid short option"); | ||||
|         } | ||||
|       } else { | ||||
|         $type = self::TYPE_COMMAND; | ||||
|         if (preg_match('/^([^:-]+)$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $args = null; | ||||
|           $option = "$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid command"); | ||||
|         } | ||||
|       } | ||||
|       if ($args === ":") { | ||||
|         $argsType = self::ARGS_MANDATORY; | ||||
|       } elseif ($args === "::") { | ||||
|         $argsType = self::ARGS_OPTIONAL; | ||||
|       } else { | ||||
|         $argsType = self::ARGS_NONE; | ||||
|       } | ||||
|       $this->options[$option] = [ | ||||
|         "name" => $name, | ||||
|         "option" => $option, | ||||
|         "type" => $type, | ||||
|         "args_type" => $argsType, | ||||
|       ]; | ||||
|     } | ||||
|     $this->updateType(); | ||||
|   } | ||||
| 
 | ||||
|   function removeOptions(?array $options): void { | ||||
|     if ($options === null) return; | ||||
|     foreach ($options as $option) { | ||||
|       if (substr($option, 0, 2) === "--") { | ||||
|         if (preg_match('/^--([^:-]+)(::?)?$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $option = "--$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid long option"); | ||||
|         } | ||||
|       } elseif (substr($option, 0, 1) === "-") { | ||||
|         if (preg_match('/^-([^:-])(::?)?$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $option = "-$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid short option"); | ||||
|         } | ||||
|       } else { | ||||
|         if (preg_match('/^([^:-]+)$/', $option, $ms)) { | ||||
|           $name = $ms[1]; | ||||
|           $option = "$name"; | ||||
|         } else { | ||||
|           throw new ArgException("$option: invalid command"); | ||||
|         } | ||||
|       } | ||||
|       unset($this->options[$option]); | ||||
|     } | ||||
|     $this->updateType(); | ||||
|   } | ||||
| 
 | ||||
|   protected ?array $extends; | ||||
| 
 | ||||
|   function processExtends(): void { | ||||
|     $extends = $this->extends; | ||||
|     $base = $extends["arg"] ?? null; | ||||
|     if ($base === null) return; | ||||
|     $base = new self($base); | ||||
|     $this->options = $base->options; | ||||
|     $this->removeOptions(varray::withn($extends["remove"] ?? null)); | ||||
|     $this->addOptions(varray::withn($extends["add"] ?? null)); | ||||
|   } | ||||
| 
 | ||||
|   protected function updateType(): void { | ||||
|     $haveShortOptions = false; | ||||
|     $haveLongOptions = false; | ||||
|     $haveCommands = false; | ||||
|     foreach ($this->options as $option) { | ||||
|       switch ($option["type"]) { | ||||
|       case self::TYPE_SHORT: | ||||
|         $haveShortOptions = true; | ||||
|         break; | ||||
|       case self::TYPE_LONG: | ||||
|         $haveLongOptions = true; | ||||
|         break; | ||||
|       case self::TYPE_COMMAND: | ||||
|         $haveCommands = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     $this->haveShortOptions = $haveShortOptions; | ||||
|     $this->haveLongOptions = $haveLongOptions; | ||||
|     $this->haveCommands = $haveCommands; | ||||
|   } | ||||
| 
 | ||||
|   protected ?array $_args = null; | ||||
| 
 | ||||
|   protected function updateArgs(): void { | ||||
|     if ($this->_args === null) { | ||||
|       $haveArgs = false; | ||||
|       $optionalArgs = null; | ||||
|       foreach ($this->options as $option) { | ||||
|         switch ($option["args_type"]) { | ||||
|         case self::ARGS_NONE: | ||||
|           break; | ||||
|         case self::ARGS_MANDATORY: | ||||
|           $haveArgs = true; | ||||
|           $optionalArgs = false; | ||||
|           break; | ||||
|         case self::ARGS_OPTIONAL: | ||||
|           $haveArgs = true; | ||||
|           $optionalArgs ??= true; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       $optionalArgs ??= false; | ||||
|       if ($haveArgs) { | ||||
|         $args = ["value"]; | ||||
|         if ($optionalArgs) $args = [$args]; | ||||
|       } | ||||
|     } | ||||
|     #XXX calculer minArgs, maxArgs, argsdesc
 | ||||
|     $this->haveArgs = $haveArgs; | ||||
|     $this->_args = $args; | ||||
|     $this->argsdesc = $argsdesc; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/app/cli/ArgException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/app/cli/ArgException.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| <?php | ||||
| namespace nulib\app\cli; | ||||
| 
 | ||||
| use nulib\ValueException; | ||||
| 
 | ||||
| class ArgException extends ValueException { | ||||
| } | ||||
							
								
								
									
										48
									
								
								tests/app/cli/ArgTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/app/cli/ArgTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| <?php | ||||
| namespace nulib\app\cli; | ||||
| 
 | ||||
| use nur\t\TestCase; | ||||
| 
 | ||||
| class ArgTest extends TestCase { | ||||
|   function testBase() { | ||||
|     $arg = new Arg(["-o", "--longo"]); | ||||
|     self::assertSame(["-o", "--longo"], $arg->getOptions()); | ||||
|     self::assertFalse($arg->haveArgs); | ||||
|     self::assertFalse($arg->optionalArgs); | ||||
| 
 | ||||
|     $arg = new Arg(["-o:", "--longo"]); | ||||
|     self::assertSame(["-o", "--longo"], $arg->getOptions()); | ||||
|     self::assertTrue($arg->haveArgs); | ||||
|     self::assertFalse($arg->optionalArgs); | ||||
| 
 | ||||
|     $arg = new Arg(["-o::", "--longo"]); | ||||
|     self::assertSame(["-o", "--longo"], $arg->getOptions()); | ||||
|     self::assertTrue($arg->haveArgs); | ||||
|     self::assertTrue($arg->optionalArgs); | ||||
| 
 | ||||
|     $arg = new Arg(["-o:", "--longo:"]); | ||||
|     self::assertSame(["-o", "--longo"], $arg->getOptions()); | ||||
|     self::assertTrue($arg->haveArgs); | ||||
|     self::assertFalse($arg->optionalArgs); | ||||
| 
 | ||||
|     $arg = new Arg(["-o:", "--longo::"]); | ||||
|     self::assertSame(["-o", "--longo"], $arg->getOptions()); | ||||
|     self::assertTrue($arg->haveArgs); | ||||
|     self::assertFalse($arg->optionalArgs); | ||||
|   } | ||||
| 
 | ||||
|   function testExtends() { | ||||
|     $basedef = ["-o:", "--longo"]; | ||||
|     $def = [ | ||||
|       "extends" => [ | ||||
|         "arg" => $basedef, | ||||
|         "add" => ["-a", "--longa"], | ||||
|         "remove" => ["-o", "--longo"], | ||||
|       ], | ||||
|     ]; | ||||
|     $arg = new Arg($def); | ||||
|     self::assertSame(["-a", "--longa"], $arg->getOptions()); | ||||
|     self::assertFalse($arg->haveArgs); | ||||
|     self::assertFalse($arg->optionalArgs); | ||||
|   } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user