Skip to content
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

Documentation on how to distribute re-usable task #532

Closed
pbuyle opened this issue Jan 31, 2017 · 14 comments
Closed

Documentation on how to distribute re-usable task #532

pbuyle opened this issue Jan 31, 2017 · 14 comments

Comments

@pbuyle
Copy link

pbuyle commented Jan 31, 2017

I'm looking for guidance/documentation on how to distribute common re-usable command?

For an example of re-usable command, see the https://gist.github.com/pbuyle/79c8fa1215e93926813f9e6a27af7ff2#file-robofile-php-L129. This pantheonPush command can be re-used as-is on multiple of our projects and by others so we would like to be able to refactor into a re-usable something.

Currently, the only option seems to be to make it into a task. If so, does this task need to use the TaskAccessor trait and then use $this->task(Foo::class, $a, $b)? How about collections inside the task, should they be build with $this->collectionBuilder()?

@greg-1-anderson
Copy link
Member

If a standalone command is best used as a command, then you could package it as a standalone application. See Robo as a framework.

In the case of standalone applications that are for use with Pantheon, you could package it as a Terminus plugin. See the Terminus Build Tools Plugin as an example. This plugin is used to test the example drops-8 composer project.

Distributing a collection of tasks is another possibility. The primary documentation on this is in the extending section. More documentation here would probably be useful; let me know if there are parts that are unclear. For an example, see the Robo Drush tasks.

@pbuyle
Copy link
Author

pbuyle commented Jan 31, 2017

I already started a project iwth Robo tasks to execute Terminus commands, see https://github.com/FloeDesignTechnologies/robo-pantheon.

Your suggestion to package the command in a Terminus trigger and interesting question. Should a command intended to be used to deploy a built site to Pantheon be a Robo command (in the project's RoboFile) or a Terminus command (in a plugin)?

@greg-1-anderson
Copy link
Member

@pbuyle I think that any of a Robo command (in a RoboFile) or a standalone app (Robo as a Framework) or a Terminus command (plugin) are all valid options, depending on how you plan on using them. Note that since Terminus is based on Robo, the implementation of any of these options is going to be fairly similar. I'd recommend going with a Terminus plugin if your command calls a lot of Terminus commands, and something else if it doesn't.

See the example drops-8 composer project for an example of how to use a Terminus plugin from a CI script.

@amenk
Copy link
Contributor

amenk commented Mar 3, 2017

I am experimenting with installing my tools (including robo) using composer global require consolidation/robo - it should be possible to load custom commands that way I think with an additional require? Then I am making a meta package which requires that all. https://packagist.org/packages/imi/itools

@greg-1-anderson
Copy link
Member

I strongly recommend against using composer global require to install commandline tools. Please use cgr instead. See Fixing the Composer Global command.

I was considering making a simple plugin scheme for cgr similar to your idea above -- a simple way to require additional components to be installed with some global package. I have not started on this yet. It should work to use cgr to install your meta package.

@amenk
Copy link
Contributor

amenk commented Mar 6, 2017

Thank you, I think that helps a lot.
Is there already working being done on a Robo interface to cgr ? (CgrTask)
But concerning distributing additional robo tasks, we would need to require "into" the robo space, right?

@greg-1-anderson
Copy link
Member

@amenk Yes, correct. External robo tasks must be required into the same project that Robo core is. Then, to use them, you also need an appropriate use statement in your RoboFile.

I don't think anyone is making a cgr task. You could always just use taskExec as well, but an external cgr task would be useful.

Terminus supports lightweight plugins, which are ideal when the code you'd like to add does not itself have any dependencies (beyond the dependencies of the plugin project). I have been considering adding this capability to Robo, but I'm undecided, and haven't discussed with @DavertMik. First step there would be to factor the code out of Terminus and into some project such as consolidation/lightweight-plugins.

The other option for plugins is embedded composer, but this design turned out to be complicated and hard to maintain. It is now deprecated by its author.

@amenk
Copy link
Contributor

amenk commented Mar 6, 2017

What I am having in mind is a Robofile which pulls additional tools (via cgr) and additional tasks (via composer + use) automatically. But as they have to be in the use statement, the robofile will not be able to run.

Other possibility is still to create a monolithic robo-fork file (we called irobo) with our specific task set. In this case a robo selfupdate command just like in composer would come in handy.
The additional tools would be pulled via cgr.

What's also interesting is the plugin system of https://github.com/pre-commit/pre-commit - it pulls plugins via git. But as we are in the PHP world, composer would be a much better way of doing this.

@greg-1-anderson
Copy link
Member

Lightweight plugins might partially meet your use-case. A lightweight plugin uses the Composer autoloader via a direct call to autoload all of the classes in the plugin at discovery / load time. If a command inside the plugin is called, then the plugin's autoload.php file is loaded. This allows each plugin to extend the primary application's dependencies, but does not risk loading dependencies from two different plugins at the same time. The upshot for your use-case is that tasks defined in plugins could not add dependencies.

Your monolithic robo-fork is the current best-practice way of adding tasks: make your own app that requires all of the dependencies that it needs, and use your external tasks in your RoboFile.

Robo selfupdate would be useful to have in robo core, imo.

@greg-1-anderson
Copy link
Member

All of this is not to discount my original idea above to use cgr as a plugin manager; there just isn't any code for that yet, so it's a little more nebulous than some of the other options. Might work better for some use-cases, though.

@amenk
Copy link
Contributor

amenk commented Mar 31, 2017

Do you have any new thoughts about this or pointers to tickets? I probably might continue with the monolithic fork.

@greg-1-anderson
Copy link
Member

greg-1-anderson commented Mar 31, 2017

Yes, there have been some new thoughts about this, but no new issues. Efforts have been focused on configuration in #552, which I just merged.

At Drupal Stanford Camp, I had a discussion with @nerdstein about robo tasks and plugins. He maintains a tool called Bild; his intention is to refactor it into Robo tasks that can be loaded as plugins. For this, we will need to build a plugin manager. 😄

Lightweight plugins from Terminus are not going to work for this. The idea with lightweight plugins is that dependencies only load for one plugin at a time, and this is only done for plugins that implement a command, at the time that one of its commands is called. We need to use plugins to provide tasks, which means that every plugin will need to have its dependencies loaded, as any given command may use tasks from multiple plugins.

For this, we are considering building a plugin manager based on cgr, as I previously mentioned. The general idea here is that an application could declare its plugin types in the extra section of its composer.json, and cgr would make note of this information and copy it somewhere else when an application is installed. If you subsequently use cgr to install a project that is one of these registered plugin types, then cgr would install the project with its owning application (e.g. robo-task with Robo), rather than installing it in its own directory.

This methodology would be complimented with a plugin manager library, that applications that use Robo as a framework could require. Using the plugin manager, an application could provide a mechanism for its users to install plugins defined by a different application. For example, Bild may provide plugins that, while intended for use with Bild, are actually defined as generic robo-task plugins that may be used by other Robo applications. If installed via cgr, these plugins would be installed in Robo, but if installed via Bild, then they would be installed in Bild.

This would only work for applications that are installed via cgr or composer require; installling a plugin is intended to be implemented simply as a composer require in the appropriate installation directory. No compatibility with phars is planned. If this is desired, see the previously-mentioned embedded-composer.

No code exists for any of this at the moment, so at the moment your best bet is either Robo as a framework, or a monolithic fork would be your best bet. The "monolithic fork" basically boils down to manually doing the operations that the plugin manager will do.

@amenk
Copy link
Contributor

amenk commented Dec 1, 2020

@greg-1-anderson I believe there was much work done into this direction in robo 2.x and robo 3.x

Currently we maintain a monolithic fork of robo 1.x and compile or own tasks into the .phar

We know we can add additional tasks using composer, but only if the project ist already setup.
What is the current way with recent robo versions to accomplish additional tasks, when robo is also used to set-up a project.

I think our best way would be to use cgr, just wondering if there are any news concerning this in v2 / v3

@greg-1-anderson
Copy link
Member

No changes in v2. I was imagining improvements to task collections et. al. in v3, but I don't know that I will get to it, so perhaps I will ship a v3 stable soon and leave that work for v4.

Will probably get PHP 8 sorted before doing that, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants