I'd love some feedback on this small patch which adds a feature for drush analogous to [alias] in .gitconfig file. That is, one can specify an associative array of "personal" aliases. Code such as below goes into your drushrc file.


$options['shell-aliases'] = array(
  'pull' => '!git pull && drush updatedb',
  'noncore' => 'pm-list --no-core',
  'wipe' => 'cache-clear all --verbose',
);

Then you can call drush pull or drush wipe and magic happens.

Note the first alias above begins with !. Thats a hint to exec() the alias directly. Its just like a bash alias. Git and vi aliases work this way so why not drush.

Todo
-------

  1. shell aliases should probably be a new variable in drushrc files (like $override). they might even merit own file like aliases.drushrc.php. the config file loading code is dense. perhaps greg can help out here.
  2. test shell alias in conjunction with a remote site alias. my hope is that remotely defined shell aliases are honored like local ones.
  3. test with core-cli shell.
  4. unit tests
  5. docs

Comments

greg.1.anderson’s picture

Status: Needs review » Needs work

The idea is very similar to bash aliases, but there are some use cases (e.g. remote execution) that make it worthwhile. This leads me to wonder if we should also support drush @remote !git pull, or something like that, to allow drush to be a thin wrapper around ssh -- just to allow you to use your site alias to specify the machine, username, password, and initial working directory for the remote ssh command. To implement this, a command '!blah' would be expanded to 'exec blah', much as your implementation in #0 expands aliases in-place. We then add a command (perhaps hidden) drush exec that just calls drush_op_system or drush_shell_exec_interactive, as appropriate.

As for the implementation of personal aliases, rather than replacing them in the command arguments, I would recommend inserting them into the drush command list. Each would get its own command entry, the callback would be the same function as drush exec, and the rest of the arguments would go in the command's arguments element. I think that would make it easier to get them working remotely, with core-cli, etc.

That's just an impression, though; I'm not 100% certain.

moshe weitzman’s picture

2. As I hoped, a shell alias that is defined remotely is honored perfectly. So, if you do drush @remote wipe, drush will try to expand 'wipe' locally and if that does not exist, it tries to expand it remotely. I do think we need to support drush @remote !git pull as Greg mentions. How do I determine whether drush_shell_exec_interactive() is needed over drush_op_system() ?

3. Shell aliases do not currently work inside the core-cli shell. This is a bug, but not one i care much about. Part of me wants to get rid of the shell part of core-cli and just keep its --pipe feature. Feedback welcome.

Although it would be nice, I'm hesitant to fix core-cli by adding $shell_aliases to the commands list. The problem is that our command definition has nowhere that I know of for representing options. Until we have that, options would still have to be injected into the context I think. Also, the only place we have to put arguments is the 'default arguments' item. 'default arguments' get overridden by cli arguments which is not the behavior thats expected for arguments in a shell alias. I guess we'd introduce a 'fixed arguments' item to $command definition. If we go that, I guess 'fixed options' takes care of the first problem.

greg.1.anderson’s picture

Yes, those are good points.

2. Your implementation has the advantage that shell aliases work remotely even if not defined on the remote machine. Expanding !git pull to exec git pull (w/ a new drush command 'exec') would be one way to support remote alias execution.

3. Supporting shell aliases in core-cli is a little odd, as in this environment, a drush shell alias reduces in behavior to a bash alias. I only use core-cli --pipe; I never use it as a subshell. I'm on the fence as to whether this means the subshell version should be removed.

moshe weitzman’s picture

I added a core-execute command which handles shell aliases like !git pull. So now remotely executing this type of shell alias works as expected. core-execute is not hidden since I think it is genuinely useful outside of shell aliases.

TODO

  1. When do I use interactive in core-execute command?
  2. Stop using drush_get_option('shell-aliases') in favor of a distinct variable in config file. Not that urgent.
  3. unit tests
  4. docs
moshe weitzman’s picture

Now with unit test and minimalist docs. Is this feature worthy of mention in the README? All I added is the following array in example.drushrc.php

+// Drush shell aliases act similar to git aliases.
+// See https://git.wiki.kernel.org/index.php/Aliases#Advanced.
+# $options['shell-aliases'] = array(
+#   'pull' => '!git pull && drush updatedb',
+#   'noncore' => 'pm-list --no-core',
+#   'wipe' => 'cache-clear all --verbose',
+# );
+
moshe weitzman’s picture

Status: Needs work » Needs review

FYI, you have to have this patch applied on both local and remote sites in order for this to work on remote site aliases. Also, all remote commands now require drush on the remote side which is a bit of a bummer. That started when I implemented the suggestion in #2 for Expanding !git pull to exec git pull.

I think this is committable as is. I would open a new issue for changing $options['shell-aliases'] to something else.

moshe weitzman’s picture

Status: Needs review » Fixed

Committed with minor changes.

Status: Fixed » Closed (fixed)

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