Class: Crew::Task

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/crew/task.rb,
lib/crew/task/dsl.rb,
lib/crew/task/test.rb,
lib/crew/task/arguments.rb,
lib/crew/task/arguments/dsl.rb

Defined Under Namespace

Classes: Arguments, DSL, Test

Constant Summary collapse

NoMatchingHintsError =
Class.new(RuntimeError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#assert, #escape, #logger, #poll, #retryable

Constructor Details

#initialize(home, name, load_path = nil, &dsl_blk) ⇒ Task

Returns a new instance of Task.



10
11
12
13
14
# File 'lib/crew/task.rb', line 10

def initialize(home, name, load_path = nil, &dsl_blk)
  @home, @name, @load_path, @dsl_blk = home, name, load_path, dsl_blk
  @context = @home.context
  reset!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &blk) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/crew/task.rb', line 57

def method_missing(name, *args, &blk)
  if t = task(name.to_s)
    t.run!(*args, &blk)
  else
    super(name, *args, &blk)
  end
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



8
9
10
# File 'lib/crew/task.rb', line 8

def arguments
  @arguments
end

#contextObject

Returns the value of attribute context.



7
8
9
# File 'lib/crew/task.rb', line 7

def context
  @context
end

#default_hintsObject

Returns the value of attribute default_hints.



7
8
9
# File 'lib/crew/task.rb', line 7

def default_hints
  @default_hints
end

#descObject

Returns the value of attribute desc.



7
8
9
# File 'lib/crew/task.rb', line 7

def desc
  @desc
end

#homeObject (readonly)

Returns the value of attribute home.



8
9
10
# File 'lib/crew/task.rb', line 8

def home
  @home
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/crew/task.rb', line 8

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path.



8
9
10
# File 'lib/crew/task.rb', line 8

def path
  @path
end

Instance Method Details

#add_run(*hints, &block) ⇒ Object



164
165
166
# File 'lib/crew/task.rb', line 164

def add_run(*hints, &block)
  add_to_list(@runners, hints, block)
end

#add_setup(*hints, &block) ⇒ Object



156
157
158
# File 'lib/crew/task.rb', line 156

def add_setup(*hints, &block)
  add_to_list(@setups, hints, block)
end

#add_template(name, contents) ⇒ Object



143
144
145
# File 'lib/crew/task.rb', line 143

def add_template(name, contents)
  @templates[name] = contents
end

#add_test(*hints, &test) ⇒ Object



152
153
154
# File 'lib/crew/task.rb', line 152

def add_test(*hints, &test)
  @tests << [(@default_hints + hints).map(&:to_s), test]
end

#add_verify(*hints, &block) ⇒ Object



160
161
162
# File 'lib/crew/task.rb', line 160

def add_verify(*hints, &block)
  add_to_list(@verifiers, hints, block)
end

#argsObject



41
42
43
# File 'lib/crew/task.rb', line 41

def args
  @arguments.proxy(self)
end

#cd(dir, &blk) ⇒ Object



65
66
67
# File 'lib/crew/task.rb', line 65

def cd(dir, &blk)
  @context.cd(dir, &blk)
end

#digestObject



125
126
127
# File 'lib/crew/task.rb', line 125

def digest
  Digest::SHA1.hexdigest(source)
end

#hint(h) ⇒ Object



89
90
91
# File 'lib/crew/task.rb', line 89

def hint(h)
  @context.hint(h)
end

#hintsObject



93
94
95
# File 'lib/crew/task.rb', line 93

def hints
  @context.hints
end

#home_dirObject



20
21
22
# File 'lib/crew/task.rb', line 20

def home_dir
  @home.home_path
end

#installed?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/crew/task.rb', line 16

def installed?
  File.exist?(@load_path) && @load_path.start_with?(home_dir)
end

#passing?Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
55
# File 'lib/crew/task.rb', line 49

def passing?
  results = Dir[File.join(all_tests_path_prefix, "**", "*.json")].collect do |result|
    JSON.parse(File.read(result))['status']
  end
  results.uniq!
  results.all? {|r| %w(pass skip).include?(r)}
end

#reconnect!Object



97
98
99
# File 'lib/crew/task.rb', line 97

def reconnect!
  @context.reconnect!
end

#reset!Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/crew/task.rb', line 24

def reset!
  @desc = ""
  @templates = {}
  @arguments = Arguments.new
  @setups = {}
  @verifiers = {}
  @runners = {}
  @tests = []
  @default_hints = []
  dsl = DSL.new(self, &@dsl_blk)
  dsl.load(@load_path) if @load_path
end

#run!(*incoming_args, &blk) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/crew/task.rb', line 101

def run!(*incoming_args, &blk)
  reset!
  @context.with_callbacks do
    @arguments.process!(incoming_args, &blk)
    @context.logger.task(@name, args) do
      success = false
      task_finished = false

      @context.home.perform_setup { setup }
      raise "task '#{@name}' has been called from within setup, but, has no verifier" if @context.home.in_setup && !verifiable?
      success = verifiable? && verified?
      unless success
        raise "can't perform `#{@name}' because we're in setup mode, but, we're not actually performing the setup" if @context.home.in_setup && !@context.home.setup_mode
        @out = run
        if verifiable?
          @out = nil
          verified? or raise "validator for '#{@name}' failed after the task completed successfully"
        end
      end
      @out
    end
  end
end

#save_data(*args) ⇒ Object



81
82
83
# File 'lib/crew/task.rb', line 81

def save_data(*args)
  @context.save_data(*args)
end

#save_file(*args) ⇒ Object



85
86
87
# File 'lib/crew/task.rb', line 85

def save_file(*args)
  @context.save_file(*args)
end

#setupObject



172
173
174
# File 'lib/crew/task.rb', line 172

def setup
  eval_for_matching_hints(@setups)
end

#sh(cmd, opts = {}) ⇒ Object



69
70
71
# File 'lib/crew/task.rb', line 69

def sh(cmd, opts = {})
  @context.sh(cmd, opts)
end

#sh_with_code(cmd, opts = {}) ⇒ Object



73
74
75
# File 'lib/crew/task.rb', line 73

def sh_with_code(cmd, opts = {})
  @context.sh_with_code(cmd, opts)
end

#sourceObject



37
38
39
# File 'lib/crew/task.rb', line 37

def source
  File.read(@load_path)
end

#task(name) ⇒ Object



77
78
79
# File 'lib/crew/task.rb', line 77

def task(name)
  @context.task(name)
end

#template(name, locals = {}) ⇒ Object



147
148
149
150
# File 'lib/crew/task.rb', line 147

def template(name, locals = {})
  template = @templates.fetch(name)
  ERB.new(template).result(OpenStruct.new(locals).instance_eval { binding })
end

#test!(tester, opts = {}) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/crew/task.rb', line 129

def test!(tester, opts = {})
  @tests.each_with_index do |(hints, test_block), index|
    force = opts[:force]
    skip = !hints.all? {|h| tester.hints.include?(h)}
    test = Test.new(self, test_path_prefix, index, skip, test_block)
    if test.result.status == 'fail' && opts[:failed_only]
      force = true
    end
    test.clear_cached_result! if force
    yield test.run_test!(opts[:fast])
  end
  clear_extra_results!
end

#untested?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/crew/task.rb', line 45

def untested?
  @tests.empty?
end

#verifyObject



168
169
170
# File 'lib/crew/task.rb', line 168

def verify
  eval_for_matching_hints(@verifiers) { raise_no_matching_hints }
end