Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/Console/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected function runStack(): void

protected function promptForModules(): void
{
if ($this->option('all-modules') || $this->option('modules') || $this->option('dev') || $this->isCI()) {
if ($this->option('all-modules') || $this->option('modules') !== null || $this->option('dev') || $this->isCI()) {
return;
}

Expand Down Expand Up @@ -410,9 +410,8 @@ protected function resolveModuleSelection(array $available): array

return collect($available)
->filter(function (string $package) use ($requested) {
$name = strtolower(Str::after($package, '/'));

return $requested->contains($name);
return $requested->contains(strtolower($package))
|| $requested->contains(strtolower(Str::after($package, '/')));
})
->values()
->all();
Expand Down
7 changes: 4 additions & 3 deletions src/Environments/DockerEnvironment.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,10 @@ public function buildContainerArgs(InstallCommand $command): array
$args[] = $stack;
}

$modules = $command->getSelectedModules();
if (! empty($modules)) {
$args[] = '--modules='.implode(',', $modules);
if ($modules = $command->option('modules')) {
$args[] = '--modules='.$modules;
} else {
$args[] = '--modules='.implode(',', $command->getSelectedModules());
}

foreach (['fresh', 'dev', 'all-modules'] as $opt) {
Expand Down
20 changes: 17 additions & 3 deletions tests/Feature/Environments/DockerEnvironmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,11 @@ public function test_forwards_selected_modules_as_comma_list(): void
$this->assertContains('--modules=saucebase/auth,saucebase/billing', $args);
}

public function test_omits_modules_arg_when_none_selected(): void
public function test_includes_empty_modules_arg_when_none_selected(): void
{
$args = $this->buildArgs(modules: []);

$matched = array_filter($args, fn (string $a) => str_starts_with($a, '--modules='));
$this->assertEmpty($matched);
$this->assertContains('--modules=', $args);
}

public function test_forwards_fresh_flag(): void
Expand Down Expand Up @@ -111,6 +110,21 @@ public function test_forwards_all_modules_flag(): void
$this->assertContains('--all-modules', $args);
}

public function test_forwards_modules_option_when_set_directly(): void
{
$args = $this->buildArgs(modules: [], options: ['modules' => 'saucebase/auth,saucebase/billing']);

$this->assertContains('--modules=saucebase/auth,saucebase/billing', $args);
}

public function test_always_includes_modules_arg_even_when_none_selected(): void
{
$args = $this->buildArgs(modules: [], options: []);

$matched = array_filter($args, fn (string $a) => str_starts_with($a, '--modules='));
$this->assertNotEmpty($matched, '--modules= must always be present so the container skips the interactive prompt');
}

public function test_multiple_flags_are_all_forwarded(): void
{
$args = $this->buildArgs(
Expand Down
44 changes: 44 additions & 0 deletions tests/Feature/InstallCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,50 @@ public function test_all_modules_without_stack_returns_all(): void
$this->assertSame(['saucebase/auth', 'saucebase/react-only'], $result);
}

// -------------------------------------------------------------------------
// resolveModuleSelection — --modules= matching
// -------------------------------------------------------------------------

public function test_resolve_matches_full_package_name(): void
{
$cmd = new TestableInstallCommand;
$cmd->fakeOptions = ['modules' => 'saucebase/auth'];

$result = $cmd->exposedResolveModuleSelection(['saucebase/auth', 'saucebase/billing']);

$this->assertSame(['saucebase/auth'], $result);
}

public function test_resolve_matches_short_name(): void
{
$cmd = new TestableInstallCommand;
$cmd->fakeOptions = ['modules' => 'auth'];

$result = $cmd->exposedResolveModuleSelection(['saucebase/auth', 'saucebase/billing']);

$this->assertSame(['saucebase/auth'], $result);
}

public function test_resolve_matches_mixed_case_short_name(): void
{
$cmd = new TestableInstallCommand;
$cmd->fakeOptions = ['modules' => 'Auth'];

$result = $cmd->exposedResolveModuleSelection(['saucebase/auth', 'saucebase/billing']);

$this->assertSame(['saucebase/auth'], $result);
}

public function test_resolve_matches_multiple_full_package_names(): void
{
$cmd = new TestableInstallCommand;
$cmd->fakeOptions = ['modules' => 'saucebase/auth,saucebase/billing'];

$result = $cmd->exposedResolveModuleSelection(['saucebase/auth', 'saucebase/billing', 'saucebase/settings']);

$this->assertSame(['saucebase/auth', 'saucebase/billing'], $result);
}

// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
Expand Down