mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Added as command for static method (#6978)
This commit is contained in:
parent
e2191cfa73
commit
4414bd2965
@ -1,5 +1,9 @@
|
|||||||
# v3.1.34 - TBD
|
# v3.1.34 - TBD
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- [#6978](https://github.com/hyperf/hyperf/pull/6978) Added as command for static method.
|
||||||
|
|
||||||
# v3.1.33 - 2024-07-25
|
# v3.1.33 - 2024-07-25
|
||||||
|
|
||||||
## Optimized
|
## Optimized
|
||||||
|
@ -12,7 +12,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Hyperf\Command;
|
namespace Hyperf\Command;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
use Hyperf\Command\Concerns\InteractsWithIO;
|
use Hyperf\Command\Concerns\InteractsWithIO;
|
||||||
|
use Hyperf\Di\ReflectionManager;
|
||||||
use Hyperf\Stringable\Str;
|
use Hyperf\Stringable\Str;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
@ -56,6 +58,12 @@ final class AsCommand extends Command
|
|||||||
{
|
{
|
||||||
$inputs = array_merge($this->input->getArguments(), $this->input->getOptions());
|
$inputs = array_merge($this->input->getArguments(), $this->input->getOptions());
|
||||||
$parameters = $this->parameterParser->parseMethodParameters($this->class, $this->method, $inputs);
|
$parameters = $this->parameterParser->parseMethodParameters($this->class, $this->method, $inputs);
|
||||||
|
|
||||||
|
if (ReflectionManager::reflectMethod($this->class, $this->method)->isStatic()) {
|
||||||
|
Closure::bind(fn ($method) => self::{$method}(...$parameters), null, $this->class)($this->method);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$instance = $this->container->get($this->class);
|
$instance = $this->container->get($this->class);
|
||||||
|
|
||||||
if (in_array(InteractsWithIO::class, class_uses_recursive($this->class))) {
|
if (in_array(InteractsWithIO::class, class_uses_recursive($this->class))) {
|
||||||
|
@ -17,6 +17,7 @@ use Hyperf\Crontab\Crontab;
|
|||||||
use Hyperf\Crontab\Schedule;
|
use Hyperf\Crontab\Schedule;
|
||||||
use Hyperf\Stringable\Str;
|
use Hyperf\Stringable\Str;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
use ReflectionFunction;
|
||||||
|
|
||||||
use function Hyperf\Tappable\tap;
|
use function Hyperf\Tappable\tap;
|
||||||
|
|
||||||
@ -57,6 +58,12 @@ final class ClosureCommand extends Command
|
|||||||
{
|
{
|
||||||
$inputs = array_merge($this->input->getArguments(), $this->input->getOptions());
|
$inputs = array_merge($this->input->getArguments(), $this->input->getOptions());
|
||||||
$parameters = $this->parameterParser->parseClosureParameters($this->closure, $inputs);
|
$parameters = $this->parameterParser->parseClosureParameters($this->closure, $inputs);
|
||||||
|
$ref = new ReflectionFunction($this->closure);
|
||||||
|
|
||||||
|
if ($ref->isStatic()) {
|
||||||
|
($this->closure)(...$parameters);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->closure->call($this, ...$parameters);
|
$this->closure->call($this, ...$parameters);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@ use HyperfTest\Command\Command\Annotation\TestAsCommand;
|
|||||||
use Mockery;
|
use Mockery;
|
||||||
use PHPUnit\Framework\Attributes\CoversNothing;
|
use PHPUnit\Framework\Attributes\CoversNothing;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RuntimeException;
|
||||||
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
|
use Symfony\Component\Console\Output\BufferedOutput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -84,7 +87,7 @@ class AsCommandAndClosureCommandTest extends TestCase
|
|||||||
);
|
);
|
||||||
|
|
||||||
$commands = array_values($this->containerSet);
|
$commands = array_values($this->containerSet);
|
||||||
$this->assertCount(3, $commands);
|
$this->assertCount(4, $commands);
|
||||||
|
|
||||||
$runCommand = $commands[0];
|
$runCommand = $commands[0];
|
||||||
$runCommandDefinition = $runCommand->getDefinition();
|
$runCommandDefinition = $runCommand->getDefinition();
|
||||||
@ -110,29 +113,71 @@ class AsCommandAndClosureCommandTest extends TestCase
|
|||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('name'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('name'));
|
||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('age'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('age'));
|
||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('testBool'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('testBool'));
|
||||||
|
|
||||||
|
$runStaticCommand = $commands[3];
|
||||||
|
$runStaticCommand->setInput(new ArrayInput([]));
|
||||||
|
$runStaticCommand->setOutput(new BufferedOutput());
|
||||||
|
$runStaticCommandDefinition = $runStaticCommand->getDefinition();
|
||||||
|
$this->assertEquals($this->getSignature($runStaticCommand), 'command:as-command:runStatic');
|
||||||
|
$this->assertEquals(count($runStaticCommandDefinition->getOptions()), 1);
|
||||||
|
$this->assertEquals(count($runStaticCommandDefinition->getArguments()), 0);
|
||||||
|
// assert runtime exception
|
||||||
|
try {
|
||||||
|
$runStaticCommand->handle();
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$this->assertEquals('command:as-command:runStatic', $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRegisterClosureCommand()
|
public function testRegisterClosureCommand()
|
||||||
{
|
{
|
||||||
$runCommand = Console::command('command:closure:run', function () {
|
$runCommand = Console::command('command:closure:run', function () {
|
||||||
return 'closure';
|
throw new RuntimeException('command:closure:run');
|
||||||
});
|
});
|
||||||
|
$runCommand->setInput(new ArrayInput([]));
|
||||||
|
$runCommand->setOutput(new BufferedOutput());
|
||||||
$runCommandDefinition = $runCommand->getDefinition();
|
$runCommandDefinition = $runCommand->getDefinition();
|
||||||
$this->assertEquals($this->getSignature($runCommand), 'command:closure:run');
|
$this->assertEquals($this->getSignature($runCommand), 'command:closure:run');
|
||||||
$this->assertEquals(count($runCommandDefinition->getOptions()), 1);
|
$this->assertEquals(count($runCommandDefinition->getOptions()), 1);
|
||||||
$this->assertEquals(count($runCommandDefinition->getArguments()), 0);
|
$this->assertEquals(count($runCommandDefinition->getArguments()), 0);
|
||||||
$this->assertNotNull($runCommandDefinition->getOption('disable-event-dispatcher'));
|
$this->assertNotNull($runCommandDefinition->getOption('disable-event-dispatcher'));
|
||||||
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('command:closure:run');
|
||||||
|
$runCommand->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRegisterStaticClosureCommand()
|
||||||
|
{
|
||||||
|
$runCommand = Console::command('command:closure:run-static', static function () {
|
||||||
|
throw new RuntimeException('command:closure:run-static');
|
||||||
|
});
|
||||||
|
$runCommand->setInput(new ArrayInput([]));
|
||||||
|
$runCommand->setOutput(new BufferedOutput());
|
||||||
|
$runCommandDefinition = $runCommand->getDefinition();
|
||||||
|
$this->assertEquals($this->getSignature($runCommand), 'command:closure:run-static');
|
||||||
|
$this->assertEquals(count($runCommandDefinition->getOptions()), 1);
|
||||||
|
$this->assertEquals(count($runCommandDefinition->getArguments()), 0);
|
||||||
|
$this->assertNotNull($runCommandDefinition->getOption('disable-event-dispatcher'));
|
||||||
|
$this->expectException(RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('command:closure:run-static');
|
||||||
|
$runCommand->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRegisterClosureCommandWithDefineOptions()
|
||||||
|
{
|
||||||
$runWithDefinedOptionsCommand = Console::command('command:closure:withDefineOptions {--name=}', function (string $name) {
|
$runWithDefinedOptionsCommand = Console::command('command:closure:withDefineOptions {--name=}', function (string $name) {
|
||||||
return 'with define options';
|
return $name;
|
||||||
});
|
});
|
||||||
$runWithDefinedOptionsCommandDefinition = $runWithDefinedOptionsCommand->getDefinition();
|
$runWithDefinedOptionsCommandDefinition = $runWithDefinedOptionsCommand->getDefinition();
|
||||||
$this->assertEquals($this->getSignature($runWithDefinedOptionsCommand), 'command:closure:withDefineOptions {--name=}');
|
$this->assertEquals($this->getSignature($runWithDefinedOptionsCommand), 'command:closure:withDefineOptions {--name=}');
|
||||||
$this->assertEquals(count($runWithDefinedOptionsCommandDefinition->getOptions()), 2);
|
$this->assertEquals(count($runWithDefinedOptionsCommandDefinition->getOptions()), 2);
|
||||||
$this->assertEquals(count($runWithDefinedOptionsCommandDefinition->getArguments()), 0);
|
$this->assertEquals(count($runWithDefinedOptionsCommandDefinition->getArguments()), 0);
|
||||||
$this->assertNotNull($runCommandDefinition->getOption('disable-event-dispatcher'));
|
$this->assertNotNull($runWithDefinedOptionsCommandDefinition->getOption('disable-event-dispatcher'));
|
||||||
$this->assertNotNull($runWithDefinedOptionsCommandDefinition->getOption('name'));
|
$this->assertNotNull($runWithDefinedOptionsCommandDefinition->getOption('name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRegisterClosureCommandWithoutDefineOptions()
|
||||||
|
{
|
||||||
$runWithoutOptionsCommand = Console::command('command:closure:withoutDefineOptions', function (string $name, int $age = 9, bool $testBool = false) {
|
$runWithoutOptionsCommand = Console::command('command:closure:withoutDefineOptions', function (string $name, int $age = 9, bool $testBool = false) {
|
||||||
return 'with define options';
|
return 'with define options';
|
||||||
});
|
});
|
||||||
@ -140,7 +185,7 @@ class AsCommandAndClosureCommandTest extends TestCase
|
|||||||
$this->assertEquals($this->getSignature($runWithoutOptionsCommand), 'command:closure:withoutDefineOptions');
|
$this->assertEquals($this->getSignature($runWithoutOptionsCommand), 'command:closure:withoutDefineOptions');
|
||||||
$this->assertEquals(count($runWithoutOptionsCommandDefinition->getOptions()), 4);
|
$this->assertEquals(count($runWithoutOptionsCommandDefinition->getOptions()), 4);
|
||||||
$this->assertEquals(count($runWithoutOptionsCommandDefinition->getArguments()), 0);
|
$this->assertEquals(count($runWithoutOptionsCommandDefinition->getArguments()), 0);
|
||||||
$this->assertNotNull($runCommandDefinition->getOption('disable-event-dispatcher'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('disable-event-dispatcher'));
|
||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('name'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('name'));
|
||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('age'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('age'));
|
||||||
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('testBool'));
|
$this->assertNotNull($runWithoutOptionsCommandDefinition->getOption('testBool'));
|
||||||
|
@ -13,6 +13,7 @@ declare(strict_types=1);
|
|||||||
namespace HyperfTest\Command\Command\Annotation;
|
namespace HyperfTest\Command\Command\Annotation;
|
||||||
|
|
||||||
use Hyperf\Command\Annotation\AsCommand;
|
use Hyperf\Command\Annotation\AsCommand;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
class TestAsCommand
|
class TestAsCommand
|
||||||
{
|
{
|
||||||
@ -33,4 +34,10 @@ class TestAsCommand
|
|||||||
{
|
{
|
||||||
return 'runWithoutOptions';
|
return 'runWithoutOptions';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[AsCommand('command:as-command:runStatic')]
|
||||||
|
protected static function runStatic()
|
||||||
|
{
|
||||||
|
throw new RuntimeException('command:as-command:runStatic');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user