class Automate::ChainLink
Represents a single link of a command chain, which takes a number of input parameters (‘@in_args`), does some magic, returning a number of output arguments (`@out_args`).
A chain link is created by the ‘Chain#go` method. The block passed to said method contains the logic which is later executed within this class (by invoke
).
Public Class Methods
# File lib/automate/chain_link.rb, line 14 def self.invoke(proc, args) new(args).invoke(proc) end
Private constructor. Instance creation is only allowed through ‘#invoke`.
# File lib/automate/chain_link.rb, line 108 def initialize(args) @in_args = args @out_args = {} @defer_list = [] end
Public Instance Methods
# File lib/automate/chain_link.rb, line 76 def defer(desc, &block) @defer_list.push [desc, block] end
Requires that an argument must be present before proceeding in the current chain
# File lib/automate/chain_link.rb, line 65 def demand(*keys) keys.each do |key| raise UnmetDemandError.new(key) if !@in_args.has_key? key end end
Manually abort a chain because of an error
# File lib/automate/chain_link.rb, line 72 def error(msg) raise CmdFailedError.new(msg) end
Invokes the block passed to the ‘#go` method. Said block will be able to call the methods listed in the “Public API” section.
# File lib/automate/chain_link.rb, line 21 def invoke(proc) ret = instance_exec(&proc) [ret, @out_args, @defer_list] rescue UnmetDemandError => e fail "Required argument '#{e.demand}', but was not given." raise ChainLinkFailedError.new(@defer_list) rescue CmdFailedError => e fail e.message raise ChainLinkFailedError.new(@defer_list) rescue => e fail "Chain link raised an exception: \n #{e} \n #{e.backtrace.join("\n")}" raise ChainLinkFailedError.new(@defer_list) end
Implement method_missing
so that we can address passed variables using the ‘_variablename` shorthand within a chain link.
# File lib/automate/chain_link.rb, line 82 def method_missing(method, *args, &block) if method.to_s =~ /^_(.+)$/ arg = @in_args[$1.to_sym] || @out_args[$1.to_sym] return arg if !arg.nil? end super end
Passes an argument onto the next link of the chain
# File lib/automate/chain_link.rb, line 59 def pass(key, value) @out_args[key] = value end
Runs a given shell command, aborting the command chain if there is an error.
# File lib/automate/chain_link.rb, line 42 def run(cmd, capture_stderr=true) notice "Running: " + cmd.color(:white) cmd += " 2>&1" if capture_stderr out = "" IO.popen(cmd) do |f| while l = f.gets out += l msg " " + l end end raise CmdFailedError.new("Command '#{cmd}' had exit status #{$?.to_i}") if $? != 0 out end