diff --git a/core/lib/Drupal/Component/Scaffold/GenerateAutoloadReferenceFile.php b/core/lib/Drupal/Component/Scaffold/GenerateAutoloadReferenceFile.php index 71ad1fe26b..332dc12093 100644 --- a/core/lib/Drupal/Component/Scaffold/GenerateAutoloadReferenceFile.php +++ b/core/lib/Drupal/Component/Scaffold/GenerateAutoloadReferenceFile.php @@ -33,7 +33,7 @@ public static function generateAutoload($package_name, $web_root, $vendorPath) { $fs = new SymfonyFilesystem(); $relativeVendorPath = $fs->makePathRelative($vendorPath, realpath($location)); $fs->dumpFile($autoloadPath->fullPath(), static::autoLoadContents($relativeVendorPath)); - return (new ScaffoldResult($autoloadPath))->setManaged(); + return new ScaffoldResult($autoloadPath, TRUE); } /** diff --git a/core/lib/Drupal/Component/Scaffold/Handler.php b/core/lib/Drupal/Component/Scaffold/Handler.php index a4b02f7b78..a6c14dca22 100644 --- a/core/lib/Drupal/Component/Scaffold/Handler.php +++ b/core/lib/Drupal/Component/Scaffold/Handler.php @@ -136,8 +136,8 @@ public function onPostPackageEvent(PackageEvent $event) { protected function createScaffoldOperations(PackageInterface $package, array $package_file_mappings) { $scaffoldOpFactory = new OperationFactory($this->composer); $scaffoldOps = []; - foreach ($package_file_mappings as $key => $metadata) { - $scaffoldOps[$key] = $scaffoldOpFactory->create($package, $key, $metadata); + foreach ($package_file_mappings as $dest_rel_path => $metadata) { + $scaffoldOps[$dest_rel_path] = $scaffoldOpFactory->create($package, $dest_rel_path, $metadata); } return $scaffoldOps; } diff --git a/core/lib/Drupal/Component/Scaffold/Operations/AppendOp.php b/core/lib/Drupal/Component/Scaffold/Operations/AppendOp.php index 3e7b50044c..2f656d03da 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/AppendOp.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/AppendOp.php @@ -10,8 +10,7 @@ /** * Scaffold operation to add to the beginning and/or end of a scaffold file. */ -class AppendOp implements OperationInterface, OriginalOpAwareInterface { - use OriginalOpAwareTrait; +class AppendOp implements OperationInterface, PreprocessOriginalOpInterface { /** * Path to the source file to prepend, if any. @@ -31,26 +30,13 @@ class AppendOp implements OperationInterface, OriginalOpAwareInterface { * Sets the relative path to the prepend file. * * @param \Drupal\Component\Scaffold\ScaffoldFilePath $prependPath - * The relative path to the prepend file file. - * - * @return $this - */ - public function setPrependFile(ScaffoldFilePath $prependPath) { - $this->prepend = $prependPath; - return $this; - } - - /** - * Sets the relative path to the append file. - * + * The relative path to the prepend file. * @param \Drupal\Component\Scaffold\ScaffoldFilePath $appendPath - * The relative path to the append file file. - * - * @return $this + * The relative path to the append file. */ - public function setAppendFile(ScaffoldFilePath $appendPath) { + public function __construct(ScaffoldFilePath $prependPath = NULL, ScaffoldFilePath $appendPath = NULL) { + $this->prepend = $prependPath; $this->append = $appendPath; - return $this; } /** @@ -69,23 +55,27 @@ protected function addInterpolationData(Interpolator $interpolator) { } /** - * Appends or prepends information to the overridden scaffold file. + * Called if the append op does not have an original operation at the same destination path. * * {@inheritdoc} */ public function process(ScaffoldFilePath $destination, IOInterface $io, ScaffoldOptions $options) { + throw new \RuntimeException($destination->getInterpolator()->interpolate("Cannot append/prepend because no prior package provided a scaffold file at that [dest-rel-path].")); + } + + /** + * Appends or prepends information to the overridden scaffold file. + * + * {@inheritdoc} + */ + public function preprocess(OperationInterface $originalOp, ScaffoldFilePath $destination, IOInterface $io, ScaffoldOptions $options) { $interpolator = $destination->getInterpolator(); $this->addInterpolationData($interpolator); $destination_path = $destination->fullPath(); - // It is not possible to append / prepend unless the destination path - // is the same as some scaffold file provided by an earlier package. - if (!$this->hasOriginalOp()) { - throw new \RuntimeException($interpolator->interpolate("Cannot append/prepend because no prior package provided a scaffold file at that [dest-rel-path].")); - } // First, scaffold the original file. Disable symlinking, because we // need a copy of the file if we're going to append / prepend to it. @unlink($destination_path); - $this->originalOp()->process($destination, $io, $options->overrideSymlink(FALSE)); + $originalOp->process($destination, $io, $options->overrideSymlink(FALSE)); // Fetch the prepend contents, if provided. $prependContents = ''; if (!empty($this->prepend)) { @@ -99,7 +89,7 @@ public function process(ScaffoldFilePath $destination, IOInterface $io, Scaffold $io->write($interpolator->interpolate(" - Append to [dest-rel-path] from [append-rel-path]")); } $this->append($destination, $prependContents, $appendContents, $io); - return (new ScaffoldResult($destination))->setManaged(); + return new ScaffoldResult($destination, TRUE); } /** diff --git a/core/lib/Drupal/Component/Scaffold/Operations/OperationCollection.php b/core/lib/Drupal/Component/Scaffold/Operations/OperationCollection.php index 76cdea3dca..d76757cedc 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/OperationCollection.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/OperationCollection.php @@ -107,11 +107,12 @@ public function collateScaffoldFiles(array $file_mappings, Interpolator $locatio foreach ($file_mappings as $package_name => $package_file_mappings) { foreach ($package_file_mappings as $destination_rel_path => $op) { $destination = ScaffoldFilePath::destinationPath($package_name, $destination_rel_path, $locationReplacements); - $scaffold_file = (new ScaffoldFileInfo())->setDestination($destination)->setOp($op); + $scaffold_file = new ScaffoldFileInfo($destination, $op); // If there was already a scaffolding operation happening at this // path, then pass it along to the new scaffold op, if it cares. - if (isset($list_of_scaffold_files[$destination_rel_path]) && $op instanceof OriginalOpAwareInterface) { - $op->setOriginalOp($list_of_scaffold_files[$destination_rel_path]->op()); + if (isset($list_of_scaffold_files[$destination_rel_path]) && $op instanceof PreprocessOriginalOpInterface) { + $preprocessOp = new PreprocessOp($list_of_scaffold_files[$destination_rel_path]->op(), $op); + $scaffold_file = new ScaffoldFileInfo($destination, $preprocessOp); } $list_of_scaffold_files[$destination_rel_path] = $scaffold_file; $resolved_file_mappings[$package_name][$destination_rel_path] = $scaffold_file; diff --git a/core/lib/Drupal/Component/Scaffold/Operations/OperationFactory.php b/core/lib/Drupal/Component/Scaffold/Operations/OperationFactory.php index dcbff7cf46..34846b9811 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/OperationFactory.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/OperationFactory.php @@ -77,7 +77,6 @@ public function create(PackageInterface $package, $dest_rel_path, $metadata) { * A scaffold replace operation object. */ protected function createReplaceOp(PackageInterface $package, $dest_rel_path, array $metadata) { - $op = new ReplaceOp(); // If this op does not provide an 'overwrite' value, default it to true. $metadata += ['overwrite' => TRUE]; if (!isset($metadata['path'])) { @@ -86,7 +85,7 @@ protected function createReplaceOp(PackageInterface $package, $dest_rel_path, ar $package_name = $package->getName(); $package_path = $this->getPackagePath($package); $source = ScaffoldFilePath::sourcePath($package_name, $package_path, $dest_rel_path, $metadata['path']); - $op->setSource($source)->setOverwrite($metadata['overwrite']); + $op = new ReplaceOp($source, $metadata['overwrite']); return $op; } @@ -104,17 +103,17 @@ protected function createReplaceOp(PackageInterface $package, $dest_rel_path, ar * A scaffold replace operation object. */ protected function createAppendOp(PackageInterface $package, $dest_rel_path, array $metadata) { - $op = new AppendOp(); $package_name = $package->getName(); $package_path = $this->getPackagePath($package); + $prepend_source_file = null; + $append_source_file = null; if (isset($metadata['prepend'])) { $prepend_source_file = ScaffoldFilePath::sourcePath($package_name, $package_path, $dest_rel_path, $metadata['prepend']); - $op->setPrependFile($prepend_source_file); } if (isset($metadata['append'])) { $append_source_file = ScaffoldFilePath::sourcePath($package_name, $package_path, $dest_rel_path, $metadata['append']); - $op->setAppendFile($append_source_file); } + $op = new AppendOp($prepend_source_file, $append_source_file); return $op; } diff --git a/core/lib/Drupal/Component/Scaffold/Operations/OriginalOpAwareInterface.php b/core/lib/Drupal/Component/Scaffold/Operations/OriginalOpAwareInterface.php deleted file mode 100644 index 6e5d0710ff..0000000000 --- a/core/lib/Drupal/Component/Scaffold/Operations/OriginalOpAwareInterface.php +++ /dev/null @@ -1,36 +0,0 @@ -originalOp = $originalOp; - return $this; - } - - /** - * {@inheritdoc} - */ - public function hasOriginalOp() { - return isset($this->originalOp); - } - - /** - * {@inheritdoc} - */ - public function originalOp() { - return $this->originalOp; - } - -} diff --git a/core/lib/Drupal/Component/Scaffold/Operations/ReplaceOp.php b/core/lib/Drupal/Component/Scaffold/Operations/ReplaceOp.php index 6f858f167e..a5961c6b2f 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/ReplaceOp.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/ReplaceOp.php @@ -31,12 +31,15 @@ class ReplaceOp implements OperationInterface { * * @param \Drupal\Component\Scaffold\ScaffoldFilePath $sourcePath * The relative path to the source file. + * @param bool $overwrite + * Whether to allow this scaffold file to overwrite files already at + * the destination. Defaults to TRUE. * * @return $this */ - public function setSource(ScaffoldFilePath $sourcePath) { + public function __construct(ScaffoldFilePath $sourcePath, $overwrite = TRUE) { $this->source = $sourcePath; - return $this; + $this->overwrite = $overwrite; } /** @@ -49,19 +52,6 @@ protected function getSource() { return $this->source; } - /** - * Sets whether the scaffold file should overwrite existing files. - * - * @param bool $overwrite - * Whether to overwrite existing files. - * - * @return $this - */ - public function setOverwrite($overwrite) { - $this->overwrite = $overwrite; - return $this; - } - /** * Determines whether scaffold file should overwrite files. * @@ -85,7 +75,7 @@ public function process(ScaffoldFilePath $destination, IOInterface $io, Scaffold if ($this->getOverwrite() === FALSE && file_exists($destination_path)) { $interpolator = $destination->getInterpolator(); $io->write($interpolator->interpolate(" - Skip [dest-rel-path] because it already exists and overwrite is false.")); - return (new ScaffoldResult($destination))->setManaged(FALSE); + return new ScaffoldResult($destination, FALSE); } // Get rid of the destination if it exists, and make sure that @@ -117,7 +107,7 @@ protected function copyScaffold(ScaffoldFilePath $destination, IOInterface $io) throw new \RuntimeException($interpolator->interpolate("Could not copy source file [src-rel-path] to [dest-rel-path]!")); } $io->write($interpolator->interpolate(" - Copy [dest-rel-path] from [src-rel-path]")); - return (new ScaffoldResult($destination))->setManaged($this->getOverwrite()); + return new ScaffoldResult($destination, $this->getOverwrite()); } /** @@ -141,7 +131,7 @@ protected function symlinkScaffold(ScaffoldFilePath $destination, IOInterface $i throw new \RuntimeException($interpolator->interpolate("Could not symlink source file [src-rel-path] to [dest-rel-path]!"), [], $e); } $io->write($interpolator->interpolate(" - Link [dest-rel-path] from [src-rel-path]")); - return (new ScaffoldResult($destination))->setManaged($this->getOverwrite()); + return new ScaffoldResult($destination, $this->getOverwrite()); } } diff --git a/core/lib/Drupal/Component/Scaffold/Operations/ScaffoldResult.php b/core/lib/Drupal/Component/Scaffold/Operations/ScaffoldResult.php index 37dcc5adde..b542b1e1a3 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/ScaffoldResult.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/ScaffoldResult.php @@ -28,10 +28,12 @@ class ScaffoldResult { * * @param \Drupal\Component\Scaffold\ScaffoldFilePath $destination * The path to the scaffold file that was processed. + * @param bool $isManaged + * (optional) Whether this result is managed. Defaults to FALSE. */ - public function __construct(ScaffoldFilePath $destination) { + public function __construct(ScaffoldFilePath $destination, $isManaged = FALSE) { $this->destination = $destination; - $this->managed = FALSE; + $this->managed = $isManaged; } /** @@ -44,19 +46,6 @@ public function isManaged() { return $this->managed; } - /** - * Records whether this result was managed or unmanaged. - * - * @param bool $isManaged - * (optional) Whether this result is managed. Defaults to TRUE. - * - * @return $this - */ - public function setManaged($isManaged = TRUE) { - $this->managed = $isManaged; - return $this; - } - /** * Gets the destination scaffold file that this result refers to. * diff --git a/core/lib/Drupal/Component/Scaffold/Operations/SkipOp.php b/core/lib/Drupal/Component/Scaffold/Operations/SkipOp.php index d61b26c3a2..325737be0f 100644 --- a/core/lib/Drupal/Component/Scaffold/Operations/SkipOp.php +++ b/core/lib/Drupal/Component/Scaffold/Operations/SkipOp.php @@ -19,7 +19,7 @@ class SkipOp implements OperationInterface { public function process(ScaffoldFilePath $destination, IOInterface $io, ScaffoldOptions $options) { $interpolator = $destination->getInterpolator(); $io->write($interpolator->interpolate(" - Skip [dest-rel-path]: disabled")); - return (new ScaffoldResult($destination))->setManaged(FALSE); + return new ScaffoldResult($destination, FALSE); } } diff --git a/core/lib/Drupal/Component/Scaffold/ScaffoldFileInfo.php b/core/lib/Drupal/Component/Scaffold/ScaffoldFileInfo.php index b9f3eea8d0..c17fe3096d 100644 --- a/core/lib/Drupal/Component/Scaffold/ScaffoldFileInfo.php +++ b/core/lib/Drupal/Component/Scaffold/ScaffoldFileInfo.php @@ -30,16 +30,17 @@ class ScaffoldFileInfo { protected $op; /** - * Sets the Scaffold operation. + * Constructs a ScaffoldFileInfo object. * + * @param \Drupal\Component\Scaffold\ScaffoldFilePath $destination + * The full and relative paths to the destination file and the package + * defining it. * @param \Drupal\Component\Scaffold\Operations\OperationInterface $op * Operations object that will handle scaffolding operations. - * - * @return $this */ - public function setOp(OperationInterface $op) { + public function __construct(ScaffoldFilePath $destination, OperationInterface $op) { + $this->destination = $destination; $this->op = $op; - return $this; } /** @@ -62,20 +63,6 @@ public function packageName() { return $this->destination->packageName(); } - /** - * Sets the relative path to the destination. - * - * @param \Drupal\Component\Scaffold\ScaffoldFilePath $destination - * The full and relative paths to the destination file and the package - * defining it. - * - * @return $this - */ - public function setDestination(ScaffoldFilePath $destination) { - $this->destination = $destination; - return $this; - } - /** * Gets the destination. * diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php b/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php index 802d9a3aeb..86dab883e1 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php @@ -159,7 +159,7 @@ public function getLocationReplacements() { */ public function replaceOp($project_name, $source) { $source_path = $this->sourcePath($project_name, $source); - return (new ReplaceOp())->setSource($source_path); + return new ReplaceOp($source_path, TRUE); } /** @@ -175,7 +175,7 @@ public function replaceOp($project_name, $source) { */ public function appendOp($project_name, $source) { $source_path = $this->sourcePath($project_name, $source); - return (new AppendOp())->setAppendFile($source_path); + return new AppendOp(NULL, $source_path); } /** diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Integration/AppendOpTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Integration/AppendOpTest.php index 339daa0ae1..a1119a262e 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Integration/AppendOpTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Integration/AppendOpTest.php @@ -23,19 +23,14 @@ public function testProcess() { $destination = $fixtures->destinationPath('[web-root]/robots.txt'); $source = $fixtures->sourcePath('drupal-assets-fixture', 'robots.txt'); $options = ScaffoldOptions::defaultOptions(); - $originalOp = new ReplaceOp(); - $originalOp->setSource($source); - $originalOp->setOverwrite(TRUE); + $originalOp = new ReplaceOp($source, TRUE); $prepend = $fixtures->sourcePath('drupal-drupal-test-append', 'prepend-to-robots.txt'); $append = $fixtures->sourcePath('drupal-drupal-test-append', 'append-to-robots.txt'); - $sut = new AppendOp(); - $sut->setOriginalOp($originalOp); - $sut->setPrependFile($prepend); - $sut->setAppendFile($append); + $sut = new AppendOp($prepend, $append); // Assert that there is no target file before we run our test. $this->assertFileNotExists($destination->fullPath()); // Test the system under test. - $sut->process($destination, $fixtures->io(), $options); + $sut->preprocess($originalOp, $destination, $fixtures->io(), $options); // Assert that the target file was created. $this->assertFileExists($destination->fullPath()); // Assert the target contained the contents from the correct scaffold files. diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Integration/OperationCollectionTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Integration/OperationCollectionTest.php index 54863e3894..6bd8d8ab87 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Integration/OperationCollectionTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Integration/OperationCollectionTest.php @@ -5,6 +5,8 @@ use PHPUnit\Framework\TestCase; use Drupal\Component\Scaffold\ScaffoldFileInfo; use Drupal\Tests\Component\Scaffold\Fixtures; +use Drupal\Component\Scaffold\Operations\AppendOp; +use Drupal\Component\Scaffold\Operations\PreprocessOp; use Drupal\Component\Scaffold\Operations\SkipOp; use Drupal\Component\Scaffold\Operations\OperationCollection; @@ -62,8 +64,15 @@ protected function assertResolvedToSameOp($project, $dest, $file_mappings, $scaf $resolved_file_info = $resolved_file_mappings[$project][$dest]; $this->assertEquals(get_class($resolved_file_info), ScaffoldFileInfo::class); $resolved_scaffold_op = $resolved_file_info->op(); - $this->assertEquals(get_class($file_mappings[$project][$dest]), get_class($resolved_scaffold_op)); - $this->assertEquals($file_mappings[$project][$dest], $resolved_scaffold_op); + // If this is an append op then it will be overridden by a preprocess op + $expected = get_class($file_mappings[$project][$dest]); + if ($expected == AppendOp::class) { + $this->assertEquals(PreprocessOp::class, get_class($resolved_scaffold_op)); + } + else { + $this->assertEquals($expected, get_class($resolved_scaffold_op)); + $this->assertEquals($file_mappings[$project][$dest], $resolved_scaffold_op); + } $this->assertEquals($project, $scaffold_list[$dest]->packageName()); } diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Integration/ReplaceOpTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Integration/ReplaceOpTest.php index 492b67ef20..ec568fc8da 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Integration/ReplaceOpTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Integration/ReplaceOpTest.php @@ -22,9 +22,7 @@ public function testProcess() { $destination = $fixtures->destinationPath('[web-root]/robots.txt'); $source = $fixtures->sourcePath('drupal-assets-fixture', 'robots.txt'); $options = ScaffoldOptions::defaultOptions(); - $sut = new ReplaceOp(); - $sut->setSource($source); - $sut->setOverwrite(TRUE); + $sut = new ReplaceOp($source, TRUE); // Assert that there is no target file before we run our test. $this->assertFileNotExists($destination->fullPath()); // Test the system under test.