Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Add default config for select starter kit modules #11045

Open
wants to merge 6 commits into
base: 5.x
Choose a base branch
from
Open
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
20 changes: 14 additions & 6 deletions src/StarterKits/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,19 +348,27 @@ protected function instantiateModule(array $config, string $key): InstallableMod
*/
protected function instantiateSelectModule(array $config, string $key): InstallableModule|array|bool
{
$skipOptionLabel = Arr::get($config, 'skip_option', 'No');
$skipModuleValue = 'skip_module';

$options = collect($config['options'])
->map(fn ($option, $optionKey) => Arr::get($option, 'label', ucfirst($optionKey)))
->prepend(Arr::get($config, 'skip_option', 'No'), $skipModule = 'skip_module')
->when($skipOptionLabel !== false, fn ($c) => $c->prepend($skipOptionLabel, $skipModuleValue))
->all();

$name = str_replace('_', ' ', $key);

$choice = select(
label: Arr::get($config, 'prompt', "Would you like to install one of the following [{$name}] modules?"),
options: $options,
);
if ($this->isInteractive) {
$choice = select(
label: Arr::get($config, 'prompt', "Would you like to install one of the following [{$name}] modules?"),
options: $options,
default: Arr::get($config, 'default'),
);
} elseif (! $this->isInteractive && ! $choice = Arr::get($config, 'default')) {
return false;
}

if ($choice === $skipModule) {
if ($choice === $skipModuleValue) {
return false;
}

Expand Down
186 changes: 177 additions & 9 deletions tests/StarterKits/InstallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -772,15 +772,15 @@ public function it_installs_no_modules_by_default_when_running_non_interactively
}

#[Test]
public function it_installs_modules_with_prompt_false_config_by_default_when_running_non_interactively()
public function it_can_still_install_modules_with_prompt_false_or_default_config()
{
$this->setConfig([
'export_paths' => [
'copied.md',
],
'modules' => [
'seo' => [
'prompt' => false, // Setting prompt to false skips confirmation, so this module should still get installed non-interactively
'prompt' => false, // Setting `prompt: false` skips confirmation, so this module should still get installed
'export_paths' => [
'resources/css/seo.css',
],
Expand All @@ -797,11 +797,38 @@ public function it_installs_modules_with_prompt_false_config_by_default_when_run
],
],
'jamaica' => [
'prompt' => false, // Setting prompt to false skips confirmation, so this module should still get installed non-interactively
'prompt' => false, // Setting `prompt: false` skips confirmation, so this module should still get installed
'export_as' => [
'resources/css/theme.css' => 'resources/css/jamaica.css',
],
],
'js' => [
'default' => 'vue', // Setting a `default` option, so this module should still get installed
'options' => [
'react' => [
'label' => 'React JS',
'export_paths' => [
'resources/js/react.js',
],
],
'vue' => [
'label' => 'Vue JS',
'export_paths' => [
'resources/js/vue.js',
],
],
],
],
'js_invalid' => [
'prompt' => false, // Setting `prompt: false` doesn't do anything for select modules, should use `default` like above
'options' => [
'svelte' => [
'export_paths' => [
'resources/js/svelte.js',
],
],
],
],
],
]);

Expand All @@ -811,6 +838,9 @@ public function it_installs_modules_with_prompt_false_config_by_default_when_run
$this->assertFileDoesNotExist(base_path('resources/css/theme.css'));
$this->assertComposerJsonDoesntHave('statamic/seo-pro');
$this->assertComposerJsonDoesntHave('bobsled/speed-calculator');
$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));
$this->assertFileDoesNotExist(base_path('resources/js/svelte.js'));

$this->installCoolRunnings();

Expand All @@ -820,6 +850,9 @@ public function it_installs_modules_with_prompt_false_config_by_default_when_run
$this->assertFileExists(base_path('resources/css/theme.css'));
$this->assertComposerJsonHasPackageVersion('require', 'statamic/seo-pro', '^0.2.0');
$this->assertComposerJsonDoesntHave('bobsled/speed-calculator');
$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileExists(base_path('resources/js/vue.js'));
$this->assertFileDoesNotExist(base_path('resources/js/svelte.js'));
}

#[Test]
Expand Down Expand Up @@ -926,7 +959,120 @@ public function it_installs_only_the_modules_confirmed_interactively_via_prompt(
}

#[Test]
public function it_display_custom_module_prompts()
public function it_allows_user_to_skip_in_select_module_prompts()
{
$this->setConfig([
'modules' => [
'js' => [
'prompt' => 'Want one of these fancy JS options?',
'options' => [
'react' => [
'label' => 'React JS',
'export_paths' => [
'resources/js/react.js',
],
],
'vue' => [
'label' => 'Vue JS',
'export_paths' => [
'resources/js/vue.js',
],
],
'svelte' => [
'export_paths' => [
'resources/js/svelte.js',
],
],
],
],
],
]);

$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));
$this->assertFileDoesNotExist(base_path('resources/js/svelte.js'));

$command = $this->installCoolRunningsModules();

// Some fixes to `expectsChoice()` were merged for us, but are not available on 11.20.0 and below
// See: https://github.com/laravel/framework/pull/52408
if (version_compare(app()->version(), '11.20.0', '>')) {
$command->expectsChoice('Want one of these fancy JS options?', 'skip_module', [
'skip_module' => 'No',
'react' => 'React JS',
'vue' => 'Vue JS',
'svelte' => 'Svelte',
]);
} else {
$command->expectsQuestion('Want one of these fancy JS options?', 'skip_module');
}

$command->run();

$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));
$this->assertFileDoesNotExist(base_path('resources/js/svelte.js'));
}

#[Test]
public function it_can_disable_skip_option_in_select_module_prompts()
{
$this->setConfig([
'modules' => [
'js' => [
'prompt' => 'Want one of these fancy JS options?',
'skip_option' => false,
'options' => [
'react' => [
'label' => 'React JS',
'export_paths' => [
'resources/js/react.js',
],
],
'vue' => [
'label' => 'Vue JS',
'export_paths' => [
'resources/js/vue.js',
],
],
'svelte' => [
'export_paths' => [
'resources/js/svelte.js',
],
],
],
],
],
]);

$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));
$this->assertFileDoesNotExist(base_path('resources/js/svelte.js'));

$command = $this->installCoolRunningsModules();

// Some fixes to `expectsChoice()` were merged for us, but are not available on 11.20.0 and below
// See: https://github.com/laravel/framework/pull/52408
if (version_compare(app()->version(), '11.20.0', '>')) {
$command->expectsChoice('Want one of these fancy JS options?', 'svelte', [
// 'skip_module' => 'No', // This should not be here anymore, because of `skip_option: false`
'react' => 'React JS',
'vue' => 'Vue JS',
'svelte' => 'Svelte',
]);
} else {
$command->expectsQuestion('Want one of these fancy JS options?', 'svelte');
}

$command->run();

$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));
$this->assertFileExists(base_path('resources/js/svelte.js'));
}

#[Test]
public function it_display_custom_module_prompts_and_option_labels()
{
$this->setConfig([
'modules' => [
Expand All @@ -938,6 +1084,7 @@ public function it_display_custom_module_prompts()
],
'js' => [
'prompt' => 'Want one of these fancy JS options?',
'skip_option' => 'No, thank you!',
'options' => [
'react' => [
'label' => 'React JS',
Expand Down Expand Up @@ -974,7 +1121,7 @@ public function it_display_custom_module_prompts()
// See: https://github.com/laravel/framework/pull/52408
if (version_compare(app()->version(), '11.20.0', '>')) {
$command->expectsChoice('Want one of these fancy JS options?', 'svelte', [
'skip_module' => 'No',
'skip_module' => 'No, thank you!',
'react' => 'React JS',
'vue' => 'Vue JS',
'svelte' => 'Svelte',
Expand Down Expand Up @@ -1146,21 +1293,21 @@ public static function validModuleConfigs()
}

#[Test]
public function it_installs_nested_modules_with_prompt_false_config_by_default_when_running_non_interactively()
public function it_can_still_install_nested_modules_with_prompt_false_or_default_config()
{
$this->setConfig([
'export_paths' => [
'copied.md',
],
'modules' => [
'canada' => [
'prompt' => false, // Setting prompt to false skips confirmation, so this module should still get installed non-interactively
'prompt' => false, // Setting `prompt: false` skips confirmation, so this module should still get installed
'export_paths' => [
'resources/css/hockey.css',
],
'modules' => [
'hockey_players' => [
'prompt' => false, // Setting prompt to false skips confirmation, so this module should still get installed non-interactively
'prompt' => false, // Setting `prompt: false` skips confirmation, so this module should still get installed
'export_paths' => [
'resources/dictionaries/players.yaml',
],
Expand All @@ -1174,11 +1321,28 @@ public function it_installs_nested_modules_with_prompt_false_config_by_default_w
],
],
'hockey_night_in_canada' => [
'prompt' => false, // Setting prompt to false skips confirmation, so this module should still get installed non-interactively
'prompt' => false, // Setting `prompt: false` skips confirmation, so this module should still get installed
'export_paths' => [
'resources/dictionaries/canadian_players.yaml',
],
],
'js' => [
'default' => 'vue', // Setting a `default` option, so this module should still get installed
'options' => [
'react' => [
'label' => 'React JS',
'export_paths' => [
'resources/js/react.js',
],
],
'vue' => [
'label' => 'Vue JS',
'export_paths' => [
'resources/js/vue.js',
],
],
],
],
],
],
],
Expand All @@ -1192,6 +1356,8 @@ public function it_installs_nested_modules_with_prompt_false_config_by_default_w
$this->assertFileDoesNotExist(base_path('resources/dictionaries/players.yaml'));
$this->assertFileDoesNotExist(base_path('resources/dictionaries/american_players.yaml'));
$this->assertFileDoesNotExist(base_path('resources/dictionaries/canadian_players.yaml'));
$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileDoesNotExist(base_path('resources/js/vue.js'));

$this->installCoolRunnings();

Expand All @@ -1201,6 +1367,8 @@ public function it_installs_nested_modules_with_prompt_false_config_by_default_w
$this->assertFileExists(base_path('resources/dictionaries/players.yaml'));
$this->assertFileDoesNotExist(base_path('resources/dictionaries/american_players.yaml'));
$this->assertFileExists(base_path('resources/dictionaries/canadian_players.yaml'));
$this->assertFileDoesNotExist(base_path('resources/js/react.js'));
$this->assertFileExists(base_path('resources/js/vue.js'));
}

#[Test]
Expand Down
Loading