diff --git a/module/Installer/src/Command/InstallCommand.php b/module/Installer/src/Command/InstallCommand.php index a08b6eeb..0f677bd5 100644 --- a/module/Installer/src/Command/InstallCommand.php +++ b/module/Installer/src/Command/InstallCommand.php @@ -189,7 +189,10 @@ class InstallCommand extends Command $config = new CustomizableAppConfig(); // Ask the user if he/she wants to import an older configuration - $importConfig = $this->io->confirm('Do you want to import configuration from previous installation?'); + $importConfig = $this->io->confirm( + 'Do you want to import configuration from previous installation? (You will still be asked for any new ' + . 'config option that did not exist in previous shlink versions)' + ); if (! $importConfig) { return $config; } diff --git a/module/Installer/src/Config/Plugin/ApplicationConfigCustomizer.php b/module/Installer/src/Config/Plugin/ApplicationConfigCustomizer.php index fbd9c6a4..563ec901 100644 --- a/module/Installer/src/Config/Plugin/ApplicationConfigCustomizer.php +++ b/module/Installer/src/Config/Plugin/ApplicationConfigCustomizer.php @@ -22,17 +22,14 @@ class ApplicationConfigCustomizer implements ConfigCustomizerInterface public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void { - $io->title('APPLICATION'); - $app = $appConfig->getApp(); - $keysToAskFor = $appConfig->hasApp() && $io->confirm('Do you want to keep imported application config?') - ? array_diff(self::EXPECTED_KEYS, array_keys($app)) - : self::EXPECTED_KEYS; + $keysToAskFor = $appConfig->hasApp() ? array_diff(self::EXPECTED_KEYS, array_keys($app)) : self::EXPECTED_KEYS; if (empty($keysToAskFor)) { return; } + $io->title('APPLICATION'); foreach ($keysToAskFor as $key) { $app[$key] = $this->ask($io, $key); } diff --git a/module/Installer/src/Config/Plugin/DatabaseConfigCustomizer.php b/module/Installer/src/Config/Plugin/DatabaseConfigCustomizer.php index 410ea912..c003d40f 100644 --- a/module/Installer/src/Config/Plugin/DatabaseConfigCustomizer.php +++ b/module/Installer/src/Config/Plugin/DatabaseConfigCustomizer.php @@ -53,10 +53,9 @@ class DatabaseConfigCustomizer implements ConfigCustomizerInterface */ public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void { - $io->title('DATABASE'); - + $titlePrinted = false; $db = $appConfig->getDatabase(); - $doImport = $appConfig->hasDatabase() && $io->confirm('Do you want to keep imported database config?'); + $doImport = $appConfig->hasDatabase(); $keysToAskFor = $doImport ? array_diff(self::EXPECTED_KEYS, array_keys($db)) : self::EXPECTED_KEYS; // If the user selected to keep DB, try to import SQLite database @@ -70,6 +69,8 @@ class DatabaseConfigCustomizer implements ConfigCustomizerInterface // If the driver is one of the params to ask for, ask for it first if (contains(self::DRIVER, $keysToAskFor)) { + $io->title('DATABASE'); + $titlePrinted = true; $db[self::DRIVER] = $this->ask($io, self::DRIVER); $keysToAskFor = array_diff($keysToAskFor, [self::DRIVER]); } @@ -79,7 +80,9 @@ class DatabaseConfigCustomizer implements ConfigCustomizerInterface $keysToAskFor = array_diff($keysToAskFor, self::DRIVER_DEPENDANT_OPTIONS); } - // Iterate any remaining option and ask for it + if (! $titlePrinted && ! empty($keysToAskFor)) { + $io->title('DATABASE'); + } foreach ($keysToAskFor as $key) { $db[$key] = $this->ask($io, $key, $db); } diff --git a/module/Installer/src/Config/Plugin/LanguageConfigCustomizer.php b/module/Installer/src/Config/Plugin/LanguageConfigCustomizer.php index 2f291a2e..f55858fb 100644 --- a/module/Installer/src/Config/Plugin/LanguageConfigCustomizer.php +++ b/module/Installer/src/Config/Plugin/LanguageConfigCustomizer.php @@ -21,10 +21,8 @@ class LanguageConfigCustomizer implements ConfigCustomizerInterface public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void { - $io->title('LANGUAGE'); - $lang = $appConfig->getLanguage(); - $keysToAskFor = $appConfig->hasLanguage() && $io->confirm('Do you want to keep imported language?') + $keysToAskFor = $appConfig->hasLanguage() ? array_diff(self::EXPECTED_KEYS, array_keys($lang)) : self::EXPECTED_KEYS; @@ -32,6 +30,7 @@ class LanguageConfigCustomizer implements ConfigCustomizerInterface return; } + $io->title('LANGUAGE'); foreach ($keysToAskFor as $key) { $lang[$key] = $this->ask($io, $key); } diff --git a/module/Installer/src/Config/Plugin/UrlShortenerConfigCustomizer.php b/module/Installer/src/Config/Plugin/UrlShortenerConfigCustomizer.php index 119eae83..2877c826 100644 --- a/module/Installer/src/Config/Plugin/UrlShortenerConfigCustomizer.php +++ b/module/Installer/src/Config/Plugin/UrlShortenerConfigCustomizer.php @@ -28,16 +28,15 @@ class UrlShortenerConfigCustomizer implements ConfigCustomizerInterface public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void { - $io->title('URL SHORTENER'); - $urlShortener = $appConfig->getUrlShortener(); - $doImport = $appConfig->hasUrlShortener() && $io->confirm('Do you want to keep imported URL shortener config?'); + $doImport = $appConfig->hasUrlShortener(); $keysToAskFor = $doImport ? array_diff(self::EXPECTED_KEYS, array_keys($urlShortener)) : self::EXPECTED_KEYS; if (empty($keysToAskFor)) { return; } + $io->title('URL SHORTENER'); foreach ($keysToAskFor as $key) { $urlShortener[$key] = $this->ask($io, $key); } diff --git a/module/Installer/test/Config/Plugin/ApplicationConfigCustomizerTest.php b/module/Installer/test/Config/Plugin/ApplicationConfigCustomizerTest.php index 68f13532..3fbcf449 100644 --- a/module/Installer/test/Config/Plugin/ApplicationConfigCustomizerTest.php +++ b/module/Installer/test/Config/Plugin/ApplicationConfigCustomizerTest.php @@ -50,10 +50,9 @@ class ApplicationConfigCustomizerTest extends TestCase /** * @test */ - public function overwriteIsRequestedIfValueIsAlreadySet() + public function onlyMissingOptionsAreAsked() { - $ask = $this->io->ask(Argument::cetera())->willReturn('the_new_secret'); - $confirm = $this->io->confirm(Argument::cetera())->willReturn(false); + $ask = $this->io->ask(Argument::cetera())->willReturn('disable_param'); $config = new CustomizableAppConfig(); $config->setApp([ 'SECRET' => 'foo', @@ -62,19 +61,18 @@ class ApplicationConfigCustomizerTest extends TestCase $this->plugin->process($this->io->reveal(), $config); $this->assertEquals([ - 'SECRET' => 'the_new_secret', - 'DISABLE_TRACK_PARAM' => 'the_new_secret', + 'SECRET' => 'foo', + 'DISABLE_TRACK_PARAM' => 'disable_param', ], $config->getApp()); - $ask->shouldHaveBeenCalledTimes(2); - $confirm->shouldHaveBeenCalledTimes(1); + $ask->shouldHaveBeenCalledTimes(1); } /** * @test */ - public function existingValueIsKeptIfRequested() + public function noQuestionsAskedIfImportedConfigContainsEverything() { - $confirm = $this->io->confirm(Argument::cetera())->willReturn(true); + $ask = $this->io->ask(Argument::cetera())->willReturn('the_new_secret'); $config = new CustomizableAppConfig(); $config->setApp([ @@ -88,6 +86,6 @@ class ApplicationConfigCustomizerTest extends TestCase 'SECRET' => 'foo', 'DISABLE_TRACK_PARAM' => 'the_new_secret', ], $config->getApp()); - $confirm->shouldHaveBeenCalledTimes(1); + $ask->shouldNotHaveBeenCalled(); } } diff --git a/module/Installer/test/Config/Plugin/DatabaseConfigCustomizerTest.php b/module/Installer/test/Config/Plugin/DatabaseConfigCustomizerTest.php index 5d03409b..9d4ab1d9 100644 --- a/module/Installer/test/Config/Plugin/DatabaseConfigCustomizerTest.php +++ b/module/Installer/test/Config/Plugin/DatabaseConfigCustomizerTest.php @@ -62,64 +62,62 @@ class DatabaseConfigCustomizerTest extends TestCase /** * @test */ - public function overwriteIsRequestedIfValueIsAlreadySet() + public function onlyMissingOptionsAreAsked() { $choice = $this->io->choice(Argument::cetera())->willReturn('MySQL'); - $confirm = $this->io->confirm(Argument::cetera())->willReturn(false); - $ask = $this->io->ask(Argument::cetera())->willReturn('MySQL'); + $ask = $this->io->ask(Argument::cetera())->willReturn('asked'); + $config = new CustomizableAppConfig(); $config->setDatabase([ 'DRIVER' => 'pdo_pgsql', - 'NAME' => 'MySQL', - 'USER' => 'MySQL', - 'PASSWORD' => 'MySQL', - 'HOST' => 'MySQL', - 'PORT' => 'MySQL', + 'NAME' => 'foo', + 'PASSWORD' => 'foo', ]); $this->plugin->process($this->io->reveal(), $config); $this->assertEquals([ - 'DRIVER' => 'pdo_mysql', - 'NAME' => 'MySQL', - 'USER' => 'MySQL', - 'PASSWORD' => 'MySQL', - 'HOST' => 'MySQL', - 'PORT' => 'MySQL', + 'DRIVER' => 'pdo_pgsql', + 'NAME' => 'foo', + 'USER' => 'asked', + 'PASSWORD' => 'foo', + 'HOST' => 'asked', + 'PORT' => 'asked', ], $config->getDatabase()); - $confirm->shouldHaveBeenCalledTimes(1); - $choice->shouldHaveBeenCalledTimes(1); - $ask->shouldHaveBeenCalledTimes(5); + $choice->shouldNotHaveBeenCalled(); + $ask->shouldHaveBeenCalledTimes(3); } /** * @test */ - public function existingValueIsKeptIfRequested() + public function noQuestionsAskedIfImportedConfigContainsEverything() { - $confirm = $this->io->confirm(Argument::cetera())->willReturn(true); + $choice = $this->io->choice(Argument::cetera())->willReturn('MySQL'); + $ask = $this->io->ask(Argument::cetera())->willReturn('asked'); $config = new CustomizableAppConfig(); $config->setDatabase([ 'DRIVER' => 'pdo_pgsql', - 'NAME' => 'MySQL', - 'USER' => 'MySQL', - 'PASSWORD' => 'MySQL', - 'HOST' => 'MySQL', - 'PORT' => 'MySQL', + 'NAME' => 'foo', + 'USER' => 'foo', + 'PASSWORD' => 'foo', + 'HOST' => 'foo', + 'PORT' => 'foo', ]); $this->plugin->process($this->io->reveal(), $config); $this->assertEquals([ 'DRIVER' => 'pdo_pgsql', - 'NAME' => 'MySQL', - 'USER' => 'MySQL', - 'PASSWORD' => 'MySQL', - 'HOST' => 'MySQL', - 'PORT' => 'MySQL', + 'NAME' => 'foo', + 'USER' => 'foo', + 'PASSWORD' => 'foo', + 'HOST' => 'foo', + 'PORT' => 'foo', ], $config->getDatabase()); - $confirm->shouldHaveBeenCalledTimes(1); + $choice->shouldNotHaveBeenCalled(); + $ask->shouldNotHaveBeenCalled(); } /** @@ -127,7 +125,6 @@ class DatabaseConfigCustomizerTest extends TestCase */ public function sqliteDatabaseIsImportedWhenRequested() { - $confirm = $this->io->confirm(Argument::cetera())->willReturn(true); $copy = $this->filesystem->copy(Argument::cetera())->willReturn(null); $config = new CustomizableAppConfig(); @@ -140,7 +137,6 @@ class DatabaseConfigCustomizerTest extends TestCase $this->assertEquals([ 'DRIVER' => 'pdo_sqlite', ], $config->getDatabase()); - $confirm->shouldHaveBeenCalledTimes(1); $copy->shouldHaveBeenCalledTimes(1); } } diff --git a/module/Installer/test/Config/Plugin/LanguageConfigCustomizerTest.php b/module/Installer/test/Config/Plugin/LanguageConfigCustomizerTest.php index 42b7e10b..8c6b633c 100644 --- a/module/Installer/test/Config/Plugin/LanguageConfigCustomizerTest.php +++ b/module/Installer/test/Config/Plugin/LanguageConfigCustomizerTest.php @@ -33,7 +33,7 @@ class LanguageConfigCustomizerTest extends TestCase */ public function configIsRequestedToTheUser() { - $ask = $this->io->choice(Argument::cetera())->willReturn('en'); + $choice = $this->io->choice(Argument::cetera())->willReturn('en'); $config = new CustomizableAppConfig(); $this->plugin->process($this->io->reveal(), $config); @@ -43,38 +43,35 @@ class LanguageConfigCustomizerTest extends TestCase 'DEFAULT' => 'en', 'CLI' => 'en', ], $config->getLanguage()); - $ask->shouldHaveBeenCalledTimes(2); + $choice->shouldHaveBeenCalledTimes(2); } /** * @test */ - public function overwriteIsRequestedIfValueIsAlreadySet() + public function onlyMissingOptionsAreAsked() { $choice = $this->io->choice(Argument::cetera())->willReturn('es'); - $confirm = $this->io->confirm(Argument::cetera())->willReturn(false); $config = new CustomizableAppConfig(); $config->setLanguage([ 'DEFAULT' => 'en', - 'CLI' => 'en', ]); $this->plugin->process($this->io->reveal(), $config); $this->assertEquals([ - 'DEFAULT' => 'es', + 'DEFAULT' => 'en', 'CLI' => 'es', ], $config->getLanguage()); - $choice->shouldHaveBeenCalledTimes(2); - $confirm->shouldHaveBeenCalledTimes(1); + $choice->shouldHaveBeenCalledTimes(1); } /** * @test */ - public function existingValueIsKeptIfRequested() + public function noQuestionsAskedIfImportedConfigContainsEverything() { - $ask = $this->io->confirm(Argument::cetera())->willReturn(true); + $choice = $this->io->choice(Argument::cetera())->willReturn('en'); $config = new CustomizableAppConfig(); $config->setLanguage([ @@ -88,6 +85,6 @@ class LanguageConfigCustomizerTest extends TestCase 'DEFAULT' => 'es', 'CLI' => 'es', ], $config->getLanguage()); - $ask->shouldHaveBeenCalledTimes(1); + $choice->shouldNotHaveBeenCalled(); } } diff --git a/module/Installer/test/Config/Plugin/UrlShortenerConfigCustomizerTest.php b/module/Installer/test/Config/Plugin/UrlShortenerConfigCustomizerTest.php index 779107f4..f5facbbd 100644 --- a/module/Installer/test/Config/Plugin/UrlShortenerConfigCustomizerTest.php +++ b/module/Installer/test/Config/Plugin/UrlShortenerConfigCustomizerTest.php @@ -33,8 +33,8 @@ class UrlShortenerConfigCustomizerTest extends TestCase */ public function configIsRequestedToTheUser() { - $choice = $this->io->choice(Argument::cetera())->willReturn('something'); - $ask = $this->io->ask(Argument::cetera())->willReturn('something'); + $choice = $this->io->choice(Argument::cetera())->willReturn('chosen'); + $ask = $this->io->ask(Argument::cetera())->willReturn('asked'); $confirm = $this->io->confirm(Argument::cetera())->willReturn(true); $config = new CustomizableAppConfig(); @@ -42,9 +42,9 @@ class UrlShortenerConfigCustomizerTest extends TestCase $this->assertTrue($config->hasUrlShortener()); $this->assertEquals([ - 'SCHEMA' => 'something', - 'HOSTNAME' => 'something', - 'CHARS' => 'something', + 'SCHEMA' => 'chosen', + 'HOSTNAME' => 'asked', + 'CHARS' => 'asked', 'VALIDATE_URL' => true, ], $config->getUrlShortener()); $ask->shouldHaveBeenCalledTimes(2); @@ -55,16 +55,44 @@ class UrlShortenerConfigCustomizerTest extends TestCase /** * @test */ - public function overwriteIsRequestedIfValueIsAlreadySet() + public function onlyMissingOptionsAreAsked() { - $choice = $this->io->choice(Argument::cetera())->willReturn('foo'); - $ask = $this->io->ask(Argument::cetera())->willReturn('foo'); + $choice = $this->io->choice(Argument::cetera())->willReturn('chosen'); + $ask = $this->io->ask(Argument::cetera())->willReturn('asked'); $confirm = $this->io->confirm(Argument::cetera())->willReturn(false); $config = new CustomizableAppConfig(); $config->setUrlShortener([ - 'SCHEMA' => 'bar', - 'HOSTNAME' => 'bar', - 'CHARS' => 'bar', + 'SCHEMA' => 'foo', + 'HOSTNAME' => 'foo', + ]); + + $this->plugin->process($this->io->reveal(), $config); + + $this->assertEquals([ + 'SCHEMA' => 'foo', + 'HOSTNAME' => 'foo', + 'CHARS' => 'asked', + 'VALIDATE_URL' => false, + ], $config->getUrlShortener()); + $choice->shouldNotHaveBeenCalled(); + $ask->shouldHaveBeenCalledTimes(1); + $confirm->shouldHaveBeenCalledTimes(1); + } + + /** + * @test + */ + public function noQuestionsAskedIfImportedConfigContainsEverything() + { + $choice = $this->io->choice(Argument::cetera())->willReturn('chosen'); + $ask = $this->io->ask(Argument::cetera())->willReturn('asked'); + $confirm = $this->io->confirm(Argument::cetera())->willReturn(false); + + $config = new CustomizableAppConfig(); + $config->setUrlShortener([ + 'SCHEMA' => 'foo', + 'HOSTNAME' => 'foo', + 'CHARS' => 'foo', 'VALIDATE_URL' => true, ]); @@ -74,36 +102,10 @@ class UrlShortenerConfigCustomizerTest extends TestCase 'SCHEMA' => 'foo', 'HOSTNAME' => 'foo', 'CHARS' => 'foo', - 'VALIDATE_URL' => false, + 'VALIDATE_URL' => true, ], $config->getUrlShortener()); - $ask->shouldHaveBeenCalledTimes(2); - $choice->shouldHaveBeenCalledTimes(1); - $confirm->shouldHaveBeenCalledTimes(2); - } - - /** - * @test - */ - public function existingValueIsKeptIfRequested() - { - $confirm = $this->io->confirm(Argument::cetera())->willReturn(true); - - $config = new CustomizableAppConfig(); - $config->setUrlShortener([ - 'SCHEMA' => 'foo', - 'HOSTNAME' => 'foo', - 'CHARS' => 'foo', - 'VALIDATE_URL' => 'foo', - ]); - - $this->plugin->process($this->io->reveal(), $config); - - $this->assertEquals([ - 'SCHEMA' => 'foo', - 'HOSTNAME' => 'foo', - 'CHARS' => 'foo', - 'VALIDATE_URL' => 'foo', - ], $config->getUrlShortener()); - $confirm->shouldHaveBeenCalledTimes(1); + $choice->shouldNotHaveBeenCalled(); + $ask->shouldNotHaveBeenCalled(); + $confirm->shouldNotHaveBeenCalled(); } }