Problem/Motivation
Since Drupal 11.4, running core/scripts/dr or the deprecated core/scripts/drupal directly fails on projects where the Drupal root is in a web/ folder. While core does not use it, that is the default layout for projects made from drupal/recommended-project, and it's also used by Drupal CMS. For example, from the web/ folder:
$ php core/scripts/drupal recipe ../recipes/my_recipe PHP Fatal error: Uncaught Error: Failed opening required '/var/www/html/web/core/scripts/../../vendor/autoload.php'
The script looks for the class loader like this:
$autoload_path = $GLOBALS['_composer_autoload_path'] ?? __DIR__ . '/../../vendor/autoload.php';
When you run vendor/bin/dr, Composer's bin proxy sets $GLOBALS['_composer_autoload_path'], so this works. When you run the script directly, that value is not set, so it falls back to vendor/autoload.php inside the Drupal root.
So: if the vendor folder is not inside the Drupal root, then running the script directly breaks. With a web/ docroot, vendor/ is next to web/, not inside it.
This matters because:
core/scripts/drupalis deprecated but still supported until Drupal 13. The change record for #3453474: CLI entry point in Drupal Core says it is replaced withcore/scripts/dr. Yet both fail in the most common project layout.- Various documentation, tutorials, CI scripts and contrib tests run
php core/scripts/drupal(for examplerecipeandgenerate-theme). - Before 11.4, the script loaded
__DIR__ . '/../../autoload.php', which worked in every layout.
The fallback was added in #3453474: CLI entry point in Drupal Core.
Steps to reproduce
- Create a project with
composer create-project drupal/recommended-project(Drupal 11.4 or later). - Run
cd web && php core/scripts/dr list, orphp core/scripts/drupal list. - The script fails with
Failed opening required '.../web/core/scripts/../../vendor/autoload.php'.
vendor/bin/dr list from the project root works fine though.
Proposed resolution
When _composer_autoload_path is not set, fall back to the autoload.php file in the Drupal root instead of the vendor directory which may be at a different place:
$autoload_path = $GLOBALS['_composer_autoload_path'] ?? __DIR__ . '/../../autoload.php';Remaining tasks
- Review.
- Backport to Drupal 11.x and 11.4.x.
User interface changes
None.
Introduced terminology
None.
API changes
None.
Data model changes
None.
Release notes snippet
N/A.
Generated with the help of an LLM.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3633186
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3633186-11.4-regression-corescriptsdr
changes, plain diff MR !17567
Comments
Comment #3
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #4
gábor hojtsyComment #5
gábor hojtsyComment #6
larowlanI run the layout you've mentioned - with app instead of web
I've recently committed several new commands and have tested each one beforehand with no issues
I have an autoload in both vendor and app (web in your case) and autoload runtime
Comment #7
phenaproximaWe in Drupal CMS have been broken by this, when we try to run
php core/scripts/dr .... It only works with the binary proxy, running from the project root, which is why we need this trait to work around it: https://git.drupalcode.org/project/drupal_cms/-/blob/2.x/drupal_cms_help...Here's my current manual testing against a new Drupal CMS project (stable version), which uses the common project layout:
When I patch
drwith Gábor's change, all of these variants work fine.Comment #8
phenaproximaMarking this RTBC based on my manual testing, and the fact that this is a one-line bug fix that hurts nothing. Sure, people should generally use
vendor/bin/dr, but there's no need to punish those who take the scenic route. It's one line.Comment #9
quietone commentedChanging title per Special titles.
Comment #10
catchCouple of small comments on the test.
Comment #11
gábor hojtsyAddressed @catch's comments on the test.
The test now uses
#[TestWith]instead of a data provider. Shorter indeed :)As for the loop, we need to copy both when we test
drupal, just not when we testdr. We can special case that, but IMHO does not hurt to copydrupaltoo in that case? Otherwise when testingdrupal, it is not enough to copydrupalonly as it requiresdrto be also there. I added a comment for this, hope that helps?Comment #17
catchCommitted/pushed to main and cherry-picked back through to 11.4.x, thanks!