Skip to content

Commit d79d461

Browse files
committed
refactor: centralize command retrieval through DevTools API
1 parent d4b344a commit d79d461

4 files changed

Lines changed: 56 additions & 24 deletions

File tree

src/Composer/Capability/DevToolsCommandProvider.php

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,22 @@
2222
use Composer\Plugin\Capability\CommandProvider;
2323
use FastForward\DevTools\Composer\Command\ProxyCommand;
2424
use FastForward\DevTools\Console\DevTools;
25+
use Symfony\Component\Console\Command\Command;
2526

2627
/**
2728
* Provides a registry of custom dev-tools commands mapped for Composer integration.
2829
* This capability struct MUST implement the defined `CommandProvider`.
2930
*/
3031
final class DevToolsCommandProvider implements CommandProvider
3132
{
32-
private const string COMMAND_NAMESPACE = 'FastForward\\DevTools\\Console\\Command\\';
33-
3433
/**
3534
* {@inheritDoc}
3635
*/
3736
public function getCommands()
3837
{
39-
$commands = [];
40-
41-
foreach (DevTools::create()->all() as $command) {
42-
if (! str_starts_with($command::class, self::COMMAND_NAMESPACE)) {
43-
continue;
44-
}
45-
46-
$id = spl_object_hash($command);
47-
48-
if (isset($commands[$id])) {
49-
continue;
50-
}
51-
52-
$commands[$id] = new ProxyCommand($command);
53-
}
54-
55-
return $commands;
38+
return array_map(
39+
static fn(Command $command): ProxyCommand => new ProxyCommand($command),
40+
iterator_to_array(DevTools::create()->getCommands()),
41+
);
5642
}
5743
}

src/Console/DevTools.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ final class DevTools extends Application
5353
*
5454
* @param CommandLoaderInterface $commandLoader the command loader responsible for providing command instances
5555
*/
56-
public function __construct(CommandLoaderInterface $commandLoader)
57-
{
56+
public function __construct(
57+
private readonly CommandLoaderInterface $commandLoader
58+
) {
5859
parent::__construct('Fast Forward Dev Tools');
5960

6061
$this->setDefaultCommand('standards');
61-
$this->setCommandLoader($commandLoader);
62+
$this->setCommandLoader($this->commandLoader);
6263
}
6364

6465
/**
@@ -72,6 +73,18 @@ public function getHelp(): string
7273
return self::LOGO . "\n\n" . parent::getHelp();
7374
}
7475

76+
/**
77+
* Retrieves the shared DevTools service container.
78+
*
79+
* @return iterable
80+
*/
81+
public function getCommands(): iterable
82+
{
83+
foreach ($this->commandLoader->getNames() as $name) {
84+
yield $name => $this->commandLoader->get($name);
85+
}
86+
}
87+
7588
/**
7689
* Create DevTools instance from container.
7790
*

tests/Composer/Capability/DevToolsCommandProviderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected function setUp(): void
5757
->willReturn($this->devTools->reveal())
5858
->shouldBeCalledOnce();
5959

60-
$this->devTools->all()
60+
$this->devTools->getCommands()
6161
->willReturn([])->shouldBeCalledOnce();
6262

6363
$this->commandProvider = new DevToolsCommandProvider();
@@ -90,7 +90,7 @@ public function getCommandsWillReturnComposerProxyCommandsForRegisteredSymfonyCo
9090
$symfonyCommand->setHelp('');
9191
$symfonyCommand->setHidden(false);
9292

93-
$this->devTools->all()
93+
$this->devTools->getCommands()
9494
->willReturn([$symfonyCommand])
9595
->shouldBeCalledOnce();
9696

tests/Console/DevToolsTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,39 @@ public function __construct()
110110
self::assertSame($customCommand, $this->devTools->get('custom'));
111111
}
112112

113+
/**
114+
* @return void
115+
*/
116+
#[Test]
117+
public function getCommandsWillYieldLoaderCommandsWithPreservedKeys(): void
118+
{
119+
$commands = [
120+
'agents' => new class extends Command {
121+
public function __construct()
122+
{
123+
parent::__construct('agents');
124+
}
125+
},
126+
'sync' => new class extends Command {
127+
public function __construct()
128+
{
129+
parent::__construct('sync');
130+
}
131+
},
132+
];
133+
134+
$this->commandLoader->getNames()
135+
->willReturn(array_keys($commands));
136+
$this->commandLoader->get('agents')
137+
->willReturn($commands['agents']);
138+
$this->commandLoader->get('sync')
139+
->willReturn($commands['sync']);
140+
141+
$providedCommands = iterator_to_array($this->devTools->getCommands());
142+
143+
self::assertSame($commands, $providedCommands);
144+
}
145+
113146
/**
114147
* @return void
115148
*/

0 commit comments

Comments
 (0)