acquia / blt

Acquia's toolset for automating Drupal 8 and 9 development, testing, and deployment.
https://docs.acquia.com/blt/
GNU General Public License v2.0
442 stars 394 forks source link

Allow custom commands to use autoloader #1793

Closed thom8 closed 5 years ago

thom8 commented 7 years ago

My system information:

We are looking to export our custom Commands and Hooks so they can be shared between projects

At the moment custom Commands and Hooks are restricted to ./blt/src/* as defined here.

So the autoload configuration here seems to be ignored.

Is it possible to make use of the autoloader via the Acquia\Blt\Custom\Commands / Acquia\Blt\Custom\Hooks namespace for any custom commands or hooks?

grasmash commented 7 years ago

Yeah, I think we basically just need to look in vendor for files in matching a certain filename pattern or belonging to a certain namespace. We could also try to use reflection to find anything that implements a particular interface.

@greg-1-anderson any suggestions on the best way to discover command files provided by composer packages?

thom8 commented 7 years ago

@grasmash I think it would be OK to assume another package would need to declare the namespace via the autoloader -- https://github.com/acquia/blt/blob/8.x/composer.required.json#L33

This should make it easier than traversing the vendor directory.

The registered paths are available in vendor/composer/autoload_psr4.php

thom8 commented 7 years ago

Something along the lines of >>

    $loader = require 'path/to/vendor/autoload.php';
    $prefixes = $loader->getPrefixesPsr4();
    $paths = isset($prefixes['Acquia\Blt\Custom\\']) ? $prefixes['Acquia\Blt\Custom\\'] : [];

Will give you the list of paths which declare the Acquia\Blt\Custom\ namespace.

greg-1-anderson commented 7 years ago

Terminus implemented a plugin mechanism that is not based on Composer; I have not yet implemented a plugin mechanism that works with resources in the vendor directory, although I think it would be a good idea to do so.

@thom8's suggestion seems reasonable. Is getPrefixesPsr4() a public Composer API? It's public, but undocumented.

thom8 commented 7 years ago

This could also be handy for Robo to specify a custom path to a project RoboFile.php via a namespace or direct classmap.

nathandentzau commented 6 years ago

Hi,

Is there any status update on this issue? We'd like to register commands from a composer dependency.

greg-1-anderson commented 6 years ago

There has been no feedback in a while on https://github.com/consolidation/Robo/pull/604. If someone wanted to use this mechanism, we could add it to Robo.

greg-1-anderson commented 6 years ago

There's new activity in https://github.com/consolidation/Robo/issues/670, for those tracking this issue.

greg-1-anderson commented 6 years ago

Please see the PR: https://github.com/consolidation/Robo/issues/671

danepowell commented 5 years ago

@grasmash started a branch to work on this more than a year ago. I'm not sure if it's still relevant or not. I've temporarily ported it to my own fork just in case it's still needed so that I can clean up stale BLT branches: https://github.com/danepowell/blt/tree/issue-1793-plugins

greg-1-anderson commented 5 years ago

There is a version of this in the most recent stable version of Robo.

mikemadison13 commented 5 years ago

closing due to inactivity

dpagini commented 5 years ago

I know this is a super old issue... I think it's a great idea and would be cool to allow other packages to provide BLT functionality. This would, if I'm understanding correctly, provide a way to extend BLT with other libraries, right? So using some recent activity I've seen with BLT, there could be a BLT-Lando, BLT-Docksal, BLT-DDev, etc that bring in functionality directly to BLT, but the main package doesn't have to worry about maintaining those. Another example might be CI tools... we have Pipelines/Travis... but maybe another library could provide CircleCI integration. Just some ideas.

greg-1-anderson commented 5 years ago

There is a Robo plugin mechanism available now. Plugins would just need to declare their command files in a well-known namespace, e.g. \MyPluginNamespace\BLT\Commands. With just a few lines in BLT, any plugin composer required into the BLT project would have its commands loaded.

dpagini commented 5 years ago

With just a few lines in BLT, any plugin composer required into the BLT project would have its commands loaded.

@greg-1-anderson - what would these few lines look like? Happy to help if I could, but I'm not even sure where to start...

greg-1-anderson commented 5 years ago

@dpagini Here's some documentation on how to use this sort of a plugin mechanism once it is implemented:

https://robo.li/extending/#register-command-files-via-psr-4-autoloading

As for implementing the plugin mechanism in another app e.g. blt, I don't think that's clearly documented anywhere. However, it's very easy -- not a few lines of code, it's just one line of code:

https://github.com/consolidation/Robo/blob/1.4.6/robo#L43

Pick your own namespace, like Blt\Plugin, and then create your plugins to match.

greg-1-anderson commented 5 years ago

Here's one place you could drop that:

https://github.com/acquia/blt/blob/10.0.x/src/Robo/Blt.php#L80

danepowell commented 5 years ago

We could even split out some components of BLT that could be shared or community-maintained:

danepowell commented 5 years ago

I've created a PR for this and would appreciate everyone's review: #3447

@greg-1-anderson the only thing I haven't figured out is what to do with hooks. Commands work great, but BLT also allows users to define hooks that run before or after commands. I'm not sure if hooks are a native Robo feature, or if they are supported as plugins the same way that commands are?