Commit 81d27473 authored by catch's avatar catch
Browse files

fix: #3633186 [regression] core/scripts/dr and core/scripts/drupal fail to...

fix: #3633186 [regression] core/scripts/dr and core/scripts/drupal fail to find the autoloader when the docroot is web/

By: gábor hojtsy
By: phenaproxima
(cherry picked from commit 912a0d3b)
parent 057c52b4
Loading
Loading
Loading
Loading
Loading
+5 −2
Changes for core/scripts/dr: 5 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -23,9 +23,12 @@ require_once __DIR__ . '/../../autoload_runtime.php';
return static function (array $context): Application {
  // We must check _composer_autoload_path before we use it, because legacy
  // callers that invoke this script directly, rather than using vendor/bin/dr,
  // won't have that value set in $GLOBALS.
  // won't have that value set in $GLOBALS. In that case, use the autoload.php
  // file in the Drupal root. The vendor directory is not always in the Drupal
  // root (for example, with a web/ docroot), but this file always points to
  // the right place.
  // @see https://getcomposer.org/doc/articles/vendor-binaries.md#finding-the-composer-autoloader-from-a-binary
  $autoload_path = $GLOBALS['_composer_autoload_path'] ?? __DIR__ . '/../../vendor/autoload.php';
  $autoload_path = $GLOBALS['_composer_autoload_path'] ?? __DIR__ . '/../../autoload.php';
  $classloader = require $autoload_path;
  return new DrupalApplication($classloader, $context);
};
+51 −0
Changes for core/tests/Drupal/BuildTests/Command/DrScriptTest.php: 51 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\BuildTests\Command;

use Drupal\BuildTests\Framework\BuildTestBase;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\TestWith;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\PhpExecutableFinder;

/**
 * Tests running the CLI scripts directly from a web/ docroot.
 *
 * In projects created from drupal/recommended-project, the vendor directory is
 * next to the Drupal root, not inside it. Running core/scripts/dr directly,
 * instead of through vendor/bin/dr, must still find the autoloader.
 */
#[Group('Command')]
class DrScriptTest extends BuildTestBase {

  /**
   * Tests calling a CLI script directly when the Drupal root is in web/.
   *
   * @param string $script
   *   The name of the script in core/scripts.
   */
  #[TestWith(['dr'])]
  #[TestWith(['drupal'])]
  public function testDirectCallFromWebDocroot(string $script): void {
    // Build a small project with the Drupal root in web/, and only the files
    // the scripts need. Like the scaffold plugin does for a real project, the
    // autoload files in web/ point to the vendor directory outside of it.
    $vendor = $this->getComposerRoot() . '/vendor';
    $web = $this->getWorkspaceDirectory() . '/web';
    $fs = new Filesystem();
    // The drupal script includes dr, so the test needs both.
    foreach (['dr', 'drupal'] as $file) {
      $fs->copy($this->root . "/core/scripts/$file", "$web/core/scripts/$file");
    }
    $fs->dumpFile("$web/autoload.php", "<?php\n\nreturn require '$vendor/autoload.php';\n");
    $fs->dumpFile("$web/autoload_runtime.php", "<?php\n\n\$_ENV['APP_RUNTIME'] ??= \\Drupal\\Core\\Runtime\\DrupalRuntime::class;\nreturn require '$vendor/autoload_runtime.php';\n");

    $php = (new PhpExecutableFinder())->find();
    $this->executeCommand(escapeshellarg($php) . " core/scripts/$script list", 'web');
    $this->assertCommandSuccessful();
    $this->assertCommandOutputContains('Available commands:');
  }

}