Daily Code Reading #18 – Capistrano recipes – invoke

Continuing from my tour of Capistrano‘s internals, I’m going to start looking through Capistrano‘s recipes now. A recipe for Capistrano is a unit of work, similar to how Rake uses tasks. I’m going to start with the basic invoke recipe today.

The Code

1
2
desc < method)
end

Review

invoke is pretty straight forward. It:

  1. Extracts the command to be run from the COMMAND environment variable
  2. Checks that command isn’t empty
  3. Decides if the command should be run as the normal user or with sudo
  4. Finally invokes the command

Bases on this, the invoke recipe is just a thin wrapper around Capistrano::Configuration::Actions::Invocation#invoke_command. And #invoke_command itself is just a dispatcher to other methods in Capistrano:

1
2
3
4
5
def invoke_command(cmd, options={}, &block)
  options = options.dup
  via = options.delete(:via) || :run
  send(via, cmd, options, &block)
end

I like how #invoke_command is using send to let the user control how the command is invoked. By default it’s called with :run which will call the run method. But back in the invoke recipe, if SUDO is set then the command will be run using the sudo method. I’ve used a similar pattern in my code, where I need to call a method based on some dynamic input.