commit 4c1e7ee07a0a5403f9cc73254ae345b5d651f771 Author: Greg Anderson Date: Wed Jun 19 13:47:14 2019 -0700 Fix handling of missing web-root location. Make sure scaffold runs after 'composer install' operations. diff --git a/core/lib/Drupal/Component/Scaffold/Handler.php b/core/lib/Drupal/Component/Scaffold/Handler.php index c0407e5f05..e59c53c9ad 100644 --- a/core/lib/Drupal/Component/Scaffold/Handler.php +++ b/core/lib/Drupal/Component/Scaffold/Handler.php @@ -143,6 +143,13 @@ public function scaffold() { $this->io->write("Nothing scaffolded because no packages are allowed in the top-level composer.json file."); return; } + + // Fail fast if the required 'web-root' location is not set in composer.json. + $webRoot = $this->manageOptions->getOptions()->getLocation('web-root'); + if (!$webRoot) { + throw new \RuntimeException("The extra.composer-scaffold.location.web-root is not set in the project's composer.json."); + } + // Call any pre-scaffold scripts that may be defined. $dispatcher = new EventDispatcher($this->composer, $this->io); $dispatcher->dispatch(self::PRE_COMPOSER_SCAFFOLD_CMD); @@ -161,10 +168,6 @@ public function scaffold() { // Generate an autoload file in the document root that includes the // autoload.php file in the vendor directory, wherever that is. Drupal // requires this in order to easily locate relocated vendor dirs. - $webRoot = $this->manageOptions->getOptions()->getLocation('web-root', FALSE); - if (!$webRoot) { - throw new \RuntimeException("The extra.composer-scaffold.location.webroot is not set in the project's composer.json."); - } $scaffoldResults[] = GenerateAutoloadReferenceFile::generateAutoload($this->rootPackageName(), $webRoot, $this->getVendorPath()); // Add the managed scaffold files to .gitignore if applicable. diff --git a/core/lib/Drupal/Component/Scaffold/Plugin.php b/core/lib/Drupal/Component/Scaffold/Plugin.php index cee41d8417..bf91dbae3a 100644 --- a/core/lib/Drupal/Component/Scaffold/Plugin.php +++ b/core/lib/Drupal/Component/Scaffold/Plugin.php @@ -50,6 +50,7 @@ public function getCapabilities() { public static function getSubscribedEvents() { return [ ScriptEvents::POST_UPDATE_CMD => 'postCmd', + ScriptEvents::POST_INSTALL_CMD => 'postCmd', PackageEvents::POST_PACKAGE_INSTALL => 'postPackage', PluginEvents::COMMAND => 'onCommand', ]; diff --git a/core/lib/Drupal/Component/Scaffold/ScaffoldOptions.php b/core/lib/Drupal/Component/Scaffold/ScaffoldOptions.php index ddc86659a0..1f3d8cb9f5 100644 --- a/core/lib/Drupal/Component/Scaffold/ScaffoldOptions.php +++ b/core/lib/Drupal/Component/Scaffold/ScaffoldOptions.php @@ -134,14 +134,12 @@ protected function hasLocation($name) { * * @param string $name * The name of the location to fetch. - * @param string $default - * The value to return if the requested location is not defined. * * @return string * The value of the provided named location */ - public function getLocation($name, $default = '') { - return $this->hasLocation($name) ? $this->locations()[$name] : $default; + public function getLocation($name) { + return $this->hasLocation($name) ? $this->locations()[$name] : FALSE; } /** diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ComposerHookTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ComposerHookTest.php index c48d8688c7..dde027d09b 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ComposerHookTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ComposerHookTest.php @@ -103,7 +103,12 @@ public function testComposerHooks() { $this->execComposer("update --no-ansi", $sut); $this->assertScaffoldedFile($sut . '/sites/default/default.settings.php', $is_link, '#scaffolded from the scaffold-override-fixture#'); // Delete the same test scaffold file again, then run - // 'composer composer:scaffold' and see if the scaffold file is replaced. + // 'composer composer:scaffold' and see if the scaffold file is re-scaffolded. + @unlink($sut . '/sites/default/default.settings.php'); + $this->execComposer("install --no-ansi", $sut); + $this->assertScaffoldedFile($sut . '/sites/default/default.settings.php', $is_link, '#scaffolded from the scaffold-override-fixture#'); + // Delete the same test scaffold file yet again, then run + // 'composer install' and see if the scaffold file is re-scaffolded. @unlink($sut . '/sites/default/default.settings.php'); $this->execComposer("composer:scaffold --no-ansi", $sut); $this->assertScaffoldedFile($sut . '/sites/default/default.settings.php', $is_link, '#scaffolded from the scaffold-override-fixture#'); diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ScaffoldTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ScaffoldTest.php index 8046662f16..a5b88a1eb0 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ScaffoldTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ScaffoldTest.php @@ -173,6 +173,20 @@ public function testScaffoldWithExpectedException($fixture_name, $expected_excep $this->scaffoldSut($fixture_name, $is_link); } + /** + * Try to scaffold a project that does not define web-root. + */ + public function testProjectWithoutWebRoot() { + $fixture_name = 'fixture-without-web-root'; + $is_link = FALSE; + $relocated_docroot = FALSE; + + $this->expectException(\Exception::class); + $this->expectExceptionMessage("The extra.composer-scaffold.location.web-root is not set in the project's composer.json."); + + list($docroot, $scaffoldOutput) = $this->scaffoldSut($fixture_name, $is_link, $relocated_docroot); + } + /** * Try to scaffold a project that does not scaffold anything. */ diff --git a/core/tests/Drupal/Tests/Component/Scaffold/fixtures/fixture-without-web-root/composer.json.tmpl b/core/tests/Drupal/Tests/Component/Scaffold/fixtures/fixture-without-web-root/composer.json.tmpl new file mode 100644 index 0000000000..35478fea3e --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Scaffold/fixtures/fixture-without-web-root/composer.json.tmpl @@ -0,0 +1,71 @@ +{ + "name": "fixtures/fixture-without-web-root", + "type": "project", + "minimum-stability": "dev", + "prefer-stable": true, + "repositories": { + "composer-scaffold": { + "type": "path", + "url": "__PROJECT_ROOT__", + "options": { + "symlink": true + } + }, + "drupal-core-fixture": { + "type": "path", + "url": "../drupal-core-fixture", + "options": { + "symlink": true + } + }, + "drupal-assets-fixture": { + "type": "path", + "url": "../drupal-assets-fixture", + "options": { + "symlink": true + } + }, + "scaffold-override-fixture": { + "type": "path", + "url": "../scaffold-override-fixture", + "options": { + "symlink": true + } + } + }, + "require": { + "drupal/core-composer-scaffold": "*", + "fixtures/drupal-core-fixture": "*", + "fixtures/scaffold-override-fixture": "*" + }, + "extra": { + "composer-scaffold": { + "allowed-packages": [ + "fixtures/drupal-core-fixture", + "fixtures/scaffold-override-fixture" + ], + "gitignore": false, + "overwrite": true, + "symlink": __SYMLINK__, + "file-mapping": { + "[web-root]/.htaccess": false, + "[web-root]/robots.txt": { + "mode": "replace", + "path": "assets/robots-default.txt", + "overwrite": true + } + } + }, + "installer-paths": { + "core": ["type:drupal-core"], + "modules/contrib/{$name}": ["type:drupal-module"], + "modules/custom/{$name}": ["type:drupal-custom-module"], + "profiles/contrib/{$name}": ["type:drupal-profile"], + "profiles/custom/{$name}": ["type:drupal-custom-profile"], + "themes/contrib/{$name}": ["type:drupal-theme"], + "themes/custom/{$name}": ["type:drupal-custom-theme"], + "libraries/{$name}": ["type:drupal-library"], + "drush/Commands/contrib/{$name}": ["type:drupal-drush"] + } + } +} diff --git a/core/tests/Drupal/Tests/Component/Scaffold/fixtures/scripts/disable-git-bin/git b/core/tests/Drupal/Tests/Component/Scaffold/fixtures/scripts/disable-git-bin/git old mode 100644 new mode 100755