8000 Add support for invokable commands in LockableTrait · symfony/symfony@e1521dd · GitHub
[go: up one dir, main page]

Skip to content

Commit e1521dd

Browse files
committed
Add support for invokable commands in LockableTrait
1 parent 901d933 commit e1521dd

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

src/Symfony/Component/Console/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* Add support for help definition via `AsCommand` attribute
1212
* Deprecate methods `Command::getDefaultName()` and `Command::getDefaultDescription()` in favor of the `#[AsCommand]` attribute
1313
* Add support for Markdown format in `Table`
14+
* Add support for invokable commands in `LockableTrait`
1415

1516
7.2
1617
---

src/Symfony/Component/Console/Command/LockableTrait.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Console\Command;
1313

14+
use Symfony\Component\Console\Attribute\AsCommand;
1415
use Symfony\Component\Console\Exception\LogicException;
1516
use Symfony\Component\Lock\LockFactory;
1617
use Symfony\Component\Lock\LockInterface;
@@ -48,10 +49,20 @@ private function lock(?string $name = null, bool $blocking = false): bool
4849
$store = new FlockStore();
4950
}
5051

51-
$this->lockFactory = (new LockFactory($store));
52+
$this->lockFactory = new LockFactory($store);
5253
}
5354

54-
$this->lock = $this->lockFactory->createLock($name ?: $this->getName());
55+
if (!$name) {
56+
if ($this instanceof Command) {
57+
$name = $this->getName();
58+
} elseif ($attribute = (new \ReflectionClass($this::class))->getAttributes(AsCommand::class)) {
59+
$name = $attribute[0]->newInstance()->name;
60+
} else {
61+
throw new LogicException(\sprintf('Lock name missing: provide it via "%s()", #[AsCommand] attribute, or by extending Command class.', __METHOD__));
62+
}
63+
}
64+
65+
$this->lock = $this->lockFactory->createLock($name);
5566
if (!$this->lock->acquire($blocking)) {
5667
$this->lock = null;
5768

src/Symfony/Component/Console/Tests/Command/LockableTraitTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Console\Tests\Command;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Command\Command;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\Lock\LockFactory;
1718
use Symfony\Component\Lock\SharedLockInterface;
@@ -28,6 +29,7 @@ public static function setUpBeforeClass(): void
2829
require_once self::$fixturesPath.'/FooLockCommand.php';
2930
require_once self::$fixturesPath.'/FooLock2Command.php';
3031
require_once self::$fixturesPath.'/FooLock3Command.php';
32+
require_once self::$fixturesPath.'/FooLock4InvokableCommand.php';
3133
}
3234

3335
public function testLockIsReleased()
@@ -80,4 +82,25 @@ public function testCustomLockFactoryIsUsed()
8082
$lockFactory->expects(static::once())->method('createLock')->willReturn($lock);
8183
$this->assertSame(1, $tester->execute([]));
8284
}
85+
86+
public function testLockInvokableCommandReturnsFalseIfAlreadyLockedByAnotherCommand()
87+
{
88+
$command = new Command('foo:lock4');
89+
$command->setCode(new \FooLock4InvokableCommand());
90+
91+
if (SemaphoreStore::isSupported()) {
92+
$store = new SemaphoreStore();
93+
} else {
94+
$store = new FlockStore();
95+
}
96+
97+
$lock = (new LockFactory($store))->createLock($command->getName());
98+
$lock->acquire();
99+
100+
$tester = new CommandTester($command);
101+
$this->assertSame(Command::FAILURE, $tester->execute([]));
102+
103+
$lock->release();
104+
$this->assertSame(Command::SUCCESS, $tester->execute([]));
105+
}
83106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Attribute\AsCommand;
4+
use Symfony\Component\Console\Command\Command;
5+
use Symfony\Component\Console\Command\LockableTrait;
6+< A1B1 div class="diff-text-inner">
7+
#[AsCommand(name: 'foo:lock4')]
8+
class FooLock4InvokableCommand
9+
{
10+
use LockableTrait;
11+
12+
public function __invoke(): int
13+
{
14+
if (!$this->lock()) {
15+
return Command::FAILURE;
16+
}
17+
18+
$this->release();
19+
20+
return Command::SUCCESS;
21+
}
22+
}

0 commit comments

Comments
 (0)
0