-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Load Drush services for themes as well as modules. #3089
Load Drush services for themes as well as modules. #3089
Conversation
src/Drupal/DrupalKernel.php
Outdated
// Also add Drush services from all modules | ||
// Also add Drush services from all modules & themes. | ||
$extensions = $this->getConfigStorage()->read('core.extension'); | ||
$this->moduleList += isset($extensions['theme']) ? $extensions['theme'] : []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this is prudent. This field is not only used by Drush, but is used throughout Drupal. Adding the themes to the module list might have unintended consequences. It would probably be much better to simply build a list of themes in local variables, and then have a separate loop over $theme_filenames
to call addDrushServiceProvider
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm... yes that does make sense; I wasn't considering that - I was thinking this only affects Drush. Ah well... quite easy to modify. I'll swap over to local/adjust the implementation. A bit more code/close to duplication but seems very worth it to not be altering core data without tons of testing
thanks for the review :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could have less duplication by merging the module list and theme list, but I don't think you should do that either. You're not supposed to ever have a module and a theme with the same name, but I've seen that violated before, so best keep the lists separated (unless Drupal is actually preventing that now -- have not tried recently).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I've seen that before too, which should have made me think about keeping it separate
src/Drupal/DrupalKernel.php
Outdated
$listing->setProfileDirectories($profile_directories); | ||
|
||
// Now find themes. | ||
$this->moduleData += $listing->scan('theme'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment - not sure that it is safe to modify $this->moduleData
like this.
This is great, thanks! I'm not 100% sure about my comments, but some of the field access here looks potentially unsafe. If it would work equivalently to use local variables in those places, that would be preferable. |
To facilitat this, also have to add the theme namespaces to the autoloader.
src/Drupal/DrupalKernel.php
Outdated
@@ -60,6 +63,7 @@ protected function initializeContainer() | |||
if ($this->shouldDrushInvalidateContainer()) { | |||
$this->invalidateContainer(); | |||
} | |||
$this->classLoaderAddMultiplePsr4($this->getModuleNamespacesPsr4($this->getThemeFileNames())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be added somewhere to add the theme folders to the autoloader. I did a bit of investigating and I think this is the best spot but it's the item I'm least sure about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this happen as a side effect of adding the themes to the module list before?
Does the active theme have its autoloader added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, didn't need it before because, one of the uses of $this->moduleList
was propagating the autoloader. (that line is basically copy & paste but with module changed to theme)
All enabled themes get their autoloader added by this - in Drupal core, themes don't get added to the autoloader at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is the hang up for me. I'm worried about the unpredictable consequences of Drush adding theme classes that Drupal does not add to the autoloader. Maybe this is no big deal; each theme should be uniquely namespaced, and if no one references the class, then it should not matter if it's autoloadable. I am concerned by the fact that this happens all the time when using Drush, whether or not a theme command is being executed. If this did cause a change in behavior, it could be really difficult to track down.
It might be safer to only add the autoloader when a theme command is executed. This is what the Terminus plugin mechanism does. The consequence of doing something similar for themes is that theme commands would have access to all of the classes defined in the theme, whether or not the theme was enabled, but hooks in the theme only have access to the command / hook classes in disabled themes (but should still have access to all classes in the enabled theme).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm... I'm 95% sure I can simply implement that with a bit of copy/paste from there and editing. Investigating, thanks :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Terminus has an autoload file that it can include, which is probably not going to be the case here. You may need to instantiate your own class loader. The Composer class loader works well in this capacity. I've done so successfully in the past, but at the moment I can't quite remember where, or I'd provide a link.
Always great to find out there is a working patch for problems you come across. We really need this patch for the ZURB Foundation theme as creating subthemes currently does not work. More info at : https://www.drupal.org/node/2920472 I can confirm that the patch works. Any possible ETA on when this could be merged? Perhaps a beta-9 release? |
The PR wont be merged as is. The next step is in #3089 (comment) |
Further narrow the namespace to only Drupal/theme_name/Commands.
Finally got some time today to work on this more. I didn't end up implementing a runtime autoload function for the theme namespaces. A quick investigation revealed that was going to be more complicated than I was first suspecting.
I believe this should reduce the risk of accidental collisions sufficiently as well as reducing possibility for accidental effects. Anyways, I look forward to hearing your thoughts on whether that resolves your concerns. |
if ($this->themeNames) { | ||
return $this->themeNames; | ||
} | ||
$extensions = $this->getConfigStorage()->read('core.extension'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets use a Drupal API like \Drupal::service('theme_handler')->listInfo();
or system_list('theme')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't do that unless we load core/includes/module.inc. At this point in the bootstrap process, it isn't yet which means system_list()
is unavailable and ->listInfo()
uses it.
src/Drupal/DrupalKernel.php
Outdated
@@ -203,4 +214,77 @@ protected function addDrushServiceProvider($serviceProviderName, $serviceYmlPath | |||
$this->serviceYamls['app'][$serviceProviderName] = $serviceYmlPath; | |||
} | |||
} | |||
|
|||
/** | |||
* populates theme data on the filesystem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start with upper case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
* @see Drupal\Core\DrupalKernel::moduleData(). | ||
*/ | ||
protected function themeData($theme_list) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too clear why we need this code. Why is iterating over all enabled themes sufficient? Are we wanting to catch the case where Drush integration is in the parent thee? What does simpletest have to do with anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've simplified this slightly. This is necessary to populate the Drupal path cache so that drupal_get_path() and similar function work for themes. I think we can remove the simpletest stuff as we're not loading themes for testing - it is in the core Drupal\Core\DrupalKernel::moduleData()
but reviewing it, we don't need it for this use case, so removed.
@weitzman or @greg-1-anderson either of you have any time to give this a re-review with those changes? |
I took a quick look and still dont feel especially comfortable with this. I'm very sensitive to maintenance/complexity costs these days. Lets see what @greg-1-anderson thainks. |
Folks wanting this should work on modernizing Drupal's theme system. I'd like to highlight catch's excellent comment on this issue. |
i'm going to cll this 'wont fix'. please work in drupal core to resolve this. |
Keep forgetting to comment back. I totally understand wanting to minimize stuff like this diverging from Drupal loader/maintainability etc and makes sense. Thanks for all the review and discussion. When I have time I'll check out that issue on the core queue you linked, thanks |
In Drush 8.x themes could define Drush commands as well as modules. In 9.x, this is no longer the case.
This patch re-implements that.