Problem/Motivation

Composer users have to modify autoload.php to properly use Composer. (Docs: Using Composer in a Drupal project)

Proposed resolution

Leverage wikimedia/composer-merge-plugin to merge the dependencies from core/composer.json into composer.json. This allows us to have all dependencies in a single composer file and therefore in a single vendor dir. /vendor becomes the new vendor directory. We could remove it altogether in a follow-up if d.o infrastructure is ready.

This approach works for core development, contrib modules with composer dependencies and a Sugar-free™ composer development workflow.

Remaining tasks

Undo #2406681: Add an autoload.php in the repo root to control the autoloader of front controllers so that we don't need the top-level autoload.php file. This is best handled in a follow-up issue.

User interface changes

API changes

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug, for two reasons. First of all, without this fix, we lose the ability to run composer create-project and composer require which makes composer essentially useless (see http://drupal.org/node/2002304). Second, composer integration is a behavior we are currently trying to support per http://drupal.org/node/2404989, but the only technique available is to modify core. Mod core to use composer is not much of a solution.

Note, however, this is only a bug so long as we are attempting to support composer integration for 8.0 (which I think we should). If we are not attempting to support composer integration for 8.0 then this is not a bug, it is a feature request.

Issue priority Major
Prioritized changes This is a prioritized change because it improves developer experience, allowing Drupal to be used in a way that is more familiar to the greater PHP community.
Disruption Essentially none.
Recommendation Include in 8.0
CommentFileSizeAuthor
#188 2380389-188.interdiff.txt417 byteswebflo
#188 2380389-188.patch2.13 MBwebflo
#183 2380389-182.interdiff.txt601 byteswebflo
#183 2380389-182.patch2.13 MBwebflo
#181 2380389-181.patch2.13 MBwebflo
#180 2380389_180.patch1.81 MBMile23
#177 interdiff.txt2.18 KBMile23
#177 2380389_177.patch35.69 MBMile23
#166 2380389-166.patch2.19 MBwebflo
#165 2380389-164.patch2.09 MBwebflo
#160 2380389-160.patch2.25 MBwebflo
#158 2380389-158.interdiff.txt803 byteswebflo
#158 2380389-158.patch2.19 MBwebflo
#155 interdiff-142-155.txt520 byteshussainweb
#155 2380389-155.patch2.19 MBhussainweb
#155 2380389-155-for-review-do-not-test.patch3.84 KBhussainweb
#153 2380389-142-for-review--do-not-test.patch3.44 KBtstoeckler
#142 2380389-142.interdiff.txt1.15 KBwebflo
#142 2380389-142.patch2.19 MBwebflo
#141 2380389-141.interdiff.txt771 byteswebflo
#141 2380389-141.patch2.19 MBwebflo
#140 2380389-138.patch2.19 MBwebflo
#140 2380389-138.interdiff.txt771 byteswebflo
#137 2380389-137.patch2.19 MBwebflo
#131 2380389-131.patch2.19 MBwebflo
#131 2380389-131-interdiff.patch776 byteswebflo
#127 2380389-127.patch2.19 MBwebflo
#127 2380389-127-interdiff.txt981 byteswebflo
#124 2380389-122.patch2.19 MBwebflo
#123 2380389-121.patch2.09 MBwebflo
#117 2380389-117.patch4.32 MBwebflo
#117 2380389-117-composer.json_.patch1.08 KBwebflo
#88 composer-merge-plugin-2380389-88.patch3.12 MBwebflo
#88 composer-merge-plugin-2380389.patch1.04 KBwebflo
#77 use_a_single_vendor-2380389-77.patch343 bytestimmillwood
#75 2380389-75.patch5.38 MBtimmillwood
#72 2380389-72.patch36.06 MBtimmillwood
#65 2380389_code_only_do_not_test.txt2.57 KBMile23
#65 2380389_64.patch3.93 MBMile23
#49 composer_only_do_not_test.txt2.12 KBMile23
#49 2380389_49.patch2.81 MBMile23
#41 2380389_41.patch32.42 MBMile23
#41 2380389_composer.json_.do_not_test.txt1.65 KBMile23
#32 interdiff.txt1.64 KBMile23
#32 2380389_32.patch11.59 KBMile23
#29 interdiff_18.txt11.72 KBMile23
#29 2380389_29.patch11.77 KBMile23
#18 2380389_18.patch11.41 KBMile23
#17 2380389_17.patch2.43 KBMile23
#13 move-vendor-2380389-13.patch1.42 MBdavidwbarratt
#11 move-vendor-2380389-11.patch1.42 MBdavidwbarratt
#7 move-vendor-2380389-7.patch1.41 MBdavidwbarratt
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

swentel’s picture

davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

Title: Change index.php to use a vendor directory in the root or move code out of index.php and into core » Change index.php to use a vendor directory in the root
Issue summary: View changes
davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

Status: Postponed » Needs review
FileSize
1.41 MB
davidwbarratt’s picture

Issue summary: View changes

Status: Needs review » Needs work

The last submitted patch, 7: move-vendor-2380389-7.patch, failed testing.

davidwbarratt’s picture

That's weird... anyone know why core/vendor/guzzlehttp/guzzle/tests/perf.php would have a syntax error when renamed to vendor/guzzlehttp/guzzle/tests/perf.php ?

davidwbarratt’s picture

Status: Needs work » Needs review
FileSize
1.42 MB

Would probably help if I fixed all of the references to the vendor directory, not just one. :)

Status: Needs review » Needs work

The last submitted patch, 11: move-vendor-2380389-11.patch, failed testing.

davidwbarratt’s picture

Status: Needs work » Needs review
FileSize
1.42 MB

I forgot that we are excluding vendor directory tests, updating the path of the exclude.

Status: Needs review » Needs work

The last submitted patch, 13: move-vendor-2380389-13.patch, failed testing.

hussainweb’s picture

The reason, apparently, is the testbot. The syntax checker might have been configured to skip syntax checks for all files within core/vendor. I saw a few other testbot logs (like one here) for patches modifying external libraries and they skip syntax checks for everything within core/vendor. Unfortunately, I don't know to whom this should go. Maybe someone at IRC can help.

The syntax error is because this particular file needs PHP 5.5. The file in the Drupal core right now needs it too but since they normally skip syntax checks, this did not fail earlier.

Mile23’s picture

Status: Needs work » Needs review
FileSize
2.43 KB

I can't review the existing patch because it's 1.4mb.

Here's my go. It requires manual testing, using these steps:

  • Pull the repo.
  • Make sure you're in the root directory.
  • Type composer install and let it finish.
  • Apply the patch.
  • Run PHPunit: ./vendor/bin/phpunit -c core/

You have to apply the patch after composer install because it re-installs core, obliterating any changes we just made. Also the patch might not apply because we're not sure when the core package was last updated.

But you can read the patch and get the idea.

PHPUnit will fail a few tests on the UnroutedUrlAssemblerTest test class, because they apparently don't know how to deal with a different core root directory.

Hopefully this patch should pass normal testing, because it also allows for the previous behavior of a non-customized vendor directory.

Room for improvement: Create core/autoload.php which does this for us in only one place, and change all references to vendor/autoload.php to load it.

Mile23’s picture

FileSize
11.41 KB

Here's a better version which introduces core/autoload.php.

It illustrates the concept, but it won't apply after you do composer install, but the library is closing so I'll quit here.

Status: Needs review » Needs work

The last submitted patch, 18: 2380389_18.patch, failed testing.

davidwbarratt’s picture

Mile23,

Well isn't that a clever solution. I was thinking we'd need to have a single vendor directory that is outside of /core, but your solution allows for both.

Although, it doesn't allow someone to have the vendor directory above the web-root (which is typically where it would be anyways). My solution didn't allow for this either now that I'm thinking about it.

Rather than doing a file_exists() on every request, why don't we just have an autoloader_path as part of the $conf array (or some sort of configuration variable?). That way, if the variable is set, that is what is used, otherwise it defaults to the path inside the core directory.

davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

Mile23’s picture

Although, it doesn't allow someone to have the vendor directory above the web-root (which is typically where it would be anyways). My solution didn't allow for this either now that I'm thinking about it.

No, vendor shouldn't be above the web root. It should be alongside whichever composer.json is active. Thus far, it looks like Drupal only lets you have composer.json in one of two places.

Rather than doing a file_exists() on every request

Some systems need auto load without the dependencies of the container.

If Drupal weren't wrongheaded about composer, this would be a non-issue. But here we are :-)

davidwbarratt’s picture

#23,

Composer let's you put the vendor directory wherever you want:
https://getcomposer.org/doc/04-schema.md#config

By default, you're correct, it's in vendor/ of the active composer.json. But there's nothing stopping you from putting in ../vendor for instance.

Also, there's nothing stopping you from moving the root composer.json file up one level too. In which case the vendor directory would be outside the webroot.

I typically follow the Symfony Standard layout which has the composer.json and vendor outside the webroot for increased security:
https://github.com/symfony/symfony-standard

davidwbarratt’s picture

Is there any way to use the $conf array that that point?

davidwbarratt’s picture

Nevermind, I guess there's not any config that is loaded at that point... I was thinking of what I did in D7:
https://www.drupal.org/project/composer_autoloader

I guess file_exists() is probably the way to go, unless we want to move the whole vendor directory up one folder.

Mile23’s picture

We are defining the composer.json file, so it's reasonable to assume that vendor/ will be where we say it is.

If someone needs to put vendor/ somewhere else, they can modify core/autoload.php, and by doing so magically change it everywhere.

davidwbarratt’s picture

#27,

Makes sense to me. But in that case shouldn't core/autoload.php be <root>/autoload.php? that way it's "user-editable" (i.e. it doesn't get blown away whenever you run composer update)?

Mile23’s picture

Status: Needs work » Needs review
FileSize
11.77 KB
11.72 KB

OK, here's the same idea, just in /autoload.php.

It should pass the testbot because it works either way. :-)

Manually test it under composer control:

  • Make sure you're in the root directory.
  • Type composer install and let it finish.
  • Apply the patch (Use git apply --reject in case the patch doesn't apply cleanly.)
  • Run PHPunit: ./vendor/bin/phpunit -c core/

Will need some other way to check out if the simpletest tests work under composer. Probably involving a .travis.yml file.

Status: Needs review » Needs work

The last submitted patch, 29: 2380389_29.patch, failed testing.

davidwbarratt’s picture

+++ b/core/includes/bootstrap.inc
@@ -716,7 +716,7 @@ function drupal_bootstrap($phase = NULL) {
+          $classloader = require __DIR__ . '/../autoload.php';

This should be two levels up. :)

Otherwise I think it looks really good.

Mile23’s picture

Status: Needs work » Needs review
FileSize
11.59 KB
1.64 KB

Solved the problem with SimpleTestBrowserTest, but the problem with SessionHttpsTest remains because https.php is devil code.

Mile23’s picture

Hmm. Looks like that fixed itself.

Mile23’s picture

Status: Needs review » Closed (duplicate)

This is a duplicate: #2406681: Add an autoload.php in the repo root to control the autoloader of front controllers

That issue has patches by a core maintainer, so let's mark this one a dupe.

davidwbarratt’s picture

Status: Closed (duplicate) » Needs work

I'm reopening this issues, since the goal(s) of this issue were not resolved in #2406681: Add an autoload.php in the repo root to control the autoloader of front controllers

davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

Title: Change index.php to use a vendor directory in the root » Use a single vendor directory in the root
davidwbarratt’s picture

Issue summary: View changes
davidwbarratt’s picture

#13 is the most recent patch on this issue.

Mile23’s picture

Mile23’s picture

Status: Needs work » Needs review
FileSize
1.65 KB
32.42 MB

OK, baby steps.

This changes the composer.json file to put its vendor directory in the root directory.

You can apply the small patch and then do this:

$ cd core/
$ composer install

This should put all the stuff into vendor/ and all the autoload.php stuff will work.

This patch just deletes the classmap section of the composer.json file. We can re-add this as needed.

Also: Big patch is big.

Mile23’s picture

Added some desired behaviors to the meta issue here: #2002304: [META] Improve Drupal's use of Composer

This patch supports those goals by making it so no one is required to edit autoload.php to point to a different vendor/ directory.

MKorostoff’s picture

Issue tags: +Composer
MKorostoff’s picture

Issue summary: View changes
MKorostoff’s picture

Status: Needs review » Needs work

Patch in #41 not applying on head for me

MKorostoff’s picture

Issue summary: View changes

The last submitted patch, 41: 2380389_41.patch, failed testing.

Mile23’s picture

Fixed a problem while making this work: #2445497: Decouple ContainerBuilderTest from Symfony's tests.

Either this one or that one will need a reroll depending on which lands first.

Mile23’s picture

Status: Needs work » Needs review
FileSize
2.81 MB
2.12 KB

So just making this patch was a pain, mostly because we keep vendor/ in the repo. Which is kind of wrong-headed, but there you go.

When applied, this patch will introduce whitespace errors, for the same reason.

In order to make the patch, I eventually had to do this:

$ git config diff.renameLimit 5000
$ git diff -M --binary 8.0.x > 2380389_49.patch

Anyway, if you can't make the monster patch work for you, there's a smaller patch of just core/composer.json and autoload.php. Apply that, apply the working patch from here: #2445497: Decouple ContainerBuilderTest from Symfony's tests. and then do this:

$ cd core
$ composer install

Now you can run unit tests from the root directory, like this:

$ ./vendor/bin/phpunit -c core/

Status: Needs review » Needs work

The last submitted patch, 49: 2380389_49.patch, failed testing.

Mile23’s picture

#49 fails due to the testbot ignoring the wrong directory: #2460991: Ignore root level vendor/ during testbot lint

Mile23’s picture

joelpittet’s picture

Thanks for cross linking, didn't know this was already going, I updated your regex-fu slightly on the pifr patch.

bojanz’s picture

Conceptually wouldn't it make more sense to package vendor/ as the vendor directory of drupal/drupal, instead of specifying it as "../vendor" for drupal/core?

Mile23’s picture

@bojanz: Eventually we'll undo #2406681: Add an autoload.php in the repo root to control the autoloader of front controllers and then it will all just make sense.

But for now, baby steps. :-)

....And now #2460991: Ignore root level vendor/ during testbot lint is in, so yay! We can proceed here.

Mile23’s picture

We're still waiting on a review of this: #2445497: Decouple ContainerBuilderTest from Symfony's tests.

Patch no longer applies. Special reroll info in #49.

Mile23’s picture

Issue summary: View changes
alexpott’s picture

At yesterdays BOF organised by @bojanz we discussed all things composer - through discussion we realised that moving core/vendor outside of core we'd prevent people updating core using a tarball after using composer with a contrib module that needs it. @bojanz is going to explore using https://sculpin.io/documentation/embedded-composer/ to use two vendor directories - one for contrib and one for core. A summary of BOF will be produced sometime soon...

hussainweb’s picture

I have been thinking long of using embedded composer for this scenario. I think it fits perfectly. @bojanz, please let me know if I can help in any way.

webflo’s picture

@alexpott: If a user installed or updated a contrib module with composer already, why is it not feasible to enforce the core update through composer?

alexpott’s picture

#60 how can we enforce that?

Mile23’s picture

Restating the problem:

If we have root vendor/, it gets overwritten by the tarball because we're distributing vendor/ with the tarball. That means contrib has to find a way to re-add their requirements.

If we have core/vendor/ it gets overwritten, but that's ok because it's only the vendor directory for core.

If we've used composer create-project to create the site, this is not a problem, because core is then a dependency which we can manage with composer update, and in fact modules could declare their dependency on specific core versions.

This is a good behavior, but it's also not one that we can rely on since we need to distribute as tarballs.

bojanz’s picture

I've created #2489646: Start using $root/vendor for non-core dependencies only since it's a completely different approach. Please comment and review.

Crell’s picture

Something else that occurred to me sometime after the BoF: Using Composer as a first-class citizen for installing modules is going to force our hand on #1612910: [policy, no patch] Switch to Semantic Versioning for Drupal contrib extensions (modules, themes, etc). If Packagist/Composer is going to be installing modules, then those modules must have a semver-compatible version string. It just won't work otherwise.

I still think we should do it; it's just one more thing we have to factor into our implementation/policy changes.

Mile23’s picture

Status: Needs work » Needs review
FileSize
3.93 MB
2.57 KB

Here's a reroll.

Patch introduces whitespace errors because it's moving around non-Drupal code.

If you can't make the big patch apply, try the smaller one and then do:

$ cd core/
$ composer update

Note that the changes to \Drupal\Core\Composer\Composer illustrate the brittle nature of that kind of premature optimization.

Status: Needs review » Needs work

The last submitted patch, 65: 2380389_64.patch, failed testing.

Mile23’s picture

This issue will conflict with #2389243: Remove unnecessary BC-layer in install_drupal() needing a reroll in one or the other.

Xano’s picture

I'm a little late to the game, so please point me to the appropriate sources if I am missing any important information.

I've been going through the code base, as well as this issue and several others for the past few days, and what I do not understand is why we treat drupal/core differently from regular packages:

  1. drupal/core is its own package, so one could argue it should be usable as such. It also has a Composer package type of drupal-core, which makes it special, yet I have not been able to find documentation on how and why this type of package is special. drupal/drupal is also the package that provides the Composer installer to put drupal/core in the correct subdirectory within the application, yet this isn't clear when looking at drupal/core itself, for instance if one wants to write a custom front controller.
  2. drupal/core is supposed to be installed within a bigger application. Keeping a separate vendor directory for drupal/core undoes Composer's core benefit. This issue is about removing that directory, but why do we keep vendor information in ./core/composer.json and \Drupal\Core\Composer\Composer?
Mile23’s picture

@xano

#68.1:

So if you look at the root-level composer.json file, you'll see that it requires composer/installers.

composer/installers is a composer plugin that knows what a drupal-core package is, and that it should go into the core/ directory. The readme: https://github.com/composer/installers and specifically: https://github.com/composer/installers/blob/7a388b041ee5b6489173b1027e75...

So if you do this:

$ cd DRUPAL_ROOT
$ composer install

Here's what happens:

Composer sees the root-level composer.json. It looks at the composer.json files of its dependencies (composer/installers and drupal/core). It sees that composer/installers is a plugin and then uses it while installing other packages. composer/installers takes over and puts drupal/core into the core directory.

Basically it overwrites the current core/ directory with the one it just downloaded from d.o.

So now you'd have a versioned core that composer is managing. Unfortunately for us right now, the subtree split isn't completely up to date, so the core you'll then have won't be @dev. The good part is that when/if the subtree split is set up on d.o, you'll be able to update Drupal core by saying composer update --prefer-stable.

If you want to make a bespoke front controller, having a separate drupal/core package is good news for you. You can now make your own project, and have it depend on drupal/core and not get any of the root-level files. But if you don't also depend on composer/installer, then D8 core will be filed away under /vendor/drupal/core/. This breaks Drupal, so don't do it. (In fact, core should be the one to depend on composer/installers, but let's address that elsewhere.)

#68.2:

Composer also generates class maps for autoloading. The class maps arrays in /core/composer.json and that Composer class are there so common classes don't have to be looked up by the autoloader and are always present in the class map as literals. It's a performance optimization.

Xano’s picture

@Mile23: thank you for taking the time to explain this so clearly. I was familiar with most of the technical aspects, but it's good you've confirmed what I already thought. My main concern is how all this is documented. There is no README file in drupal/core, or documentation in that package's Composer file.

Composer also generates class maps for autoloading. The class maps arrays in /core/composer.json and that Composer class are there so common classes don't have to be looked up by the autoloader and are always present in the class map as literals. It's a performance optimization.

I was wondering if those shouldn't also be moved to the application level, but I now realize that would require any front controller package to be bigger than the bare minimum

yched’s picture

Also, note that the template provided in https://github.com/drupal-composer/drupal-project already works pretty good.
Only drawback is that you get duplicated code between (root)/vendor and (root)/web/core/vendor, with the latter being just dead code - that is until we stop committing vendor code in our core repo (aka #1475510: Remove external dependencies from the core repo and let Composer manage the dependencies instead).

timmillwood’s picture

Status: Needs work » Needs review
FileSize
36.06 MB

A 36MB patch, but moved vendor from"/core" to "/". Also updates it, adds composer.lock to root, removes composer.lock and .gitignore from "/core".

Ideally I'd like to remove the vendor directory, but this seems like a first step.

Status: Needs review » Needs work

The last submitted patch, 72: 2380389-72.patch, failed testing.

davidwbarratt’s picture

#72,

If you are renaming/moving things, you can use git diff -C -M to make a smaller patch (doesn't work when deleting things though).

timmillwood’s picture

Status: Needs work » Needs review
FileSize
5.38 MB

Let's try this

Status: Needs review » Needs work

The last submitted patch, 75: 2380389-75.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
343 bytes

If we're using a single vendor directory I think it should go in the /core directory, this patch updates "composer.json" to put vendor in core.

By putting it in core by default it allows those who manage core manually to just copy the latest "core" folder from a zip file to the FTP server. It also allows people to run `composer install` in the root directory and update all the dependencies.

It does however mean most custom dependencies will end up in core, and one using composer you need to continue. This is not such a bad thing, just something that needs to be dictated on a per project basis.

davidwbarratt’s picture

Status: Needs review » Needs work

#77,

I appreciate your enthusiasm, but what you've proposed wont work.

If I update my project's composer.json to look like this:

"require": {
    "composer/installers": "^1.0.20",
    "league/commonmark": "0.8.*",
    "drupal/core": "~8.0"
  },
}

and I run composer update, Composer will:

  1. Download league/commonmark into ./core/vendor/league/commonmark
  2. Delete ./core
  3. Download drupal/core into ./core

If you see what will happen, league/commonmark will never be installed because it will always be overwritten by drupal/core. The only way around this is to use something like Composer preserve paths to ensure that the path is not overwritten.

If you are a Composer user, you don't manage core manually, you simply execute composer update and composer will update everything in ./core for you (as well as resolve all of the dependencies).

alexpott’s picture

If you are a Composer user, you don't manage core manually, you simply execute composer update and composer will update everything in ./core for you (as well as resolve all of the dependencies).

It does however mean most custom dependencies will end up in core, and one using composer you need to continue. This is not such a bad thing, just something that needs to be dictated on a per project basis.

The problem with these statements is that we'll have projects telling people to use composer to install the project - for example Rules and Commerce and then instructions everywhere telling people to download core and copying it over. The once you've used Composer always use Composer is easy to say but it's going to be hard to enforce. This is what discussion in LA concluded and why #2489646: Start using $root/vendor for non-core dependencies only was opened.

timmillwood’s picture

@alexpott - Thanks for the comments the problem with #2489646: Start using $root/vendor for non-core dependencies only as mentioned in there is it means having to require two autoload.php's, once I updated the autoloader-suffix so it's different in each composer.json I thought I was on to something, but no luck. Also what if core and module X require the same package? will we end up with conflicts?

I am looking to have Drupal 8 is a way (like many other PHP projects) that it can be fully managed via composer, currently that's not an option. I'm happy to go with whatever the consensus as long as it works.

davidwbarratt’s picture

#80

I am looking to have Drupal 8 is a way (like many other PHP projects) that it can be fully managed via composer, currently that's not an option. I'm happy to go with whatever the consensus as long as it works.

Why is that not an option?
I'm already doing it here:
https://github.com/davidbarratt/drupal8

Also see this template:
https://github.com/drupal-composer/drupal-project

I've even fully managed Drupal 7 with Composer, so I'm not sure why you think it's not an option.

davidwbarratt’s picture

#79,

I think this is the more broad ticket #2477789: Use composer to build sites, but yes, I acknowledge that it's a potential issue, and I'm not sure the best way to solve it, but I do know that using a single vendor directory in ./core/vendor doesn't solve the problem either (nor does reverting #1975220: Allow a Composer user to manage Drupal, modules, and PHP dependencies with a custom root composer.json). :(

timmillwood’s picture

@davidwbarratt - I mainly didn't see it as being possible because I cloned the Drupal git repo, ran `composer update` and I now had two copies of everything, one in /vendor and one in /core/vendor.

yched’s picture

I mainly didn't see it as being possible because I cloned the Drupal git repo, ran `composer update` and I now had two copies of everything, one in /vendor and one in /core/vendor

See https://github.com/drupal-composer/drupal-project/issues/23
One drawback of https://github.com/drupal-composer/drupal-project is indeed that you end up with duplicate code between vendor and core/vendor. It's only a cosmetic annoyance, because the project makes sure that the autoloader only ever sees the former (composer managed), and the latter (pulled with drupal/core since it's currently hard-committed in our repo) is only dead code, never actually loaded at runtime. It's just a (very actual) pita when doing searches in your IDE.

But other than that drupal-composer/drupal-project does seem to work fairly well.

davidwbarratt’s picture

#83,

You're told in the readme exactly what to do:

"_readme": [
  "By default Drupal loads the autoloader from ./core/vendor/autoload.php.",
  "To change the autoloader you can edit ./autoload.php."
]

Basically what you've pointed out is the reason for this issue, it's an annoyance that it's still in /vendor, but it works when you update ./autoload.php.

timmillwood’s picture

Taking a step back I think we need the d.o packager and testbot working with composer before we can move forward.

#1923582: Add ability for testbot to run 'composer install' during installation and #2315545: Install composer dependencies to D8 when packaging run composer install in the core directory, this should therefore work before and after any changes we make.

Mile23’s picture

webflo’s picture

I tried to approach the problem again with the composer-merge-plugin from wikimedia (https://github.com/wikimedia/composer-merge-plugin)

composer-merge-plugin-2380389.patch contains just the changed composer.json the another one moved core/vendor back to vendor.

timmillwood’s picture

On the fence about this issue, but looking forward to discussing it on Tuesday afternoon (if not before!).

webflo’s picture

The composer-merge-plugin allows us to to a few things.

  • /composer.json is a working example
  • /composer.json is not polluted with core dependencies, it includes the dependencies from core/composer.json
  • composer create-project drupal/drupal just works
  • Get rid of core/composer.lock
  • Follow-up: Get rid of autoload.php, because the autoloader is always in vendor/autoload.php
  • Follow-up: Composer manager could manipulate /composer.json. Less specific login in the composer manager module.

The last submitted patch, 88: composer-merge-plugin-2380389.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 88: composer-merge-plugin-2380389-88.patch, failed testing.

Mile23’s picture

Status: Needs work » Reviewed & tested by the community

Diggit. :-)

So composer-merge-plugin is nice and lets me type composer install at the top level and Drupal still works, which means people new to Drupal won't destroy their site by doing what comes naturally.

We can still do the subtree split for create-package, and if we don't, we can easily pull the two composer.json files together and remove the dependency on composer-merge-plugin.

+1.

Just one thing:

/composer.json is a working example

That's not true in this patch. The top-level composer.json file is a working working. :-)

Also, this mechanism of composer-merge-plugin could be extended to merge in other arbitrary composer.json files as well, but that's way outside scope here.

bojanz’s picture

I am completely convinced by #88.

It gives us a single vendor directory, and no need to hack autoload.php anymore.
It also resolves the main problem alexpott and others had with the "single vendor" proposal, which is the inability to just replace the core directory if there's been a security update. Meanwhile, nothing's stopping people from modifying composer.json to download core as well if they want to.
I've always felt that blowing away core/ only makes sense if you're starting with Composer (ala Drush Make) in the first place, which is not always the correct assumption.

It allows people to simply do "composer require drupal/commerce" and get the module and its dependencies without any additional steps or dangers.
This finally makes the main part of composer_manager obsolete.

Testing contrib will require a way to point Composer to a local dir for a module, but that should be doable with the new local repository feature Composer has.

davidwbarratt’s picture

Status: Reviewed & tested by the community » Needs work

Well that's a clever solution. I personally would still just add drupal/core and use the subtree split, but it seems like it resolves the problems others are having while still allowing people like me to do it more of a "composer way".

Only feedback is that perhaps on this:

"wikimedia/composer-merge-plugin": "^1.3@dev"

it should be:

"wikimedia/composer-merge-plugin": "^1.3.0"

I think that should load the dev version until 1.3.0 is hit, but if I'm wrong feel free to move this back to RTBC.

alexpott’s picture

I'm a massive +1 to this issue. I think it finally delivers what we want with composer. There are still some tricky things to sort out with respect to managing your project with a mixture of methods - for example starting with composer and then downloading core - but that can be solved with documentation as this is truely an edge case - but this does address my main concerns. Can we file a followup to remove autoload.php since this patch makes it obsolete.

Also we need a CR and proof that existing sites can work happily with this change. It would also be great to get an issue summary that explains the concerns and how the approach addresses them.

webflo++

davidwbarratt’s picture

+++ b/composer.json
@@ -5,7 +5,10 @@
     "composer/installers": "^1.0.21",

Also, you should be able to remove this line since there's no need for Composer Installers if you're not using the subtree split. This should also prevent the dependency from being installed.

You can also remove the readme in ./composer.json, because there shouldn't be any need to modify ./autoload.php now, but at a minimum, the path in the readme needs to be updated.

davidwbarratt’s picture

#96,

I would not remove ./autoload.php because if we remove it, we are assuming the ./vendor directory is in the docroot, when that is not necessarily the case. I always move it out of the docroot for security reasons, if we remove ./autoload.php I wouldn't be able to do that. :(

bojanz’s picture

We also need to move the scripts from core/composer.json to composer.json, the merge plugin doesn't merge them and they make sense on the root composer.json anyway.

I've checked the rebased autoload paths (since a merge-plugin issue said it can sometimes be buggy), and they are all rebased correctly.

Also, you should be able to remove this line since there's no need for Composer Installers if you're not using the subtree split. This should also prevent the dependency from being installed.

Untrue. That would prevent you from being able to require modules ("composer require drupal/commerce")

yched’s picture

That approach looks awesome.

Just wondering : https://github.com/wikimedia/composer-merge-plugin/issues/72 seems to hint that the new 'path' repository type added recently in Composer possibly makes composer-merge-plugin moot, so could we solve this with a native 'path' repo ?

bojanz’s picture

@yched
No, we cannot. That allows a local directory to satisfy dependencies, but you still need to specify those dependencies in the first place.

As for:

I would not remove ./autoload.php because if we remove it, we are assuming the ./vendor directory is in the docroot, when that is not necessarily the case. I always move it out of the docroot for security reasons, if we remove ./autoload.php I wouldn't be able to do that. :(

Feels like a good enough reason to keep it, but we'll need to update the docblock.

davidwbarratt’s picture

#99,

By the same argument, we should add Drupal Packagist to ./composer.json. Your example only allows you to install packages that are on the standard Packagist.

I actually think we should add Drupal Packagist to ./composer.json, but not everyone agrees. In my mind, we either add Drupal Packagist, put all modules on the standard Packagist, or we remove the dependency on Composer Installers. I just don't see the point in having it if there are only a few modules are on standard Packagist anyways. :/

davidwbarratt’s picture

#99,

Also, what happens when Drupal core updates the scripts? Does the user need to manually merge the script list? Doesn't this bring us back to the same problem we had before with the dependencies?

yched’s picture

@bojanz #101

[Composer's 'path' repo] allows a local directory to satisfy dependencies, but you still need to specify those dependencies in the first place.

Right,
- the root composer.json
declares /core as a local 'path' repository,
and requires 'drupal/core'
- /core/composer.json exposes the 'drupal/core' package and lists its 'require's
?

Then if you want to use the subtree split instead, just remove the /core 'path' repo from the root composer.json, and remove /core from your project's git ?

Sorry for the disruption, I'm most probably missing something here, but can't see what atm.

bojanz’s picture

By the same argument, we should add Drupal Packagist to ./composer.json. Your example only allows you to install packages that are on the standard Packagist.

There's a parallel discussion going on in #2551607: [meta] Path forward for Composer support about using Drupal Packagist VS Packagist (by automatically creating d.o projects there). Initial consensus was to use Packagist, but if Drupal Packagist wins after all, then it will definitely need to be added. That's out of scope for this issue.

Also, what happens when Drupal core updates the scripts? Does the user need to manually merge the script list? Doesn't this bring us back to the same problem we had before with the dependencies?

Yes, any additional scripts would need to be manually added.
If we make composer-merge-plugin also merge scripts, then that would resolve your concern and fix the problem before we encounter it.
The current scripts explicitly make sense on the root composer.json and should go there, though.

@yched
It would mean we'd need to keep core/vendor, something we'd want to avoid for confusion sake.
It would also mean we'd need to reinvent merging all of the other keys (such as replace, conflicts, autoload) that composer-merge-plugin handles for us.

webflo’s picture

Issue summary: View changes
webflo’s picture

Issue summary: View changes
yched’s picture

It would mean we'd need to keep core/vendor, something we'd want to avoid for confusion sake.

Really ? I'd expect that, once the drupal/core package is found (locally in that case), its dependencies would get resolved and downloaded to the root /vendor, just like any dependencies of any other packages required by the root composer.json ? So for the tarball we'd just ship core's dependencies in /vendor (i.e. mv core/vendor vendor) ?

It would also mean we'd need to reinvent merging all of the other keys (such as replace, conflicts, autoload) that composer-merge-plugin handles for us.

Right, indeed. But do those keys make more sense in core/composer.json rather than in the root one ?
I mean, if you use the subtree split by requiring packagist's drupal/core in your root composer.json, those keys from core/composer.json are lost as well, right ?

It seems to me that using a 'path' repo keeps 1:1 consistency between "/core comes from the tarball" or "/core is fetched through the subtree split package" : in both cases it's just the drupal/core package, you just modify where it is fetched from (packagist repo or local 'path' repo), otherwise everything else works the same ? That consistency seems important if we want to support both ?

bojanz’s picture

Okay, I've just tried to implement "path" as an alternative to the merge plugin.

This is my composer.json:

{
  "name": "drupal/drupal",
  "type": "project",
  "require": {
    "composer/installers": "^1.0.21",
    "drupal/core": "~8.0"
  },
  "minimum-stability": "dev",
  "prefer-stable": true,
  "config": {
    "preferred-install": "dist",
    "autoloader-suffix": "Drupal8"
  },
  "repositories": [
    {
      "type": "path",
      "url": "core"
    }
  ]
}

So basically I kept it all as-is, but also added a pointer to the core directory as one of the repositories.
This didn't work because Composer empties the target directory before download, so core/ was emptied in preparation for core being downloaded, then Composer looked into core/ to find the package... Two conflicting features.
I also tried to remove drupal/core from "require" and add it to "replace" like webflo's patch did, but this resulted in the core dependencies not being downloaded at all.

So, as it stands we still need the composer-merge-plugin.
I think it's a good idea regardless of the problem above, because it also allows you to add a module to modules/ manually (custom module, for example) and then add it to the merge list to still get its composer dependencies. Useful for testing.

Mile23’s picture

I'd wager it's composer-installer that's emptying the core/ directory.

Anyway, +1 on #109: Don't let the perfect be the enemy of the adequate in this case. We can amend in other issues.

Patch in #88 looking good.

yched’s picture

Meanwhile I was testing the 'path' approach myself, and hit the same issue as @bojanz mentions, with Composer's PathDownloader deleting the target dir before trying to symlink to it since it's also the source dir.

That's IMO a bug in the (still recent) 'path' feature : if the local package is already in its final destination (here "/core", as specified by composer-installer for a package of type "drupal-core") then there's nothing to be done to "download" the package, and PathDownloader::download() shouldn't do any deletion or symlinking.

I fixed it with a relatively simple composer patch (will open a PR asap), and things seem to work fine after that.

I still think that the 'path' repo approach is worthwhile, because of :
- native composer support without depending on an additional corpus of code :-)
- the consistency argument at the end of #108 : "use the tarballed /core" and "use the packagist drupal/core subtree split" being just a switch of repository, with the rest of the composer resolution and processing being strictly equal, is IMO very precious if we intend to support both. I'm a bit worried that merging some keys from core/composer.json in one case and not in the other can be very hairpulling in the long run...

However, I agree we shouldn't wait on that being fixed upstream in Composer. If the merge plugin lets us "mv core/vendor vendor" at last, we should probably go for it, and possibly revisit 'path' later ?

yched’s picture

I think [composer-merge-plugin] is a good idea regardless of the problem above, because it also allows you to add a module to modules/ manually (custom module, for example) and then add it to the merge list to still get its composer dependencies. Useful for testing.

Yeah, that topic (handling the composer.json of local custom modules) is of high interest to me too, see https://github.com/drupal-composer/drupal-project/issues/25 :-)

But that's a different topic IMO. composer-merge-plugin might very well be the right tool for that case, but I'm not sure it's the right tool for the /core thing, for the reasons in #108 / #111.

The last submitted patch, 88: composer-merge-plugin-2380389.patch, failed testing.

The last submitted patch, 88: composer-merge-plugin-2380389-88.patch, failed testing.

yched’s picture

PR for the Composer 'path' repo deleting the local folder : https://github.com/composer/composer/pull/4431

bojanz’s picture

Right, indeed. But do those keys make more sense in core/composer.json rather than in the root one ?
I mean, if you use the subtree split by requiring packagist's drupal/core in your root composer.json, those keys from core/composer.json are lost as well, right ?

I'm a bit worried that merging some keys from core/composer.json in one case and not in the other can be very hairpulling in the long run...

Sure, "path" is conceptually cleaner due to there being one magical class less in the process.
On the other hand, supporting local modules (custom development or testing) and a composer_manager-like workflow in general will end up requiring
the merge plugin anyway, bringing us back to the start.

That said, I'm not sure I see the same problem with the merge plugin.
Keep in mind that Composer already merges these keys at runtime.
If drupal/drupal requires drupal/core, then Composer will download drupal/core, parse its composer.json, and merge its requirements, replacements, autoload information, etc. The only thing the merge plugin adds to the process is doing that merge up front for the specified composer.json files. The mechanism is the same.

webflo’s picture

The last submitted patch, 117: 2380389-117-composer.json_.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 117: 2380389-117.patch, failed testing.

The last submitted patch, 117: 2380389-117-composer.json_.patch, failed testing.

Mile23’s picture

Status: Needs work » Reviewed & tested by the community

+1 on the concept, shown in 2380389-117-composer.json_.patch.

If only we didn't have to mess around with hairy, delicate patches to vendor/. #1475510: Remove external dependencies from the core repo and let Composer manage the dependencies instead

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 117: 2380389-117.patch, failed testing.

webflo’s picture

Status: Needs work » Needs review
FileSize
2.09 MB
webflo’s picture

FileSize
2.19 MB

The last submitted patch, 123: 2380389-121.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 124: 2380389-122.patch, failed testing.

webflo’s picture

Status: Needs work » Needs review
FileSize
981 bytes
2.19 MB

Status: Needs review » Needs work

The last submitted patch, 127: 2380389-127.patch, failed testing.

The last submitted patch, 123: 2380389-121.patch, failed testing.

The last submitted patch, 124: 2380389-122.patch, failed testing.

webflo’s picture

Status: Needs review » Needs work

The last submitted patch, 131: 2380389-131.patch, failed testing.

The last submitted patch, 131: 2380389-131-interdiff.patch, failed testing.

The last submitted patch, 127: 2380389-127.patch, failed testing.

The last submitted patch, 131: 2380389-131-interdiff.patch, failed testing.

The last submitted patch, 131: 2380389-131.patch, failed testing.

webflo’s picture

Status: Needs work » Needs review
FileSize
2.19 MB

Status: Needs review » Needs work

The last submitted patch, 137: 2380389-137.patch, failed testing.

The last submitted patch, 137: 2380389-137.patch, failed testing.

webflo’s picture

Reverted the usage of DRUPAL_ROOT.

webflo’s picture

FileSize
2.19 MB
771 bytes
webflo’s picture

FileSize
2.19 MB
1.15 KB

Found two other instances of core/vendor.

webflo’s picture

Status: Needs review » Needs work

The last submitted patch, 142: 2380389-142.patch, failed testing.

webflo queued 142: 2380389-142.patch for re-testing.

The last submitted patch, 142: 2380389-142.patch, failed testing.

timmillwood queued 142: 2380389-142.patch for re-testing.

timmillwood’s picture

Status: Needs work » Needs review

Not sure why it's not failing tests, it should be passing (passes on DrupalCI)

webflo’s picture

Drafted a change record on #2574533.

timmillwood’s picture

Issue tags: -Needs change record
timmillwood’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs issue summary update

I think issue summary looks good too.

bojanz’s picture

Status: Reviewed & tested by the community » Needs work

We still need to update this comment in autoload.php:

 * This file can be edited to change the autoloader if you are managing a
 * project's dependencies using Composer. If Drupal code requires the
 * autoloader, it should always be loaded using this file so that projects
 * using Composer continue to work.

I suggest we just remove it completely.

We also need to move the "scripts" from the core composer.json to the root composer.json

tstoeckler’s picture

Here's the for-review patch. Generated with the following, after the patch is applied with --index in a clean repo:
git diff --cached `git status --short | grep -v 'vendor/' | grep -v 'composer.lock' | sed -e 's/M //' -e 's/A //' -e 's/?? //' -e 's/D //'`

X-Post with the above, but the script should work for future patches as well.

hussainweb’s picture

+++ b/.gitattributes
@@ -51,3 +51,4 @@
+*.ttf     -text diff

I am probably missing something. Why do we have this?

hussainweb’s picture

Status: Needs work » Needs review
FileSize
3.84 KB
2.19 MB
520 bytes

Changing as per #152. Review patch generated with help of #153. I have not changed anything for #154 yet as I am not clear if that was intentional.

douggreen’s picture

I tested and confirm that applying the patch does not affect/break existing sites. I created a new D8 site, applied the patch, and then checked that the site was still functional. No cc is necessary.

bojanz’s picture

Status: Needs review » Needs work

We still haven't moved the scripts :)

webflo’s picture

Status: Needs review » Needs work

The last submitted patch, 158: 2380389-158.patch, failed testing.

webflo’s picture

Status: Needs work » Needs review
FileSize
2.25 MB

Status: Needs review » Needs work

The last submitted patch, 160: 2380389-160.patch, failed testing.

The last submitted patch, 160: 2380389-160.patch, failed testing.

Status: Needs work » Needs review

webflo queued 160: 2380389-160.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 160: 2380389-160.patch, failed testing.

webflo’s picture

Status: Needs work » Needs review
FileSize
2.09 MB
webflo’s picture

FileSize
2.19 MB
Mile23’s picture

Status: Needs review » Reviewed & tested by the community

Quick before it needs a reroll! :-)

What's the difference between #165 and #166?

webflo’s picture

I forgot to add the Plugin in #166

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +beta target

So! Reviewed this with @webflo tonight at DrupalCon.

Looks like all of the main Composer-y people I know of are on board with this, so that sounds great. The idea of being able to run composer install from root again is lovely. And while @alexpott was initially opposed earlier in this issue, looks like he came around in #2380389-96: Use a single vendor directory in the root. He also requested two things; a change record (which is done) and testing on an existing site to make sure it doesn't break.

On my local I have Acquia Dev Desktop running PHP 5.5.27 w/ APC cache enabled. I went through the following steps:

  1. drush si against latest HEAD
  2. Log in as admin, load the home page in my browser.
  3. Apply patch.
  4. Reload the page.
  5. BAM. Fatal error.
    Warning: require(/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php): failed to open stream: No such file or directory in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    
    Fatal error: require(): Failed opening required '/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php' (include_path='.:/Applications/DevDesktop/common/pear:/usr/lib/php') in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    

Basically the APCu cache is holding onto the old file paths and isn't notified that the file paths have changed. What we found is one of two things can get you out of this situation:

  1. Restart Apache (which clears the APCu cache)
  2. (Once rebuild.php is fixed, see below) Edit your settings.php and add the line $settings['rebuild_access'] = TRUE, then hit /core/rebuild.php, which rebuilds your APCu cache. (No idea how someone is supposed to know how to do that from a PHP fatal error, though. :\)

Things that do not work include: going to update.php (same fatal error), deleting the sites/default/files/php directory (no effect, because old files are cached). And, if you revert the patch you have to restart Apache again because now it'll cache the new files. ;)

So we need a few things here:

1) rebuild.php needs to be fixed because it's still pointing to /vendor/autoload.php after this patch (should be /../autoload.php)
2) Also need automated tests of rebuild.php of any kind (separate issue, major?)
3) Make really sure that both the change record and the beta16 release notes call out that this could happen to D8 sites w/ APC and what to do about it.

Needs work for #1.

webchick’s picture

Oh, another thing that doesn't seem to work is drush cr. I guess it doesn't clear APCu cache as it goes.

webchick’s picture

In additional hilarity, drush cr could never work, because it's clearing the CLI cache and not the Apache cache. ;) /via @webflo

We tested this with ./php -r "apcu_clear_cache();" directly.

webflo’s picture

1) rebuild.php needs to be fixed because it's still pointing to /vendor/autoload.php after this patch (should be /../autoload.php)
2) Also need automated tests of rebuild.php of any kind (separate issue, major?)

I think we can do both in one issue. Created #2575267: Add test coverage for rebuild.php. I am gonna work on it during the extended sprint.

Mile23’s picture

So what *should* happen is that you solve this by typing composer install, and it calls the same code that's used by rebuild.php to uncachify some stuff, particularly APC. And it should also be called by update.php as a matter of course.

So the way forward is:

  1. Refactor the functionality of rebuild.php into some modular code.
  2. ...Which must not be cached. :-) Or at least immune to being moved around.
  3. Which is tested.
  4. Call it from rebuild.php.
  5. Call it as part of the build process in composer.json to reset the caches.
  6. Call it from update.php as well.

How much of that is in scope here? Not enough. There should be another issue and this one should be postponed on it.

hussainweb’s picture

I just did a round of manual testing as per #169.

  1. Install latest HEAD using browser.
  2. Saw that site is working.
  3. Apply the patch in #166.
  4. Apply the fix for rebuild.php in #2575267-3: Add test coverage for rebuild.php.
  5. Saw the same exception as webchick reported in #169.
  6. Update settings.php to add $settings['rebuild_access'] = TRUE;.
  7. Accessed core/rebuild.php in browser.
  8. Saw that site is working fine.
  9. Reverted the patches.
  10. Saw the same exception.
  11. Ran core/rebuild.php in browser (rebuild_access is still TRUE).
  12. Saw that site is working fine.

We should note that reverting the patches and rebuild works because rebuild loads the autoloader within core/vendor. The fix is still required.

Since the fix for rebuild.php is in #2575267: Add test coverage for rebuild.php, should we postpone this on that? Or should we bring in the fix here and deal with the tests in that issue? I have no strong preference because there are pros and cons on each side. If we bring the fix here, we can commit this quicker but doing it there helps us preserve git history.

webflo’s picture

I created #2575495: Invalidate APCu Class Loader automatically if necessary to deal with composers autoload and apcu.

donquixote’s picture

Mile23’s picture

In #2575495: Invalidate APCu Class Loader automatically if necessary #39 there's a way to deal with the issue of ApcClassLoader getting confused when you move the vendor directory (as you might with this patch).

I've folded that in here, because it solves the immediate problem here. There are other concerns it doesn't solve, but those are out of scope in this issue.

See the interdiff for the details.

Using this technique, we overcome the manual test errors in #169, repro'd in #174, so that if you have a Drupal installed with APC, you can just pull the core repro and everything works.

Mile23’s picture

Status: Needs work » Needs review

Ewps. Forgot this.

Also, any clues on how to make a patch that isn't 35 MB would be appreciated. :-)

webflo’s picture

You have to use git diff -C -M.

Mile23’s picture

I think my previous patch broke the testbot, so let's try again with -C -M.

webflo’s picture

Rerolled the patch. The patch is bigger than because i run "composer update --lock" from repo root.

bojanz’s picture

Status: Needs review » Reviewed & tested by the community

We're good to go.

webflo’s picture

Patch in #181 was corrupt.

Mixologic’s picture

/me wonders why #181 passed... :/

tstoeckler’s picture

Re #184:
@webflo killed the test run before it finished.

https://www.drupal.org/pift-ci-job/43543 shows that no test results came back, so the "All classes passed!" (which leads to the green color) is theoretically correct, but it really means "No classes passed!" as well. I have no idea where the "14,121 pass" in the summary here came from.

I also saw the actual fatal in the Jenkins output a minute ago, but I can't find it right now. Very strange! In any case that's a DrupalCI issue.

webflo’s picture

@Mixologic: #181 >> https://www.drupal.org/pift-ci-job/43543 >> https://dispatcher.drupalci.org/job/default/18834/consoleFull Search for "Drupal\system\Tests\System\HtaccessTest"

webchick’s picture

K, repeating steps from #169 now that #2575495: Invalidate APCu Class Loader automatically if necessary is in.

  1. drush si against latest HEAD
  2. Log in as admin, load the home page in my browser.
  3. Apply patch.
  4. Reload the page.
  5. BAM. Fatal error.
    Warning: require(/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php): failed to open stream: No such file or directory in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    
    Fatal error: require(): Failed opening required '/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php' (include_path='.:/Applications/DevDesktop/common/pear:/usr/lib/php') in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    
  6. Went to rebuild.php. Fatal error:
    Warning: require_once(/Users/webchick/Sites/8.x/core/vendor/autoload.php): failed to open stream: No such file or directory in /Users/webchick/Sites/8.x/core/rebuild.php on line 23
    
    Fatal error: require_once(): Failed opening required '/Users/webchick/Sites/8.x/core/vendor/autoload.php' (include_path='.:/Applications/DevDesktop/common/pear:/usr/lib/php') in /Users/webchick/Sites/8.x/core/rebuild.php on line 23
    
  7. Ran drush cr. Reloaded home page. Same fatal error:
    
    Warning: require(/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php): failed to open stream: No such file or directory in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    
    Fatal error: require(): Failed opening required '/Users/webchick/Sites/8.x/core/vendor/symfony/http-foundation/Response.php' (include_path='.:/Applications/DevDesktop/common/pear:/usr/lib/php') in /Users/webchick/Sites/8.x/vendor/symfony/class-loader/ApcClassLoader.php on line 114
    

Ummmm.... ?

webflo’s picture

Include path in rebuild.php was wrong.

chx’s picture

rebuild.php should put up a message on screen , before it tries anything urging ppl to up the deployment indicator in case it dies. drush should nuke the apcu classloader on cr. Just ideas to avoid a registry like situation.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Ok, repeating steps #187...

6. Now instead of a fatal error, it kicks me back to home page with the same fatal error. Not helpful at all, but at least not more fatal errors. :)
8. After manually specifying $settings['deployment_identifier'] = '8.0.0-beta16'; in settings.php, everything works great. The hypothesis therefore is that none of this monkey-patching will be necessary for "real" users of beta16, since a) they didn't have a deployment_identifier to begin with, so it's obviously going to be different, and b) it'll be on a stable release.

Rebuild.php could really use a whole round of "UX" work on it. In addition to what chx says in #189, the variable to turn it on is not even documented in settings.php, and it's confusing as crap that the "r" part of drush cr apparently doesn't invoke the full range of what you'd expect rebuild to do.

Nevertheless, none of that has anything to do with this issue, and the sooner in front of beta16 this is committed, the more time we have to suss out problems. Therefore!

Committed and pushed to 8.0.x. Thanks a LOT, folks!

Mile23’s picture

Status: Fixed » Needs work

We see BAM in #187 and #190 because a) #2575495: Invalidate APCu Class Loader automatically if necessary doesn't actually solve it, and b) my fix in #177 didn't make it into the reroll.

This will continue to affect everyone who pulls the repo until this is fixed.

Apply the interdiff in #177 and try again.

yched’s picture

WOOOOHOOOO !!!!

webflo’s picture

Status: Needs work » Fixed

@Mile23: Please open a follow-up for #191.

Mile23’s picture

As per IRC chat no need for follow-up. It only really affects devs who can figure out to restart Apache.

But durn I felt really clever for figuring it out. :-)

  • webchick committed 3b742fd on 8.0.x
    Issue #2380389 by webflo, Mile23, davidwbarratt, timmillwood, hussainweb...

The last submitted patch, 177: 2380389_177.patch, failed testing.

The last submitted patch, 180: 2380389_180.patch, failed testing.

MKorostoff’s picture

Woohoo! Congrats guys! This is a big win!

jibran’s picture

  • Follow-up: Get rid of autoload.php, because the autoloader is always in vendor/autoload.php
  • Follow-up: Composer manager could manipulate /composer.json. Less specific login in the composer manager module.

Have we created these?

hussainweb’s picture

The last submitted patch, 181: 2380389-181.patch, failed testing.

The last submitted patch, 183: 2380389-182.patch, failed testing.

claudiu.cristea’s picture

Until this, I used to run a specific phpunit test from core/ directory with:

$ ./vendor/bin/phpunit --filter SomePhpUnitClassTest

or all tests:

$ ./vendor/bin/phpunit

Now, running the same commands from Drupal root, both are showing only the help text of phpunit.

What's wrong?

claudiu.cristea’s picture

It seems that is working from core/

$ cd <DRUPAL_ROOT>/core
$ ../vendor/bin/phpunit --filter 'SomePhpUnitClassTest'

Maybe related to autoload?

Mile23’s picture

You have to say ./vendor/bin/phpunit -c core to pick up phpunit.xml.

Status: Fixed » Needs work

The last submitted patch, 188: 2380389-188.patch, failed testing.

webflo’s picture

Status: Needs work » Fixed
Wim Leers’s picture

#205: thanks for that, added it to the CR: https://www.drupal.org/node/2574533.

chx’s picture

I also updated https://www.drupal.org/node/2012184 to say

To run tests, change into the core directory and then run ../vendor/bin/phpunit, you might want to limit to your group (--group Breakpoint), see -h for other options. You can also integrate it with IDE's like PHPStorm. Using the Simpletest UI is not recommended as it is not well integrated (and it never will be). Alternatively, from the Drupal root dir ./vendor/bin/phpunit -c core --filter SomePhpUnitClassTest.

yched’s picture

Side note : the CR has an unfinished sentence : "core/composer.json gets merged on runtime into the root composer.json with" ;-)

Mile23’s picture

Just finished that sentence.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Novitsh’s picture

@chx I also updated https://www.drupal.org/node/2012184 because it was still assuming that the vendor folder was in core/.