Skip to content

Commit 0ed0b93

Browse files
committed
refactor: enhance InstallCommand with improved contract handling and rename methods for consistency
- Updated method names in `InstallCommand` to reflect contract-specific responsibilities (`selectTargetIdes` -> `selectTargetMcpClients`). - Introduced `getSelectionConfig` to centralize configuration for contract-based selection. - Standardized `CodeEnvironment` method behaviors (`name()` -> `displayName()`). - Adjusted tests to align with updated method and property names. - Included exception handling for unsupported contract classes.
1 parent 391ad01 commit 0ed0b93

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

src/Console/InstallCommand.php

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Support\Arr;
1010
use Illuminate\Support\Collection;
1111
use Illuminate\Support\Str;
12+
use InvalidArgumentException;
1213
use Laravel\Boost\Contracts\Agent;
1314
use Laravel\Boost\Contracts\McpClient;
1415
use Laravel\Boost\Install\Cli\DisplayHelper;
@@ -118,7 +119,7 @@ private function collectInstallationPreferences(): void
118119
{
119120
$this->selectedBoostFeatures = $this->selectBoostFeatures();
120121
$this->enforceTests = $this->determineTestEnforcement(ask: false);
121-
$this->selectedTargetMcpClient = $this->selectTargetIdes();
122+
$this->selectedTargetMcpClient = $this->selectTargetMcpClients();
122123
$this->selectedTargetAgents = $this->selectTargetAgents();
123124
}
124125

@@ -143,9 +144,9 @@ private function discoverTools(): array
143144
->name('*.php');
144145

145146
foreach ($finder as $toolFile) {
146-
$fqdn = 'Laravel\\Boost\\Mcp\\Tools\\'.$toolFile->getBasename('.php');
147-
if (class_exists($fqdn)) {
148-
$tools[$fqdn] = Str::headline($toolFile->getBasename('.php'));
147+
$fullyClassifiedClassName = 'Laravel\\Boost\\Mcp\\Tools\\'.$toolFile->getBasename('.php');
148+
if (class_exists($fullyClassifiedClassName)) {
149+
$tools[$fullyClassifiedClassName] = Str::headline($toolFile->getBasename('.php'));
149150
}
150151
}
151152

@@ -260,14 +261,14 @@ protected function boostToolsToDisable(): array
260261
/**
261262
* @return Collection<int, CodeEnvironment>
262263
*/
263-
private function selectTargetIdes(): Collection
264+
private function selectTargetMcpClients(): Collection
264265
{
265266
if (! $this->shouldInstallMcp() && ! $this->shouldInstallHerdMcp()) {
266267
return collect();
267268
}
268269

269270
return $this->selectCodeEnvironments(
270-
'ide',
271+
McpClient::class,
271272
sprintf('Which code editors do you use in %s?', $this->projectName)
272273
);
273274
}
@@ -282,29 +283,47 @@ private function selectTargetAgents(): Collection
282283
}
283284

284285
return $this->selectCodeEnvironments(
285-
'agent',
286+
Agent::class,
286287
sprintf('Which agents need AI guidelines for %s?', $this->projectName)
287288
);
288289
}
289290

291+
/**
292+
* Get configuration settings for contract-specific selection behavior.
293+
*
294+
* @param string $contractClass
295+
* @return array{scroll: int, required: bool, displayMethod: string}
296+
*/
297+
private function getSelectionConfig(string $contractClass): array
298+
{
299+
return match($contractClass) {
300+
Agent::class => ['scroll' => 4, 'required' => false, 'displayMethod' => 'agentName'],
301+
McpClient::class => ['scroll' => 5, 'required' => true, 'displayMethod' => 'displayName'],
302+
default => throw new InvalidArgumentException("Unsupported contract class: {$contractClass}"),
303+
};
304+
}
305+
290306
/**
291307
* @return Collection<int, CodeEnvironment>
292308
*/
293-
private function selectCodeEnvironments(string $type, string $label): Collection
309+
private function selectCodeEnvironments(string $contractClass, string $label): Collection
294310
{
295311
$allEnvironments = $this->codeEnvironmentsDetector->getCodeEnvironments();
312+
$config = $this->getSelectionConfig($contractClass);
296313

297-
$availableEnvironments = $allEnvironments->filter(function (CodeEnvironment $environment) use ($type) {
298-
return ($type === 'ide' && $environment->isMcpClient()) ||
299-
($type === 'agent' && $environment->IsAgent());
314+
$availableEnvironments = $allEnvironments->filter(function (CodeEnvironment $environment) use ($contractClass) {
315+
return $environment instanceof $contractClass;
300316
});
301317

302318
if ($availableEnvironments->isEmpty()) {
303319
return collect();
304320
}
305321

306-
$options = $availableEnvironments->mapWithKeys(function (CodeEnvironment $environment) {
307-
return [get_class($environment) => $environment->displayName()];
322+
$options = $availableEnvironments->mapWithKeys(function (CodeEnvironment $environment) use ($config) {
323+
$displayMethod = $config['displayMethod'];
324+
$displayText = $environment->{$displayMethod}();
325+
326+
return [get_class($environment) => $displayText];
308327
})->sort();
309328

310329
$detectedClasses = [];
@@ -314,8 +333,7 @@ private function selectCodeEnvironments(string $type, string $label): Collection
314333
));
315334

316335
foreach ($installedEnvNames as $envKey) {
317-
$matchingEnv = $availableEnvironments->first(fn (CodeEnvironment $env) => strtolower($envKey) === strtolower($env->name())
318-
);
336+
$matchingEnv = $availableEnvironments->first(fn (CodeEnvironment $env) => strtolower($envKey) === strtolower($env->name()));
319337
if ($matchingEnv) {
320338
$detectedClasses[] = get_class($matchingEnv);
321339
}
@@ -325,10 +343,15 @@ private function selectCodeEnvironments(string $type, string $label): Collection
325343
label: $label,
326344
options: $options->toArray(),
327345
default: array_unique($detectedClasses),
328-
scroll: $type === 'ide' ? 5 : 4,
329-
required: $type === 'ide',
346+
scroll: $config['scroll'],
347+
required: $config['required'],
330348
hint: empty($detectedClasses) ? null : sprintf('Auto-detected %s for you',
331-
Arr::join(array_map(fn ($className) => $availableEnvironments->first(fn ($env) => get_class($env) === $className)->displayName(), $detectedClasses), ', ', ' & ')
349+
Arr::join(array_map(function ($className) use ($availableEnvironments, $config) {
350+
$env = $availableEnvironments->first(fn ($env) => get_class($env) === $className);
351+
$displayMethod = $config['displayMethod'];
352+
353+
return $env->{$displayMethod}();
354+
}, $detectedClasses), ', ', ' & ')
332355
)
333356
))->sort();
334357

src/Install/CodeEnvironment/CodeEnvironment.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ abstract public function displayName(): string;
2525

2626
public function agentName(): ?string
2727
{
28-
return $this->name();
28+
return $this->displayName();
2929
}
3030

3131
public function mcpClientName(): ?string
3232
{
33-
return $this->name();
33+
return $this->displayName();
3434
}
3535

3636
/**

src/Install/CodeEnvironment/PhpStorm.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function projectDetectionConfig(): array
5252

5353
public function agentName(): string
5454
{
55-
return 'junie';
55+
return 'Junie';
5656
}
5757

5858
public function mcpConfigPath(): string

tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,16 @@ public function mcpConfigPath(): string
122122
expect($result)->toBe(false);
123123
});
124124

125-
test('agentName returns name by default', function () {
125+
test('agentName returns displayName by default', function () {
126126
$environment = new TestCodeEnvironment($this->strategyFactory);
127127

128-
expect($environment->agentName())->toBe('test');
128+
expect($environment->agentName())->toBe('Test Environment');
129129
});
130130

131-
test('mcpClientName returns name by default', function () {
131+
test('mcpClientName returns displayName by default', function () {
132132
$environment = new TestCodeEnvironment($this->strategyFactory);
133133

134-
expect($environment->mcpClientName())->toBe('test');
134+
expect($environment->mcpClientName())->toBe('Test Environment');
135135
});
136136

137137
test('IsAgent returns true when implements Agent interface and has agentName', function () {

0 commit comments

Comments
 (0)