Class: Build::Graph::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/build/graph/task.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(walker, node) ⇒ Task

Returns a new instance of Task.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/build/graph/task.rb', line 39

def initialize(walker, node)
	@walker = walker
	
	@walker.tasks[node] = self
	
	@node = node
	@fiber = nil
	
	@error = nil
	
	# Tasks that must be complete before finishing this task.
	@children = []
	
	@state = nil
	
	@inputs_failed = false
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children


60
61
62
# File 'lib/build/graph/task.rb', line 60

def children
  @children
end

#errorObject (readonly)

The error, if the execution of the node fails.


66
67
68
# File 'lib/build/graph/task.rb', line 66

def error
  @error
end

#inputsObject (readonly)

Returns the value of attribute inputs


57
58
59
# File 'lib/build/graph/task.rb', line 57

def inputs
  @inputs
end

#inputs_failedObject (readonly)

A list of any inputs whose relevant tasks failed:


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

def inputs_failed
  @inputs_failed
end

#nodeObject (readonly)

Returns the value of attribute node


70
71
72
# File 'lib/build/graph/task.rb', line 70

def node
  @node
end

#outputsObject (readonly)

Returns the value of attribute outputs


58
59
60
# File 'lib/build/graph/task.rb', line 58

def outputs
  @outputs
end

#stateObject (readonly)

The state of the task, one of nil, :complete or :failed.


63
64
65
# File 'lib/build/graph/task.rb', line 63

def state
  @state
end

#walkerObject (readonly)

Returns the value of attribute walker


68
69
70
# File 'lib/build/graph/task.rb', line 68

def walker
  @walker
end

Instance Method Details

#changed!Object


145
146
147
# File 'lib/build/graph/task.rb', line 145

def changed!
	@walker.delete(@node) if (@inputs.update! or @outputs.update!)
end

#complete?Boolean

Returns:

  • (Boolean)

131
132
133
# File 'lib/build/graph/task.rb', line 131

def complete?
	@state == :complete
end

#directoriesObject


149
150
151
# File 'lib/build/graph/task.rb', line 149

def directories
	(@inputs.roots + @outputs.roots).collect{|path| path.to_s}
end

#dirty?Boolean

Returns true if the outputs of the task are out of date w.r.t. the inputs. Currently, does not take into account if the input is a glob and files have been added.

Returns:

  • (Boolean)

137
138
139
140
141
142
143
# File 'lib/build/graph/task.rb', line 137

def dirty?
	if @outputs
		@outputs.dirty?(@inputs)
	else
		true
	end
end

#failed?Boolean

Returns:

  • (Boolean)

127
128
129
# File 'lib/build/graph/task.rb', line 127

def failed?
	@state == :failed
end

#inspectObject


157
158
159
# File 'lib/build/graph/task.rb', line 157

def inspect
	"\#<#{self.class}:0x#{self.object_id.to_s(16)} #{node_string} #{state_string}>"
end

#invoke(node) ⇒ Task

Returns the child task that was created to update the node.

Returns:

  • (Task)

    the child task that was created to update the node.

Raises:

  • (ArgumentError)

117
118
119
120
121
122
123
124
125
# File 'lib/build/graph/task.rb', line 117

def invoke(node)
	child_task = @walker.call(node, self)
	
	raise ArgumentError.new("Invalid child task") unless child_task
	
	@children << child_task
	
	return child_task
end

#to_sObject


153
154
155
# File 'lib/build/graph/task.rb', line 153

def to_s
	"#<#{self.class} #{node_string} #{state_string}>"
end

#visitObject

Derived task can override this function to provide appropriate behaviour.


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/build/graph/task.rb', line 76

def visit
	update_inputs_and_outputs
	
	# Inforn the walker a new task is being generated for this node:
	@walker.enter(self)
	
	if @fiber
		raise RuntimeError, "Task is already running!"
	end
	
	@fiber = Fiber.new do
		# If all inputs were good, we can update the node.
		if wait_for_inputs?
			begin
				yield
			rescue TransientError => error
				fail!(error)
			end
		else
			fail!(InputsFailed)
		end
		
		wait_for_children!
		
		update_outputs!
		
		@state ||= :complete
		
		@walker.exit(self)
		
		@fiber = nil
	end
	
	# Schedule the work, hopefully synchronously:
	@fiber.resume
	
	# This allows the child task to be passed back to the parent when it is first invoked.
	return self
end