Skip to content

Commit

Permalink
Support for options flags
Browse files Browse the repository at this point in the history
  • Loading branch information
knivey committed May 1, 2021
1 parent b701ba5 commit 584410f
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 19 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ $router = new cmdr\Cmdr();
//All command functions will have Request as the last argument
#[cmdr\attributes\Cmd("example", "altname")] //define as many cmds for this function as you want
#[cmdr\attributes\Syntax("<required> [optional]")]
#[cmdr\attributes\Options("--option", "--anotheroption")]
function exampleFunc($additonal, $arguments, cmdr\Request $request) {
echo $request->args["required"];
if(isset($request->args["optional"])
if(isset($request->args["optional"]))
echo $request->args["optional"];
if($request->getOpt('--option'))
echo "--option was used";
}

//Do this AFTER all functions you want to load are defined
Expand Down
30 changes: 27 additions & 3 deletions src/Args.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
*/
class Args implements \ArrayAccess, \Countable
{
public string $syntax;
/**
* @var Arg[] $args
*/
Expand All @@ -24,14 +23,20 @@ class Args implements \ArrayAccess, \Countable
*/
protected array $parsed = Array();

/**
* @var array $parsedOpts
*/
protected array $parsedOpts = Array();

/**
* constructor.
* @param string $syntax
* @param array $opts
* @throws SyntaxException Will throw if syntax is invalid
*/
function __construct(string $syntax)
function __construct(public string $syntax, protected array $opts = [])
{
$this->syntax = $syntax;
$this->opts = array_map('\strtolower', $this->opts);
$argv = array_filter(explode(' ', $syntax));
if (count($argv) == 0) {
return;
Expand Down Expand Up @@ -82,6 +87,17 @@ function __construct(string $syntax)
* @throws ParseException throws exception if required args arent provided
*/
public function parse(string $msg) : Args {
$this->parsedOpts = [];
$msg = explode(' ', $msg);
$msgb = [];
foreach ($msg as $w) {
if(in_array($w, $this->opts))
$this->parsedOpts[$w] = $w;
else
$msgb[] = $w;
}
$msg = implode(' ', $msgb);

$this->parsed = [];
foreach ($this->args as $k => $v)
$this->parsed[$k] = clone $v;
Expand All @@ -102,6 +118,14 @@ public function parse(string $msg) : Args {
return clone $this;
}

public function getOpts() {
return $this->parsedOpts;
}

public function getOpt($name) : bool {
return isset($this->parsedOpts[strtolower($name)]);
}

public function getArg(string $name): ?Arg {
foreach ($this->parsed as &$arg) {
if ($arg->name == $name) {
Expand Down
5 changes: 3 additions & 2 deletions src/Cmd.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ public function __construct(
public $method,
public array $preArgs,
public array $postArgs,
public string $syntax
public string $syntax,
public array $opts
)
{
if(!is_callable($this->method)) {
throw new \Exception("Method argument to Cmd isn't callable (" . print_r($method, 1) .")");
}
$this->cmdArgs = new Args($syntax);
$this->cmdArgs = new Args($syntax, $opts);
}
}
24 changes: 14 additions & 10 deletions src/Cmdr.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ public function __construct()
$this->cmds = new CIArray();
}

function add(string $command, callable $method, array $preArgs = [], array $postArgs = [], string $syntax = '') {
function add(string $command, callable $method, array $preArgs = [], array $postArgs = [], string $syntax = '', array $opts = []) {
if (str_contains($command, '#')) {
throw new \Exception('Command name cannot contain #');
}
if(isset($this->cmds[$command])) {
throw new \Exception('Command already exists');
}
$this->cmds[$command] = new Cmd($command, $method, $preArgs, $postArgs, $syntax);
$this->cmds[$command] = new Cmd($command, $method, $preArgs, $postArgs, $syntax, $opts);
}

function get(string $command, string $text) : Request|false {
Expand Down Expand Up @@ -52,18 +52,22 @@ protected function attrAddCmd($rf, $f) {
$sa = $syntaxAttr[0]->newInstance();
$syntax = $sa->syntax;
}

$callWrapAttr = $rf->getAttributes(attributes\CallWrap::class);
if (isset($callWrapAttr[0])) {
$cw = $callWrapAttr[0]->newInstance();
$callWrapper = $cw->caller;
$callWrapperPre = $cw->preArgs;
if ($cw = ($callWrapAttr[0]??null)?->newInstance()) {
$callWrapperPre = [...$cw->preArgs, $f];
$f = $cw->caller;
$callWrapperPost = $cw->postArgs;
}

$optionsAttr = $rf->getAttributes(attributes\Options::class);
$opts = [];
if(isset($optionsAttr[0]))
$opts = $optionsAttr[0]->newInstance()->options;


foreach ($cmdAttr->args as $command) {
if ($callWrapper != null)
$this->cmds[$command] = new Cmd($command, $callWrapper, [...$callWrapperPre, $f], $callWrapperPost, $syntax);
else
$this->cmds[$command] = new Cmd($command, $f, $callWrapperPre, $callWrapperPost, $syntax);
$this->cmds[$command] = new Cmd($command, $f, $callWrapperPre, $callWrapperPost, $syntax, $opts);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/attributes/Options.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php


namespace knivey\cmdr\attributes;

#[\Attribute]
class Options
{
public array $options;
public function __construct(string ...$options)
{
$this->options = $options;
}
}
38 changes: 38 additions & 0 deletions tests/ArgsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,42 @@ function testArgWhenNotReq()
$args->parse('moo boo poo woo');
$this->assertCount(0, $args);
}


function testOptions()
{
$args = new Args('<foo>...', ['--nes']);
$args->parse('moo boo poo');
$this->assertEquals('moo boo poo', $args[0]);
$this->assertEmpty($args->getOpts());
$args->parse('moo --nes poo');
$this->assertEquals('moo poo', $args[0]);
$this->assertEquals(['--nes'=>'--nes'], $args->getOpts());

$args = new Args('<foo>', ['--nes']);
$args->parse('moo boo poo');
$this->assertEquals('moo', $args[0]);
$this->assertEmpty($args->getOpts());
$args->parse('moo --nes poo');
$this->assertEquals('moo', $args[0]);
$this->assertEquals(['--nes'=>'--nes'], $args->getOpts());

$args = new Args('[foo]', ['--nes']);
$args->parse('moo boo poo');
$this->assertEquals('moo', $args[0]);
$this->assertEmpty($args->getOpts());
$args->parse('--nes moo');
$this->assertEquals('moo', $args[0]);
$this->assertTrue($args->getOpt('--nes'));

$args = new Args('[foo]', ['--nes', '--bar']);
$args->parse('moo --nes boo poo');
$this->assertEquals('moo', $args[0]);
$this->assertTrue($args->getOpt('--nes'));
$this->assertFalse($args->getOpt('--bar'));
$args->parse('--nes moo --bar');
$this->assertEquals('moo', $args[0]);
$this->assertTrue($args->getOpt('--nes'));
$this->assertTrue($args->getOpt('--bar'));
}
}
10 changes: 7 additions & 3 deletions tests/CmdrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace knivey\cmdr\test;

use knivey\cmdr\attributes\Options;
use knivey\cmdr\Cmdr;
use knivey\cmdr\Request;
use knivey\cmdr\attributes\Cmd;
Expand Down Expand Up @@ -44,10 +45,11 @@ public function testUsingAdd()
$lol = function ($req) use(&$cnt) {
$this->assertInstanceOf(Request::class, $req);
$this->assertEquals('abc def', $req->args['stuff']);
$this->assertEquals(['--bar'], $req->args->getOpts());
$cnt++;
};
$cmdr->add('test', $lol, syntax: '<stuff>...');
$cmdr->call('test', 'abc def');
$cmdr->add('test', $lol, syntax: '<stuff>...', opts: ['--bar']);
$cmdr->call('test', 'abc def --bar');
$this->assertEquals(1, $cnt);
}

Expand Down Expand Up @@ -91,10 +93,11 @@ public function testLoadFuncs()
$testFunc =
function ($req) use(&$cnt) {
$this->assertEquals('abc def', $req->args['foo']);
$this->assertTrue($req->args->getOpt('--bar'));
$cnt++;
};
$cmdr->loadFuncs();
$cmdr->call('testattrs', 'abc def');
$cmdr->call('testattrs', 'abc --bar def');
$cmdr->call('noexist', 'abc def');
$this->assertEquals(1, $cnt);
}
Expand Down Expand Up @@ -167,6 +170,7 @@ public function testCallWrapAttribute()

#[Cmd("testAttrs")]
#[Syntax("<foo>...")]
#[Options("--bar")]
function testAttrs(...$args) {
global $testFunc;
$testFunc(...$args);
Expand Down

0 comments on commit 584410f

Please sign in to comment.