Skip to content

Commit

Permalink
fix: sync long and short option value error
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Dec 13, 2019
1 parent 0b55ec4 commit ac41eca
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 80 deletions.
6 changes: 5 additions & 1 deletion src/console/src/Annotation/Parser/CommandOptionParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ public function parse(int $type, $option): array
}

$method = $this->methodName;
$valType = $option->getType();
$defVal = $option->getDefault();
$valType = $option->getType();

// if ($valType === 'BOOL') {
// $defVal = Flags::filterBool($defVal);
// }

// Add route info for group command action
CommandRegister::bindOption($this->className, $method, $option->getName(), [
Expand Down
79 changes: 3 additions & 76 deletions src/console/src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
use Swoft;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\BeanFactory;
use Swoft\Console\Annotation\Mapping\Command;
use Swoft\Console\Concern\RenderHelpInfoTrait;
use Swoft\Console\Contract\ConsoleInterface;
use Swoft\Console\Exception\CommandFlagException;
use Swoft\Console\Input\Input;
use Swoft\Console\Output\Output;
use Swoft\Console\Router\Router;
Expand All @@ -18,8 +16,6 @@
use Throwable;
use function array_merge;
use function implode;
use function input;
use function output;
use function strpos;
use function strtr;
use function trim;
Expand Down Expand Up @@ -121,8 +117,8 @@ public function commentsVars(): array

protected function prepare(): void
{
$this->input = input();
$this->output = output();
$this->input = Swoft::getBean('input');
$this->output = Swoft::getBean('output');

// load builtin comments vars
$this->setCommentsVars($this->commentsVars());
Expand Down Expand Up @@ -198,7 +194,7 @@ protected function doRun(string $inputCmd): void
}

// Parse default options and arguments
$this->bindCommandFlags($info);
$this->input->bindingFlags($info);
$this->input->setCommandId($info['cmdId']);

Swoft::triggerByArray(ConsoleEvent::DISPATCH_BEFORE, $this, $info);
Expand Down Expand Up @@ -228,75 +224,6 @@ private function filterSpecialOption(): void
$this->showApplicationHelp(false);
}

/**
* Bind option and argument values by route info
*
* @param array $info
*
* @throws CommandFlagException
*/
protected function bindCommandFlags(array $info): void
{
// Bind options
if ($opts = $info['options']) {
$sOpts = $this->input->getSOpts();
$lOpts = $this->input->getLOpts();

foreach ($opts as $name => $opt) {
$inputVal = $this->input->getLongOpt($name);

// Exist short
if (null === $inputVal && $opt['short']) {
$inputVal = $this->input->getShortOpt($opt['short']);
}

// Exist default value
if (null === $inputVal && isset($opt['default'])) {
$inputVal = $opt['default'];
}

if (null !== $inputVal) {
$sOpts[$name] = $lOpts[$name] = $inputVal;

// Required check
} elseif ($opt['mode'] === Command::OPT_REQUIRED) {
$short = $opt['short'] ? "(short: {$opt['short']})" : '';
throw new CommandFlagException("The option '{$name}'{$short} is required");
}
}

// Save to input
$this->input->setLOpts($lOpts, true);
$this->input->setSOpts($sOpts, true);
}

// Bind named argument by index
if ($args = $info['arguments']) {
$index = 0;
$values = $this->input->getArgs();

foreach ($args as $name => $arg) {
// Bind value to name
if (isset($values[$index])) {
$values[$name] = $values[$index];
// Bind default value
} elseif (isset($arg['default'])) {
$values[$name] = $arg['default'];
$values[$index] = $arg['default'];
}

// Check arg is required
if ($arg['mode'] === Command::ARG_REQUIRED && empty($values[$name])) {
throw new CommandFlagException("The argument '{$name}'(position: {$index}) is required");
}

$index++;
}

$this->input->setArgs($values, true);
}
}

/**
* Replace the variable in the comment with the corresponding value
*
Expand Down
15 changes: 15 additions & 0 deletions src/console/src/FlagType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);

namespace Swoft\Console;

use Swoft\Stdlib\PhpType;

/**
* Class FlagType
*
* @since 2.0.8
*/
class FlagType extends PhpType
{

}
108 changes: 105 additions & 3 deletions src/console/src/Input/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Swoft\Console\Input;

use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Console\Annotation\Mapping\Command;
use Swoft\Console\Exception\CommandFlagException;
use Toolkit\Cli\Flags;
use function array_map;
use function array_shift;
Expand Down Expand Up @@ -49,8 +51,9 @@ public function __construct(array $args = null, bool $parsing = true)
$args = (array)$_SERVER['argv'];
}

$this->pwd = $this->getPwd();
$this->tokens = $args;
$this->pwd = $this->getPwd();
$this->tokens = $args;

$this->scriptFile = array_shift($args);
$this->fullScript = implode(' ', $args);

Expand Down Expand Up @@ -101,7 +104,106 @@ public function read(string $question = '', bool $nl = false): string
}

/***********************************************************************************
* getter/setter
* Binding options and arguments
***********************************************************************************/

/**
* Binding options and arguments by give config
*
* @param array $info
*
* @throws CommandFlagException
*/
public function bindingFlags(array $info): void
{
// Bind options
if ($opts = $info['options']) {
$this->bindingOptions($opts);
}

// Bind named argument by index
if ($args = $info['arguments']) {
$this->bindingArguments($args);
}
}

/**
* @param array $opts
*
* @throws CommandFlagException
*/
protected function bindingOptions(array $opts): void
{
$sOpts = $this->getSOpts();
$lOpts = $this->getLOpts();

foreach ($opts as $name => $opt) {
$shortName = $opt['short'];
$inputVal = $this->getLongOpt($name);

// Exist short
if (null === $inputVal && $shortName) {
$inputVal = $this->getShortOpt($shortName);
}

// Exist default value
if (null === $inputVal && isset($opt['default'])) {
$inputVal = $opt['default'];
}

// Has option value
if (null !== $inputVal) {
$lOpts[$name] = $inputVal;

if ($shortName) {
$sOpts[$shortName] = $inputVal;
}

// Value is required
} elseif ($opt['mode'] === Command::OPT_REQUIRED) {
$short = $shortName ? "(short: {$shortName})" : '';
throw new CommandFlagException("The option '{$name}'{$short} is required");
}
}

// Save to input
$this->setLOpts($lOpts, true);
$this->setSOpts($sOpts, true);
}

/**
* @param array $args
*
* @throws CommandFlagException
*/
protected function bindingArguments(array $args): void
{
$index = 0;
$values = $this->getArgs();

foreach ($args as $name => $arg) {
// Bind value to name
if (isset($values[$index])) {
$values[$name] = $values[$index];
// Bind default value
} elseif (isset($arg['default'])) {
$values[$name] = $arg['default'];
$values[$index] = $arg['default'];
}

// Check arg is required
if ($arg['mode'] === Command::ARG_REQUIRED && empty($values[$name])) {
throw new CommandFlagException("The argument '{$name}'(position: {$index}) is required");
}

$index++;
}

$this->setArgs($values, true);
}

/***********************************************************************************
* Getter/setter methods
***********************************************************************************/

/**
Expand Down
40 changes: 40 additions & 0 deletions src/console/test/unit/Input/InputTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php declare(strict_types=1);

namespace SwoftTest\Console\Unit\Input;

use PHPUnit\Framework\TestCase;
use Swoft\Console\Exception\CommandFlagException;
use Swoft\Console\Input\Input;

class InputTest extends TestCase
{
/**
* @throws CommandFlagException
*/
public function testBindingFlags(): void
{
$args = ['bin/swoft', '-d', '12'];
// value sync binding
$info = [
'options' => [
'day' => [
'short' => 'd',
],
],
'arguments' => [],
];

$in = new Input($args);
$in->bindingFlags($info);

$this->assertSame('12', $in->getOpt('day'));
$this->assertSame('12', $in->getOpt('d'));

$args = ['bin/swoft', '--day', '12'];
$in = new Input($args);
$in->bindingFlags($info);

$this->assertSame('12', $in->getOpt('day'));
$this->assertSame('12', $in->getOpt('d'));
}
}

0 comments on commit ac41eca

Please sign in to comment.