Drush 5 is broken in D8 now that this patch landed: http://drupal.org/node/1497230.

drupal_container() is causing similar issues elsewhere, and while they are being worked on in issues like http://drupal.org/node/1511482, the reason it's breaking is more drush's fault IMO.

What happens is we call dt() in drush_bootstrap(), which checks if t() is available to use. We check that by checking for the function itself, and then if the Drupal version is greater than 7, we leave it at that. The problem is, t() now calls drupal_container() to get an instance of the language class, and that class doesn't get registered until drupal_language_initialize() is called.

We should just improve our check to make sure we've bootstrapped past DRUPAL_BOOTSTRAP_LANGAUGE before calling t(). Makes more sense either way, and it fixes this issue.

Comments

robloach’s picture

Status: Active » Needs review

t() shouldn't be available without DRUPAL_BOOTSTRAP_LANGUAGE, so this one does make sense. Thanks! I'll leave needs review in case someone has more time to do a proper review of it. As you mentioned, we will be doing some initial lazy-instantiation stuff on this once #1511482: Bootstrap for the Dependency Injection Container is in. But this patch does seem sound.

moshe weitzman’s picture

I and others worked hard to make t() always safe to call in Drupal 7 and that has now regressed in D8. Drush is going to wait for Drupal8 to fix this.

msonnabaum’s picture

Sure, but is there ever a point to calling t() before language has been bootstrapped? Core bugs aside, this just seems more sensible.

FWIW, I ran into a very similar issue earlier this week trying the variables.inc patch: http://drupal.org/node/1193396.

We call t() earlier than Drupal does, so this is likely to keep coming up.

neclimdul’s picture

If I might poke this issue a bit, the only real problem seems to be the autoloader isn't setup. Can we just add drupal_classloader(); fairly early to the d8 bootstrap and call it a day. Its statically cached and it'd be a single call so its basically free.

Alternatively, we could poke core to add the call inside the static cache of drupal_container(). Either way, seems like a much simpler fix and fits with the re-factoring Rob is doing of the language system.

attiks’s picture

FYI: I ran into the same problem with Barracuda and the patch above is working (Drush 4), see #1459362: Add support for Drupal 8 sites since /core patch

moshe weitzman’s picture

Status: Needs review » Closed (won't fix)

I want this fixed in Drupal core. Drupal developers should not have to think when they can call t() and when they can't. And yes, there is a point to calling t() before the language system is available. In D7, you got translation for settings.php string mappings in this case.

neclimdul’s picture

Ok, Is there a core issue to follow up on?

Just a note, the fix I would suggest for Drupal core is the same I suggested here though which is registering the auto-loader as early as possible and using the container to bootstrap as needed. This fits with the DI container approach which decreases the tight coupling of bootstrap levels with functions like t() and should decrees the fragility of the bootstrap in general. Getting Drush on-board with the end goal early should decrease having to do this for each core bootstrap change during the release.

moshe weitzman’s picture

I don't know of a specific issue. effulgentsia posted a core patch to #136 at #1497230-135: Use Dependency Injection to handle object definitions . He mentions a further change which would make it always safe to call t() which would be ideal, if we can pull it off.

effulgentsia’s picture

Status: Closed (won't fix) » Active

#1497230-136: Use Dependency Injection to handle object definitions is now committed to core. As per that comment, t() now only fails if:
- You haven't bootstrapped to DRUPAL_BOOTSTRAP_CONFIGURATION (the very first bootstrap level), and
- You haven't called drupal_classloader() yourself.

I think we need to do one of the following:
- Fix Drush to not call t() if we haven't even bootstrapped configuration.
- Make Drush call drupal_classloader() if it wants to call t() before bootstrapping configuration. I don't think this is ideal since drupal_classloader() has conditional logic based on settings.php.
- In core, separate bootstrap.inc into a file per bootstrap level, and move functions requiring a certain level into the appropriate file. That way, Drush will continue to work by just checking function_exists('t'). I think this would be good in theory, but I'm not crazy about needing an extra 6 or so includes for every request.

moshe weitzman’s picture

Is there some reason why t() can't just return an untranslated string when called too early? Thats what happens in D7.

clemens.tolboom’s picture

#1540110: Drush calling t() before D8 dependency injection construct is available is closed as a dup of this issue ... (x<y) doh ... it has a patch too which keeps the theme-function check ... which I guess is a D6 thing which we should keep right?

effulgentsia’s picture

Is there some reason why t() can't just return an untranslated string when called too early? Thats what happens in D7.

D7 doesn't make as much use of autoloaded classes during bootstrap. As far as I know, D8 is moving towards autoloaded classes for as much of bootstrap as possible (that's nowhere near complete yet, but there's a lot of interest in that). So we should consider this t() issue to be representative of maybe more to come. In general, which functions do we want to be callable prior to having a class loader? That's a question that should be raised in the core queue. I haven't yet opened a dedicated issue for that, but it's just now come up in #1569456-11: Move replace fix_gpc_magic() with a hard requirement for magic quotes to be disabled.

andypost’s picture

StatusFileSize
new537 bytes

Is there some reason why t() can't just return an untranslated string when called too early? Thats what happens in D7.

No reason to use t() while core is not bootstrapped yet

moshe weitzman’s picture

Status: Active » Closed (won't fix)

see my prior comments.

webchick’s picture

zendoodles has made a patch that does what moshe asks for over at #1590182: Return untranslated string when t() is called too early in the bootstrap phase..

sun’s picture

Status: Closed (won't fix) » Active

Pasting from #1590182: Return untranslated string when t() is called too early in the bootstrap phase.:

Fatal error: Class 'Drupal\Core\DependencyInjection\ContainerBuilder' not found in ...xxxxxx/drupal/core/includes/bootstrap.inc on line 2354

Q: What does this error mean?

A: PHP is not able to load the class Drupal\Core\DependencyInjection\ContainerBuilder.

Q: Is it related to t() or the language system?

A: No. PHP is not able to load the class Drupal\Core\DependencyInjection\ContainerBuilder.

Q: Does Drush properly account for the new bootstrap phases in D8?

A: Dunno. DRUPAL_BOOTSTRAP_CONFIGURATION was added as very first bootstrap phase, which calls drupal_classloader(). Was it?

Q: Does Drush initialize the PSR-0 class loader in Drupal core or implement its own?

A: Dunno. grep -i 'ClassLoader' ./* on drush yields no results. Does it?

ZenDoodles’s picture

Status: Active » Reviewed & tested by the community

This is mostly the same as my patch from #1540110: Drush calling t() before D8 dependency injection construct is available which has been working for me since May 2. Can we please commit it already?

Edit: actually, I think I prefer the one over there...

sun’s picture

Status: Reviewed & tested by the community » Active

All of the patches I've seen so far are only trying to hide the symptom.

tim.plunkett’s picture

Status: Active » Needs review
StatusFileSize
new11.66 KB
new796 bytes

Because we're doing a core sprint tomorrow, and everyone will ask why Drush "doesn't work" with D8, here is the patch I've been using. It's a modified version of the one linked in the duplicate issue. I'm also attaching a patched version of the entire file (includes/output.inc), just so people can Get Stuff Done tomorrow.

sun’s picture

StatusFileSize
new490 bytes

Just to prove what I'm saying... use this instead.

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Duh, I missed #16 and only saw #17. #20 works just fine.

#1590274: Drush does not work from within a subdirectory (e.g. /core) in Drupal 8 is an unrelated follow-up.

moshe weitzman’s picture

Status: Reviewed & tested by the community » Fixed

Committed #20. I caved.

effulgentsia’s picture

IMO, the committed fix is a good one for now. I also opened a core issue to tackle the broader scope problem of bootstrap functions that depend on classes: #1593826: Split bootstrap.inc into functions available before/by settings.php and functions available after there's a class loader. If something along those lines gets committed, then #20 can be reverted.

Status: Fixed » Closed (fixed)

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