diff --git a/src/Console/Commands/ProEnable.php b/src/Console/Commands/ProEnable.php index 865cc726d1..ed111c006d 100644 --- a/src/Console/Commands/ProEnable.php +++ b/src/Console/Commands/ProEnable.php @@ -40,6 +40,7 @@ public function handle() } $this->checkInfo('Statamic Pro successfully enabled in .env file!'); + $this->promptToSetLicenseKey(); if ($this->option('update-config') && $this->updateConfig()) { $this->checkInfo('Statamic editions config successfully updated to reference .env var!'); @@ -53,7 +54,7 @@ public function handle() $this->crossLine('Statamic editions config not currently referencing .env var!'); $this->comment('Please re-run this command with the `--update-config` option.'); } else { - $this->laravel['config']['statamic.editions.pro'] = true; + config()->set('statamic.editions.pro', true); } } @@ -84,7 +85,7 @@ protected function setProInEnvironmentFile() */ protected function proEnvVarExists() { - return preg_match('/^STATAMIC_PRO_ENABLED=/m', $this->envContents()); + return preg_match('/^#?\s*STATAMIC_PRO_ENABLED=/m', $this->envContents()); } /** @@ -95,7 +96,7 @@ protected function proEnvVarExists() protected function ensureProInEnv() { file_put_contents($this->envPath(), preg_replace( - '/^STATAMIC_PRO_ENABLED=.*$/m', + '/^#?\s*STATAMIC_PRO_ENABLED=.*$/m', 'STATAMIC_PRO_ENABLED=true', $this->envContents() )); @@ -111,6 +112,98 @@ protected function appendProToEnv() file_put_contents($this->envPath(), $this->envContents()."\nSTATAMIC_PRO_ENABLED=true"); } + /** + * Prompt to set the license key in the environment file. + * + * @return void + */ + protected function promptToSetLicenseKey() + { + if (! $this->input->isInteractive()) { + return; + } + + if ($this->licenseKeyAlreadySet()) { + return; + } + + $licenseKey = trim((string) $this->ask('If you have a Statamic license key, paste it now (leave blank to add later)')); + + if ($licenseKey === '') { + $this->comment('Add `STATAMIC_LICENSE_KEY=...` to your `.env` before or when your site goes live.'); + + return; + } + + if ($this->licenseKeyEnvVarExists()) { + $this->replaceLicenseKeyInEnv($licenseKey); + } else { + $this->appendLicenseKeyToEnv($licenseKey); + } + + $this->checkInfo('Statamic license key saved in .env file.'); + } + + /** + * Check whether a non-empty license key already exists. + * + * @return bool + */ + protected function licenseKeyAlreadySet() + { + $licenseKey = $this->licenseKeyFromEnv(); + + return $licenseKey !== null && $licenseKey !== ''; + } + + /** + * Check whether the license key env var exists. + * + * @return bool + */ + protected function licenseKeyEnvVarExists() + { + return preg_match('/^#?\s*STATAMIC_LICENSE_KEY=/m', $this->envContents()); + } + + /** + * Replace key in .env file. + * + * @param string $licenseKey + * @return void + */ + protected function replaceLicenseKeyInEnv($licenseKey) + { + file_put_contents($this->envPath(), preg_replace_callback( + '/^#?\s*STATAMIC_LICENSE_KEY=.*$/m', + fn () => 'STATAMIC_LICENSE_KEY='.$licenseKey, + $this->envContents() + )); + } + + /** + * Append key to end of .env file. + * + * @param string $licenseKey + * @return void + */ + protected function appendLicenseKeyToEnv($licenseKey) + { + file_put_contents($this->envPath(), $this->envContents()."\nSTATAMIC_LICENSE_KEY={$licenseKey}"); + } + + /** + * Get the license key from .env. + * + * @return string|null + */ + protected function licenseKeyFromEnv() + { + preg_match('/^STATAMIC_LICENSE_KEY=(.*)$/m', $this->envContents(), $matches); + + return isset($matches[1]) ? trim($matches[1]) : null; + } + /** * Get app .env path. * @@ -118,7 +211,7 @@ protected function appendProToEnv() */ protected function envPath() { - return $this->laravel->environmentFilePath(); + return app()->environmentFilePath(); } /** diff --git a/tests/Console/Commands/ProEnableTest.php b/tests/Console/Commands/ProEnableTest.php index 80c4045aa0..1679acf921 100644 --- a/tests/Console/Commands/ProEnableTest.php +++ b/tests/Console/Commands/ProEnableTest.php @@ -61,7 +61,9 @@ public function it_can_enable_pro_by_updating_existing_var_in_env() $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); - $this->artisan('statamic:pro:enable'); + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', ''); $this->assertTrue(Statamic::pro()); $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); @@ -83,7 +85,9 @@ public function it_can_enable_pro_by_appending_to_env() $this->assertFalse(Statamic::pro()); $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); - $this->artisan('statamic:pro:enable'); + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', ''); $this->assertTrue(Statamic::pro()); $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); @@ -94,6 +98,26 @@ public function it_can_enable_pro_by_appending_to_env() ENV, $this->files->get($this->envPath)); } + #[Test] + public function it_replaces_commented_pro_enabled_var_in_env_instead_of_appending() + { + $this->files->put($this->envPath, <<<'ENV' +APP_NAME=Statamic +# STATAMIC_PRO_ENABLED=false +STATAMIC_LICENSE_KEY= +ENV); + + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', ''); + + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + } + #[Test] public function if_config_is_not_referencing_env_var_it_should_prompt_user_to_run_with_update_config_option() { @@ -116,6 +140,7 @@ public function if_config_is_not_referencing_env_var_it_should_prompt_user_to_ru $this ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', '') ->expectsOutput('Please re-run this command with the `--update-config` option.'); // Though it should still update .env @@ -159,7 +184,9 @@ public function it_can_update_editions_config_to_reference_env_var($boolean) $this->assertFalse(Statamic::pro()); $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); - $this->artisan('statamic:pro:enable', ['--update-config' => true]); + $this + ->artisan('statamic:pro:enable', ['--update-config' => true]) + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', ''); $this->assertTrue(Statamic::pro()); $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); @@ -192,6 +219,7 @@ public function if_it_has_trouble_updating_editions_config_it_should_instruct_us $this ->artisan('statamic:pro:enable', ['--update-config' => true]) + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', '') ->expectsOutput(PHP_EOL.'For this setting to take effect, please modify your [config/statamic/editions.php] as follows:') ->expectsOutput("'pro' => env('STATAMIC_PRO_ENABLED', false)"); @@ -205,4 +233,79 @@ public function if_it_has_trouble_updating_editions_config_it_should_instruct_us // Pro should not be enabled in the in-memory config, because config is not properly referencing .env var yet $this->assertFalse(Statamic::pro()); } + + #[Test] + public function it_can_set_license_key_while_enabling_pro() + { + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', 'test-license-key'); + + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY=test-license-key +ENV, $this->files->get($this->envPath)); + } + + #[Test] + public function it_replaces_commented_license_key_line_instead_of_appending() + { + $this->files->put($this->envPath, <<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=false +# STATAMIC_LICENSE_KEY= +ENV); + + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', 'test-license-key'); + + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY=test-license-key +ENV, $this->files->get($this->envPath)); + } + + #[Test] + public function commented_non_empty_license_key_still_prompts_and_gets_replaced() + { + $this->files->put($this->envPath, <<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=false +# STATAMIC_LICENSE_KEY=overlord_698g7f6sd89gs +ENV); + + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', 'test-license-key'); + + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY=test-license-key +ENV, $this->files->get($this->envPath)); + } + + #[Test] + public function it_mentions_setting_license_key_later_when_left_blank() + { + $this + ->artisan('statamic:pro:enable') + ->expectsQuestion('If you have a Statamic license key, paste it now (leave blank to add later)', '') + ->expectsOutput('Add `STATAMIC_LICENSE_KEY=...` to your `.env` before or when your site goes live.'); + } + + #[Test] + public function it_skips_license_key_prompt_in_non_interactive_mode() + { + $this->artisan('statamic:pro:enable', ['--no-interaction' => true]); + + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + } }