In Aegir land when executing Drush command 'A' we'd like to call Drush command 'B' i.e.

When executing:

drush @alias command-a

We'd like to run:

drush @alias command-b

So we call:

drush_invoke_process('@alias', 'command-b');

But this actually calls something like:

drush --uri=... --root=... command-b

Note that the name of the alias isn't passed through there. In Aegir land we use the name of the current alias extensively, and so we need it passed through to the invocation of the drush command.

I've found a workaround which is to call:

drush_invoke_process('@alias', '@alias command-b');

And then the call is made like this:

drush --uri=... --root=... @alias command-b

Is this okay to do? Is the space in the command name going to cause problems?

All the aliases will be local to the running drush instance.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

moshe weitzman’s picture

Assigned: Unassigned » greg.1.anderson
greg.1.anderson’s picture

How are you checking the alias name today? I presume you are requesting the @self alias, and testing the #name attribute?

I would strongly discourage prepending the alias to the command name; better to adjust Drush to maintain the alias context. Drush does not guarantee the behavior of specifying both --root + --uri with @alias, so your code might accidentally break even in the Drush-5.x branch if you did this. If you did insist on going this way, I would strongly recommend that you contribute tests to insure that the appropriate option (in this case, the alias) is taking priority. If you did this, then you could at least be assured of compatibility with Drush-5. I don't know if we want to sanction spaces in the command name, though.

I would recommend instead fixing this in Drush. There are a few ways this could be done.

One option would be to introduce a new hidden global option, --site-alias, and have drush_invoke_process pass it through. On the receiving end, if --site-alias is specified, Drush will try to load an alias with the specified name; this will always work on the local system, and may or may not work on remote systems. The alias context (e.g. command specific options, etc.) would then be merged in with @self and applied as appropriate. This would be easiest to implement.

Another option would be to POST the entire alias record in drush backend invoke, and use it on the receiving end. This would work remotely and locally, but would interfere with using method GET in backend invoke. There might be consequences to this, so this probably should not be done in drush-5.x.

Finally, drush_invoke_process does know if an alias is being used or not (that pesky first parameter); it could automatically adjust to using the alias name instead of --root + --uri to specify the site, but only for local dispatches.

The last option is probably the most promising, but it's going to take some experimentation, so I'm not sure when I would get to it. I can help review any patches submitted in the interim, though.

Steven Jones’s picture

So, actually it seems that when you use drush_invoke_process with an alias, Drush tries to pull all the options from the alias into the command line, not just --root and --url. This is fair enough, if you're sshing to a remote server, then it's not going to have the alias and thus the corresponding options.
We've got a slightly hacked up version in Aegir 2.x in the moment, that doesn't pull any options in from the alias, instead just adding the alias to the command line. This works perfectly for our use case too.

So I guess we have two perfectly valid use cases, I wonder if you'd accept a patch that added a 'backend option' that told Drush not to 'expand' an alias onto the command line if it's set?

greg.1.anderson’s picture

I think that controlling the behavior of the dispatch through backend options is reasonable. The alias options are added to the alias context early on, but I think it would be easy enough to skip the alias context if so directed by a backend option.

Steven Jones’s picture

Fairly certain this is now a duplicate of: #1613376: how to not explode aliases in drush_invoke_process, will confirm and update.

Steven Jones’s picture

Assigned: greg.1.anderson » Steven Jones
Category: support » feature

Actually, no #1613376: how to not explode aliases in drush_invoke_process just stops the options being validated on the called side, it doesn't stop all the options appearing in the command line, which is a problem for us. Going to look at writing something that skips this.

Steven Jones’s picture

Assigned: Steven Jones » Unassigned
Status: Active » Needs review
FileSize
2.41 KB

Here's my first cut of this.

greg.1.anderson’s picture

Status: Needs review » Needs work

1. If dispatch using alias is true, then you should suppress --root and --uri from the commandline options. Specifying both is ambiguous, and should be avoided regardless of how the current implementation resolves that situation.

2. I would also prefer to not append non-commandname stuff to $command, at least not until the point that the entire command string is composed. Add another variable or parameter or field for the alias so that it can be composed cleanly at the correct time.

3. Finally, if the alias is being passed by name on the command line, it would be good if the options defined in the alias were not transferred to the commandline options.

Edit: Added numbers above to reference below.

Steven Jones’s picture

Hmm...in my testing the root and uri options don't make it onto the command line, do you know where these get added?

greg.1.anderson’s picture

Sorry, I made a mistake in #8; items 1 and 3 are already handled. This is done in your patch by not passing the site alias record to _drush_backend_classify_options, which is where --root and --uri are usually added. I would still prefer to see item 2 implemented by adding the alias as another field of $invocation_options (either by name, or by passing the whole record), with equivalent changes being made to the code that composes the command string. That will keep the code cleaner if we later want to examine / adjust the command name or the alias.

Thanks for working on this; the dispatch command is a lot cleaner when the alias is used. Perhaps it would work to automatically set 'dispatch-using-alias' to TRUE if the site alias record is local ('remote-host' not set) and the record has a '#file' field (indicates that the record is persistent, not dynamically generated). That can be a future improvement in a separate issue, though.

Steven Jones’s picture

Status: Needs work » Needs review
FileSize
4.29 KB

How about this.

greg.1.anderson’s picture

Assigned: Unassigned » greg.1.anderson

That looks great; haven't tested it yet, but should work fine.

It's a pity that Drush expects aliases to be passed in as '@site', but stores them in the alias as 'site'. Fixing that would be a lot of work; maybe in Drush 6.

greg.1.anderson’s picture

Status: Needs review » Needs work

There were 2 failures in the tests:

1) shellAliasesCase::testShellAliasDrushRemote
2) backendCase::testOrigin

These were caused because the new code introduces an extra space in the command strings generated by backend invoke. It's okay to leave the extra space if the tests are adjusted to pass. A test that sets dispatch-using-alias would be nice to have.

greg.1.anderson’s picture

Here's a version where all tests pass; however, I'm not really happy with the comparison code in the dispatch-using-alias test. It might be simpler just to make a unit test that did direct calls to functions in backend.inc, but I wanted to do a functional test that tested loading the alias file through dispatching the command front-to-back. That turned out to be a little messy, but this is most of the way there.

greg.1.anderson’s picture

Status: Needs work » Fixed

Fixed up test in #14 and committed bce076e

Steven Jones’s picture

Assigned: greg.1.anderson » Unassigned

Awesome! Thanks so much.

Status: Fixed » Closed (fixed)

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