diff --git a/config/runner.yml b/config/runner.yml index 9d380200..793aaf00 100644 --- a/config/runner.yml +++ b/config/runner.yml @@ -37,6 +37,12 @@ drupal: config_dir: ~ existing_config: false settings_override_file: "settings.override.php" + # Local development settings override. + # Add development settings that you want to share with your team and commit this file. + # If found this file will be copied in `/sites/{sites-subdir}/settings.local.php`, + # which should be, instead, git-ignored. This will give the possibility to locally + # tweak development settings. + settings_local_file: "${drupal.root}/sites/example.settings.local.php" # Setting this to "false" will run "site-install" without the "--db-url" parameter. # This is useful if the database settings are already set in your settings.php file. generate_db_url: true diff --git a/src/Commands/AbstractDrupalCommands.php b/src/Commands/AbstractDrupalCommands.php index 28e1592d..c1f2368e 100644 --- a/src/Commands/AbstractDrupalCommands.php +++ b/src/Commands/AbstractDrupalCommands.php @@ -27,9 +27,7 @@ abstract class AbstractDrupalCommands extends AbstractCommands implements Filesy */ public function getDrupal() { - return $this->getConfig()->get('drupal.core') === 7 ? - new Drupal7Commands() : - new Drupal8Commands(); + return $this->getConfig()->get('drupal.core') === 7 ? new Drupal7Commands() : new Drupal8Commands(); } /** @@ -341,12 +339,15 @@ public function drushSetup(array $options = [ * @option root Drupal root. * @option sites-subdir Drupal site subdirectory. * @option settings-override-file Drupal site settings override filename. - * @option force Drupal force generation of a new settings.php. - * @option skip-permissions-setup Drupal skip permissions setup. + * @option force Force generation of a new settings.php. + * @option skip-permissions-setup Skip permissions setup. + * @option dev Development settings setup. * * @param array $options * * @return \Robo\Collection\CollectionBuilder + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function settingsSetup(array $options = [ 'root' => InputOption::VALUE_REQUIRED, @@ -354,21 +355,21 @@ public function settingsSetup(array $options = [ 'settings-override-file' => InputOption::VALUE_REQUIRED, 'force' => false, 'skip-permissions-setup' => false, + 'dev' => false ]) { - $settings_default_path = $options['root'] . '/sites/' . $options['sites-subdir'] . '/default.settings.php'; + $settings_default_path = $options['root'] . '/sites/default/default.settings.php'; $settings_path = $options['root'] . '/sites/' . $options['sites-subdir'] . '/settings.php'; $settings_override_path = $options['root'] . '/sites/' . $options['sites-subdir'] . '/' . $options['settings-override-file']; // Save the filename of the override file in a single variable to use it // in the heredoc variable $custom_config hereunder. $settings_override_filename = $options['settings-override-file']; - $custom_config = $this->getDrupal()->getSettingsSetupAddendum($settings_override_filename); $collection = []; - if (true === (bool) $options['force'] || !file_exists($settings_path)) { + if ((bool) $options['force'] || !file_exists($settings_path)) { $collection[] = $this->taskWriteToFile($settings_default_path)->append()->lines([$custom_config]); $collection[] = $this->taskFilesystemStack()->copy($settings_default_path, $settings_path, true); } @@ -378,6 +379,19 @@ public function settingsSetup(array $options = [ $this->getConfig() )->setConfigKey('drupal.settings'); + // If ran in dev mode copy local settings file to 'settings.local.php'. + // Such file will be conditionally included in 'settings-override-file'. + if ($options['dev']) { + $local_settings_file = $this->getConfig()->get('drupal.site.settings_local_file'); + if (file_exists($local_settings_file)) { + $local_settings_path = $options['root'] . '/sites/' . $options['sites-subdir'] . '/settings.local.php'; + $collection[] = $this->taskFilesystemStack()->copy($local_settings_file, $local_settings_path, $options['force']); + } + $collection[] = $this->taskWriteToFile($settings_override_path) + ->append() + ->text($this->getDrupal()->getSettingsLocalSetupAddendum()); + } + if (!$options['skip-permissions-setup']) { $collection[] = $this->permissionsSetup($options); } @@ -437,4 +451,24 @@ protected function processPrePostInstallCommands(array &$commands, array $tokens } } } + + /** + * Get include portion for local development override configuration. + * + * This will be optionally appended to the settings override file. + * + * @return string + */ + protected function getSettingsLocalSetupAddendum() + { + return <<< EOF + +/** + * Load local development override configuration, if available. + */ +if (file_exists(__DIR__ . '/settings.local.php')) { + include __DIR__ . '/settings.local.php'; +} +EOF; + } } diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index 8408fee0..7837e70c 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -265,58 +265,39 @@ function $fct() {} } /** - * @param array $config + * @param array $configs * @param array $expected * - * @dataProvider settingsSetupForceDataProvider + * @dataProvider settingsSetupParametersDataProvider */ - public function testSettingsSetupForce(array $config, array $expected) + public function testSettingsSetupParameters(array $configs, array $expected) { - $configFile = $this->getSandboxFilepath('runner.yml'); - file_put_contents($configFile, Yaml::dump($config)); - - $sites_subdir = isset($config['drupal']['site']['sites_subdir']) ? $config['drupal']['site']['sites_subdir'] : 'default'; - mkdir($this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/', 0777, true); - file_put_contents($this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/default.settings.php', ''); - file_put_contents($this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/settings.php', '# Already existing file.'); - - $input = new StringInput('drupal:settings-setup --working-dir=' . $this->getSandboxRoot()); - - if (true === $config['drupal']['site']['force']) { - $input = new StringInput('drupal:settings-setup --working-dir=' . $this->getSandboxRoot() . ' --force'); + $sites_subdir = isset($configs['drupal']['site']['sites_subdir']) ? $configs['drupal']['site']['sites_subdir'] : 'default'; + mkdir($this->getSandboxRoot() . '/build/sites/default', 0755, true); + if ($sites_subdir !== 'default') { + mkdir($this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/', 0755, true); } - $runner = new TaskRunner($input, new BufferedOutput(), $this->getClassLoader()); - $runner->run(); + file_put_contents($this->getSandboxRoot() . '/build/sites/default/default.settings.php', ''); + file_put_contents($this->getSandboxRoot() . '/build/sites/example.settings.local.php', '// Local development override configuration.'); - foreach ($expected as $row) { - $content = file_get_contents($this->getSandboxFilepath($row['file'])); - $this->assertContainsNotContains($content, $row); + if (!empty($configs['files'])) { + foreach ($configs['files'] as $file) { + file_put_contents($this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/' . $file['name'], $file['content']); + } } - // Generate a random function name. - $fct = $this->generateRandomString(20); - - // Generate a dummy PHP code. - $config_override_dummy_script = <<< EOF -getSandboxRoot() . '/build/sites/' . $sites_subdir . '/' . $config_override_filename, - $config_override_dummy_script - ); - - // Include the config override file. - include_once $this->getSandboxRoot() . '/build/sites/' . $sites_subdir . '/' . $config_override_filename; + $input = 'drupal:settings-setup --working-dir=' . $this->getSandboxRoot() . ' --sites-subdir=' . $sites_subdir; + if (isset($configs['parameters']['force']) && $configs['parameters']['force']) { + $input .= ' --force'; + } + if (isset($configs['parameters']['dev']) && $configs['parameters']['dev']) { + $input .= ' --dev'; + } + $runner = new TaskRunner(new StringInput($input), new BufferedOutput(), $this->getClassLoader()); + $exit_code = $runner->run(); + $this->assertEquals(0, $exit_code, 'Command run returned an error.'); - // Test if the dummy PHP code has been properly included. - $this->assertTrue(\function_exists($fct)); + $this->processSettingsAssertions($expected); } /** @@ -404,9 +385,9 @@ public function drupal8SettingsSetupDataProvider() /** * @return array */ - public function settingsSetupForceDataProvider() + public function settingsSetupParametersDataProvider() { - return $this->getFixtureContent('commands/drupal-settings-setup-force.yml'); + return $this->getFixtureContent('commands/drupal-settings-setup-parameters.yml'); } /** @@ -427,13 +408,35 @@ public function changelogDataProvider() /** * @param string $content - * @param array $expected + * @param array $expectations */ - protected function assertContainsNotContains($content, array $expected) + protected function assertContainsNotContains($content, array $expectations) { - $this->assertContains($expected['contains'], $content); + if (!empty($expectations['contains'])) { + foreach ((array) $expectations['contains'] as $expected) { + $this->assertContains($expected, $content); + } + } if (!empty($expected['not_contains'])) { - $this->assertNotContains($expected['not_contains'], $content); + foreach ((array) $expectations['not_contains'] as $expected) { + $this->assertNotContains($expected, $content); + } + } + } + + /** + * @param array $expected + */ + protected function processSettingsAssertions(array $expected) + { + foreach ($expected as $row) { + if (isset($row['file'])) { + $content = file_get_contents($this->getSandboxFilepath($row['file'])); + $this->assertContainsNotContains($content, $row); + } + if (isset($row['no_file'])) { + $this->assertFileNotExists($row['no_file']); + } } } } diff --git a/tests/fixtures/commands/drupal-settings-setup-force.yml b/tests/fixtures/commands/drupal-settings-setup-force.yml deleted file mode 100644 index be04d9d7..00000000 --- a/tests/fixtures/commands/drupal-settings-setup-force.yml +++ /dev/null @@ -1,17 +0,0 @@ -- configuration: - drupal: - site: - force: false - expected: - - file: "build/sites/default/settings.php" - contains: "# Already existing file." - not_contains: "include $app_root . '/' . $site_path . '/settings.override.php';" - -- configuration: - drupal: - site: - force: true - expected: - - file: "build/sites/default/settings.php" - contains: "include $app_root . '/' . $site_path . '/settings.override.php';" - not_contains: "# Already existing file." diff --git a/tests/fixtures/commands/drupal-settings-setup-parameters.yml b/tests/fixtures/commands/drupal-settings-setup-parameters.yml new file mode 100644 index 00000000..f5acb6a4 --- /dev/null +++ b/tests/fixtures/commands/drupal-settings-setup-parameters.yml @@ -0,0 +1,96 @@ +- configuration: + files: + - name: 'settings.php' + content: '# Already existing file.' + parameters: + force: false + expected: + - file: "build/sites/default/settings.php" + contains: "# Already existing file." + not_contains: + - "include $app_root . '/' . $site_path . '/settings.override.php';" + - "include $app_root . '/' . $site_path . '/settings.local.php';" + - no_file: "build/sites/default/settings.local.php" + +- configuration: + files: + - name: 'settings.php' + content: '# Already existing file.' + parameters: + force: true + expected: + - file: "build/sites/default/settings.php" + contains: "include $app_root . '/' . $site_path . '/settings.override.php';" + not_contains: + - "# Already existing file." + - "include $app_root . '/' . $site_path . '/settings.local.php';" + - no_file: "build/sites/default/settings.local.php" + +- configuration: + files: + - name: 'settings.php' + content: '# Already existing file.' + - name: 'settings.local.php' + content: '# Already existing file.' + parameters: + force: false + dev: true + expected: + - file: "build/sites/default/settings.php" + contains: "# Already existing file." + not_contains: + - "include $app_root . '/' . $site_path . '/settings.override.php';" + - "include $app_root . '/' . $site_path . '/settings.local.php';" + - file: "build/sites/default/settings.local.php" + contains: "# Already existing file." + +- configuration: + files: + - name: 'settings.php' + content: '# Already existing file.' + - name: 'settings.local.php' + content: '# Already existing file.' + parameters: + force: false + dev: true + drupal: + site: + sites_subdir: 'foo' + expected: + - file: "build/sites/foo/settings.php" + contains: "# Already existing file." + not_contains: + - "include $app_root . '/' . $site_path . '/settings.override.php';" + - "include $app_root . '/' . $site_path . '/settings.local.php';" + - file: "build/sites/foo/settings.local.php" + contains: "# Already existing file." + +- configuration: + files: + - name: 'settings.php' + content: '# Already existing file.' + - name: 'settings.local.php' + content: '# Already existing file.' + parameters: + force: true + dev: true + expected: + - file: "build/sites/default/settings.override.php" + contains: + - "include __DIR__ . '/settings.local.php';" + not_contains: "# Already existing file." + - file: "build/sites/default/settings.local.php" + contains: "// Local development override configuration." + +- configuration: + files: + - name: 'settings.local.php' + content: '// Initial config.' + parameters: + force: false + expected: + - file: "build/sites/default/settings.php" + not_contains: "include $app_root . '/' . $site_path . '/settings.local.php';" + contains: "include $app_root . '/' . $site_path . '/settings.override.php';" + - file: "build/sites/default/settings.local.php" + contains: "// Initial config."