Many modules implement Drush commands and Drush provides a large number of hooks for each command. It'd be great to be able to specify when a given recipe should be called automatically within its spec. So, a recipe could specify that it should run before or after one or more commands. For example, automatically trigger a backup recipe before updating a site's modules and other potentially dangerous operations, or run a security recipe whenever a module is enabled.
When enhancing or customizing Aegir workflows, I commonly build something similar to recipes directly as a series of hook implementations in a custom Drush extension. Being able to specify a particular hook, and even ordering of tasks within a single hook via a weight-like mechanism would be very handy when building up complex automated workflows.
Comments
Comment #1
btopro commentedLove this idea. Could you point to an example in AEgir that has a ton of hook chaining going on so I could try and work up an example JSON spec that could accomplish that? Most of my immediate needs are simple (go run these 4 commands against whatever the initial target is) but it's cause I don't have immediate need for more difficult things like migration routine. Would be great if this could be an overlapping piece between our efforts.
Comment #2
btopro commentedComment #3
ergonlogicHere's an example of an 'update' task in Aegir, that essentially runs 'drush updatedb'. In a drush_hook_COMMAND_pre_validate() implementation, we take a backup first, so that we can restore in a drush_hook_COMMAND_pre_rollback() implementation should the update fail.
We use the pre_validate hook here to leave room for a pre_COMMAND hook implementation to come after the backup but before updatedb, so that we can (in a separate extension) run a 'git pull'. This pull request will allow for altering the order of execution of implementations of the same hook, which is currently resolved alphabetically (iirc). With that merged, we can move our backup to drush_provision_tasks_extra_pre_provision_update() and implement another drush_hook_pre_provision_update() with our git code, along with the required hook_drush_invoke_alter() to get the order right.
As for the spec, I'd suggest an element that contains a simple array of command names to react to, which would assume the 'post' hook. If running in a different hook is required, the command is replaced by an array with more specifics. Something like:
Comment #4
btopro commentedComment #5
btopro commented2.0 spec
Comment #6
btopro commentedhook_drush_recipes_pre_cook_alter -- fires before a recipe list is executed so this could be used to inject new recipes automatically
hook_drush_recipes_system_recipe_data_alter -- fires after recipes are loaded from the file system so you could look at them and react
*the real gem*
hook_drush_recipes_command_invoke_alter -- fires before every drush command in the block chain. This allows you to react to other commands that are invoked in other recipes automatically. You could (for example) do a bunch of git commands or additional advanced processing whenever a command is noticed.
hook_drush_recipes_post_cook_alter -- fires after a recipe fires so you could look back through which recipe it was / commands it had and react to them