Module: Toys::StandardMixins::Exec

Includes:
Mixin
Defined in:
lib/toys/standard_mixins/exec.rb

Overview

A set of helper methods for invoking subcommands. Provides shortcuts for common cases such as invoking Ruby in a subprocess or capturing output in a string. Also provides an interface for controlling a spawned process's streams.

You may make these methods available to your tool by including the following directive in your tool configuration:

include :exec

This is a frontend for Utils::Exec. More information is available in that class's documentation.

Configuration Options

Subprocesses may be configured using the options in the Utils::Exec class. These include a variety of options supported by Process#spawn, and some options supported by Utils::Exec itself.

You can set default configuration by passing options to the include directive. For example, to log commands at the debug level for all subprocesses spawned by this tool:

include :exec, log_level: Logger::DEBUG

Two special options are also recognized by the mixin.

  • A :result_callback proc may take a second argument. If it does, the context object is passed as the second argument. This is useful if a :result_callback is applied to the entire tool by passing it to the include directive. In that case, self is not set to the context object as it normally would be in a tool's run method, so you cannot access it otherwise. For example, here is how to log the exit code for every subcommand:

    tool "mytool" do
      callback = proc do |result, context|
        context.logger.info "Exit code: #{result.exit_code}"
      end
      include :exec, result_callback: callback
      # ...
    end
    

    You may also pass a symbol as the :result_callback. The method with that name is then called as the callback. The method must take one argument, the result object.

  • If :exit_on_nonzero_status is set to true, a nonzero exit code returned by the subprocess will also cause the tool to exit immediately with that same code.

    This is particularly useful as an option to the include directive, where it causes any subprocess failure to abort the tool, similar to setting set -e in a bash script.

    include :exec, exit_on_nonzero_status: true
    

    :e can be used as a shortcut for :exit_on_nonzero_status

    include :exec, e: true
    

Constant Summary collapse

KEY =

Context key for the executor object.

Returns:

  • (Object)
::Object.new.freeze

Instance Method Summary collapse

Methods included from Mixin

create

Instance Method Details

#capture(cmd, opts = {}) {|controller| ... } ⇒ String

Execute a command. The command may be given as a single string to pass to a shell, or an array of strings indicating a posix command.

Captures standard out and returns it as a string. Cannot be run in the background.

If a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • cmd (String, Array<String>)

    The command to execute.

  • opts (Hash) (defaults to: {})

    The command options. All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:

  • (String)

    What was written to standard out.



237
238
239
# File 'lib/toys/standard_mixins/exec.rb', line 237

def capture(cmd, opts = {}, &block)
  self[KEY].capture(cmd, Exec._setup_exec_opts(opts, self), &block)
end

#capture_proc(func, opts = {}) {|controller| ... } ⇒ String

Execute a proc in a subprocess.

Captures standard out and returns it as a string. Cannot be run in the background.

If a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • func (Proc)

    The proc to call.

  • opts (Hash) (defaults to: {})

    The command options. Most options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:

  • (String)

    What was written to standard out.



281
282
283
# File 'lib/toys/standard_mixins/exec.rb', line 281

def capture_proc(func, opts = {}, &block)
  self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self), &block)
end

#capture_ruby(args, opts = {}) {|controller| ... } ⇒ String

Spawn a ruby process and pass the given arguments to it.

Captures standard out and returns it as a string. Cannot be run in the background.

If a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • args (String, Array<String>)

    The arguments to ruby.

  • opts (Hash) (defaults to: {})

    The command options. All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:

  • (String)

    What was written to standard out.



259
260
261
# File 'lib/toys/standard_mixins/exec.rb', line 259

def capture_ruby(args, opts = {}, &block)
  self[KEY].capture_ruby(args, Exec._setup_exec_opts(opts, self), &block)
end

#capture_tool(cmd, opts = {}) {|controller| ... } ⇒ String

Execute a tool. The command may be given as a single string or an array of strings, representing the tool to run and the arguments to pass.

Captures standard out and returns it as a string. Cannot be run in the background.

If a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • cmd (String, Array<String>)

    The tool to execute.

  • opts (Hash) (defaults to: {})

    The command options. Most options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:

  • (String)

    What was written to standard out.



304
305
306
307
# File 'lib/toys/standard_mixins/exec.rb', line 304

def capture_tool(cmd, opts = {}, &block)
  func = Exec._make_tool_caller(cmd)
  self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self), &block)
end

#configure_exec(opts = {}) ⇒ self

Set default configuration keys.

All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Parameters:

  • opts (Hash) (defaults to: {})

    The default options.

Returns:

  • (self)


121
122
123
124
# File 'lib/toys/standard_mixins/exec.rb', line 121

def configure_exec(opts = {})
  self[KEY].configure_defaults(Exec._setup_exec_opts(opts, self))
  self
end

#exec(cmd, opts = {}) {|controller| ... } ⇒ Toys::Utils::Exec::Controller, Toys::Utils::Exec::Result

Execute a command. The command may be given as a single string to pass to a shell, or an array of strings indicating a posix command.

If the process is not set to run in the background, and a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • cmd (String, Array<String>)

    The command to execute.

  • opts (Hash) (defaults to: {})

    The command options. All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:



145
146
147
# File 'lib/toys/standard_mixins/exec.rb', line 145

def exec(cmd, opts = {}, &block)
  self[KEY].exec(cmd, Exec._setup_exec_opts(opts, self), &block)
end

#exec_proc(func, opts = {}) {|controller| ... } ⇒ Toys::Utils::Exec::Controller, Toys::Utils::Exec::Result

Execute a proc in a subprocess.

If the process is not set to run in the background, and a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • func (Proc)

    The proc to call.

  • opts (Hash) (defaults to: {})

    The command options. Most options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:



190
191
192
# File 'lib/toys/standard_mixins/exec.rb', line 190

def exec_proc(func, opts = {}, &block)
  self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
end

#exec_ruby(args, opts = {}) {|controller| ... } ⇒ Toys::Utils::Exec::Controller, Toys::Utils::Exec::Result Also known as: ruby

Spawn a ruby process and pass the given arguments to it.

If the process is not set to run in the background, and a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • args (String, Array<String>)

    The arguments to ruby.

  • opts (Hash) (defaults to: {})

    The command options. All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:



167
168
169
# File 'lib/toys/standard_mixins/exec.rb', line 167

def exec_ruby(args, opts = {}, &block)
  self[KEY].exec_ruby(args, Exec._setup_exec_opts(opts, self), &block)
end

#exec_tool(cmd, opts = {}) {|controller| ... } ⇒ Toys::Utils::Exec::Controller, Toys::Utils::Exec::Result

Execute a tool. The command may be given as a single string or an array of strings, representing the tool to run and the arguments to pass.

If the process is not set to run in the background, and a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • cmd (String, Array<String>)

    The tool to execute.

  • opts (Hash) (defaults to: {})

    The command options. Most options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:



213
214
215
216
# File 'lib/toys/standard_mixins/exec.rb', line 213

def exec_tool(cmd, opts = {}, &block)
  func = Exec._make_tool_caller(cmd)
  self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
end

#exit_on_nonzero_status(status) ⇒ Integer

Exit if the given status code is nonzero. Otherwise, returns 0.

Parameters:

Returns:

  • (Integer)


335
336
337
338
339
340
# File 'lib/toys/standard_mixins/exec.rb', line 335

def exit_on_nonzero_status(status)
  status = status.exit_code if status.respond_to?(:exit_code)
  status = status.exitstatus if status.respond_to?(:exitstatus)
  Context.exit(status) unless status.zero?
  0
end

#sh(cmd, opts = {}) {|controller| ... } ⇒ Integer

Execute the given string in a shell. Returns the exit code. Cannot be run in the background.

If a block is provided, a Utils::Exec::Controller will be yielded to it.

Parameters:

  • cmd (String)

    The shell command to execute.

  • opts (Hash) (defaults to: {})

    The command options. All options listed in the Utils::Exec documentation are supported, plus the exit_on_nonzero_status option.

Yield Parameters:

Returns:

  • (Integer)

    The exit code



325
326
327
# File 'lib/toys/standard_mixins/exec.rb', line 325

def sh(cmd, opts = {}, &block)
  self[KEY].sh(cmd, Exec._setup_exec_opts(opts, self), &block)
end