diff --git a/src/Console/Commands/ProEnable.php b/src/Console/Commands/ProEnable.php index 8d7f291a8ac..7d0650313f3 100644 --- a/src/Console/Commands/ProEnable.php +++ b/src/Console/Commands/ProEnable.php @@ -17,7 +17,8 @@ class ProEnable extends Command * @var string */ protected $signature = 'statamic:pro:enable - { --force : Force the operation to run when in production }'; + { --force : Force the operation to run when in production } + { --update-config : Also update editions config to reference .env var }'; /** * The console command description. @@ -37,14 +38,21 @@ public function handle() return; } - $this->laravel['config']['statamic.editions.pro'] = true; - $this->checkInfo('Statamic Pro successfully enabled in .env file!'); - if ($this->configNotReferencingEnv()) { - $this->crossLine('Statamic editions config not currently referencing .env file.'); + if ($this->option('update-config') && $this->updateConfig()) { + $this->checkInfo('Statamic editions config successfully updated to reference .env var!'); + } + + if ($this->option('update-config') && ! $this->isConfigReferencingEnv()) { + $this->crossLine('Could not reliably update editions config to reference .env var!'); $this->comment(PHP_EOL.'For this setting to take effect, please modify your [config/statamic/editions.php] as follows:'); $this->line("'pro' => env('STATAMIC_PRO_ENABLED', false)"); + } elseif (! $this->isConfigReferencingEnv()) { + $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; } } @@ -123,16 +131,46 @@ protected function envContents() } /** - * Check whether the editions config is referencing the .env var. + * Update editions config to reference the .env var. * * @return bool */ - protected function configNotReferencingEnv() + protected function updateConfig() { if (! file_exists($configPath = config_path('statamic/editions.php'))) { return false; } - return ! preg_match('/[\'"]pro[\'"]\s*=>\s*env\([\'"]STATAMIC_PRO_ENABLED[\'"]/m', file_get_contents($configPath)); + if ($this->isConfigReferencingEnv()) { + return false; + } + + $contents = file_get_contents($configPath); + + if (str_contains($contents, "'pro' => false,")) { + $contents = str_replace("'pro' => false,", "'pro' => env('STATAMIC_PRO_ENABLED', false),", $contents); + } elseif (str_contains($contents, "'pro' => true,")) { + $contents = str_replace("'pro' => true,", "'pro' => env('STATAMIC_PRO_ENABLED', false),", $contents); + } else { + return false; + } + + file_put_contents($configPath, $contents); + + return true; + } + + /** + * Check whether the editions config is referencing the .env var. + * + * @return bool + */ + protected function isConfigReferencingEnv() + { + if (! file_exists($configPath = config_path('statamic/editions.php'))) { + return true; + } + + return (bool) preg_match('/[\'"]pro[\'"]\s*=>\s*env\([\'"]STATAMIC_PRO_ENABLED[\'"]/m', file_get_contents($configPath)); } } diff --git a/src/Statamic.php b/src/Statamic.php index 44085ea41ff..a37c665e90b 100644 --- a/src/Statamic.php +++ b/src/Statamic.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Vite; use Laravel\Nova\Nova; @@ -48,17 +49,7 @@ public static function pro() public static function enablePro() { - $path = config_path('statamic/editions.php'); - - $contents = File::get($path); - - if (! Str::contains($contents, "'pro' => false,")) { - throw new \Exception('Could not reliably update the config file.'); - } - - $contents = str_replace("'pro' => false,", "'pro' => true,", $contents); - - File::put($path, $contents); + Artisan::call('statamic:pro:enable', ['--update-config' => true]); } public static function availableScripts(Request $request) diff --git a/tests/Console/Commands/ProEnableTest.php b/tests/Console/Commands/ProEnableTest.php new file mode 100644 index 00000000000..308536ceda4 --- /dev/null +++ b/tests/Console/Commands/ProEnableTest.php @@ -0,0 +1,209 @@ +files = app(Filesystem::class); + + $this->envPath = base_path('.env'); + $this->editionsPath = config_path('statamic/editions.php'); + + $this->defaultEnvContents = <<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=false +STATAMIC_LICENSE_KEY= +ENV; + + $this->defaultEditionsContents = $this->files->get(__DIR__.'/../../../config/editions.php'); + + $this->files->put($this->envPath, $this->defaultEnvContents); + + $this->files->makeDirectory(dirname($this->editionsPath), 0777, true, true); + $this->files->put($this->editionsPath, $this->defaultEditionsContents); + } + + protected function getEnvironmentSetUp($app) + { + parent::getEnvironmentSetUp($app); + + $app['config']->set('statamic.editions.pro', false); + } + + public function tearDown(): void + { + $this->files->delete($this->envPath); + $this->files->delete($this->editionsPath); + + parent::tearDown(); + } + + /** @test */ + public function it_can_enable_pro_by_updating_existing_var_in_env() + { + $this->assertFalse(Statamic::pro()); + $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); + $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); + + $this->artisan('statamic:pro:enable'); + + $this->assertTrue(Statamic::pro()); + $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + } + + /** @test */ + public function it_can_enable_pro_by_appending_to_env() + { + $this->files->put($this->envPath, $this->defaultEnvContents = <<<'ENV' +APP_NAME=Statamic +STATAMIC_LICENSE_KEY= +ENV); + + $this->assertFalse(Statamic::pro()); + $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); + + $this->artisan('statamic:pro:enable'); + + $this->assertTrue(Statamic::pro()); + $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_LICENSE_KEY= +STATAMIC_PRO_ENABLED=true +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() + { + $this->files->put($this->editionsPath, $this->defaultEditionsContents = <<<'EDITIONS' + env('WRONG!!!', false), + + 'addons' => [ + // + ], + +]; +EDITIONS); + + $this->assertFalse(Statamic::pro()); + $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); + + $this + ->artisan('statamic:pro:enable') + ->expectsOutput('Please re-run this command with the `--update-config` option.'); + + // Though it should still update .env + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + + // Pro should not be enabled in the in-memory config, because config is not properly referencing .env var yet + $this->assertFalse(Statamic::pro()); + } + + public static function hardcodedBooleans() + { + return [ + 'true' => ['true'], + 'false' => ['false'], + ]; + } + + /** + * @test + * + * @dataProvider hardcodedBooleans + */ + public function it_can_update_editions_config_to_reference_env_var($boolean) + { + $this->files->put($this->editionsPath, <<<"EDITIONS" + $boolean, + + 'addons' => [ + // + ], + +]; + +EDITIONS); + + $this->assertFalse(Statamic::pro()); + $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); + + $this->artisan('statamic:pro:enable', ['--update-config' => true]); + + $this->assertTrue(Statamic::pro()); + $this->assertEquals($this->defaultEditionsContents, $this->files->get($this->editionsPath)); + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + } + + /** @test */ + public function if_it_has_trouble_updating_editions_config_it_should_instruct_user() + { + $this->files->put($this->editionsPath, <<<'EDITIONS' + 'wabbajack', // It should fail trying to update this! + + 'addons' => [ + // + ], + +]; +EDITIONS); + + $this->assertFalse(Statamic::pro()); + $this->assertEquals($this->defaultEnvContents, $this->files->get($this->envPath)); + + $this + ->artisan('statamic:pro:enable', ['--update-config' => true]) + ->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)"); + + // Though it should still update .env + $this->assertEquals(<<<'ENV' +APP_NAME=Statamic +STATAMIC_PRO_ENABLED=true +STATAMIC_LICENSE_KEY= +ENV, $this->files->get($this->envPath)); + + // Pro should not be enabled in the in-memory config, because config is not properly referencing .env var yet + $this->assertFalse(Statamic::pro()); + } +}