Class: Automate::ChainLink

Inherits:
Object
  • Object
show all
Includes:
Messenger
Defined in:
lib/automate/chain_link.rb

Overview

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).

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Messenger

#fail, #format, #msg, #notice, #success

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

Implement method_missing so that we can address passed variables using the ‘_variablename` shorthand within a chain link.



82
83
84
85
86
87
88
89
# 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

Class Method Details

.invoke(proc, args) ⇒ Object



14
15
16
# File 'lib/automate/chain_link.rb', line 14

def self.invoke(proc, args)
  new(args).invoke(proc)
end

Instance Method Details

#defer(desc, &block) ⇒ Object



76
77
78
# File 'lib/automate/chain_link.rb', line 76

def defer(desc, &block)
  @defer_list.push [desc, block]
end

#demand(*keys) ⇒ Object

Requires that an argument must be present before proceeding in the current chain



65
66
67
68
69
# 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

#error(msg) ⇒ Object

Manually abort a chain because of an error

Raises:



72
73
74
# File 'lib/automate/chain_link.rb', line 72

def error(msg)
  raise CmdFailedError.new(msg)
end

#invoke(proc) ⇒ Object

Invokes the block passed to the ‘#go` method. Said block will be able to call the methods listed in the “Public API” section.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 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

#pass(key, value) ⇒ Object

Passes an argument onto the next link of the chain



59
60
61
# File 'lib/automate/chain_link.rb', line 59

def pass(key, value)
  @out_args[key] = value
end

#prefixObject

Messenger module related



97
98
99
# File 'lib/automate/chain_link.rb', line 97

def prefix
  "    => "
end

#run(cmd, capture_stderr = true) ⇒ Object

Runs a given shell command, aborting the command chain if there is an error.

Raises:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 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