build-graph 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -3
- data/build-graph.gemspec +1 -2
- data/lib/build/graph/task.rb +1 -4
- data/lib/build/graph/version.rb +1 -1
- data/lib/build/graph/walker.rb +17 -18
- data/spec/build/graph/build_test.rb +0 -1
- data/spec/build/graph/graph_spec.rb +0 -2
- data/spec/build/graph/process_graph.rb +4 -1
- data/spec/build/graph/walker_spec.rb +2 -4
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4245e7fa0dd8f7cd2de6ef69631c4aa879579d0508bae3227dae10cd7d6a4d6
|
4
|
+
data.tar.gz: 662bcc629c6826483d2fc0807ae0e50da02fd30e920e1f89c3b2d6d02e2e16e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 526776e467bf78940a9369ff6f4c1c6f8ebc43999180039b59b2a0046f3598f2291d48f9d3eb2939d8cb5552b719d55510267c1ebac498d6e3e6b6f05afd8bb0
|
7
|
+
data.tar.gz: 922671aa30935391f4d6ba21c01e1e8776835438769a81f5f9f67e0ab486f0a427f9ead2b06f0c0bf42281fd75120d605cc4798b1d2ad14009f7f0a7e77b49c6
|
data/Gemfile
CHANGED
data/build-graph.gemspec
CHANGED
@@ -24,11 +24,10 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_dependency "process-group", "~> 1.1"
|
26
26
|
spec.add_dependency "build-files", "~> 1.0"
|
27
|
+
spec.add_dependency "event", "~> 1.0"
|
27
28
|
|
28
29
|
spec.add_development_dependency "build-makefile", "~> 1.0"
|
29
30
|
|
30
|
-
spec.add_dependency "rainbow", "~> 2.0"
|
31
|
-
|
32
31
|
spec.add_development_dependency "covered"
|
33
32
|
spec.add_development_dependency "bundler"
|
34
33
|
spec.add_development_dependency "rspec", "~> 3.4"
|
data/lib/build/graph/task.rb
CHANGED
@@ -180,10 +180,7 @@ module Build
|
|
180
180
|
def fail!(error)
|
181
181
|
@annotation = "failed"
|
182
182
|
|
183
|
-
|
184
|
-
logger.error("Task #{self} failed: #{error}")
|
185
|
-
logger.debug(error) if error.kind_of?(Exception)
|
186
|
-
end
|
183
|
+
@walker.logger&.error(self) {error}
|
187
184
|
|
188
185
|
@error = error
|
189
186
|
@state = :failed
|
data/lib/build/graph/version.rb
CHANGED
data/lib/build/graph/walker.rb
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'set'
|
22
|
-
require '
|
22
|
+
require 'event/console'
|
23
23
|
|
24
24
|
require_relative 'task'
|
25
25
|
require_relative 'node'
|
@@ -39,7 +39,7 @@ module Build
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def initialize(logger:
|
42
|
+
def initialize(logger: Event::Console.logger, &block)
|
43
43
|
# Node -> Task mapping.
|
44
44
|
@tasks = {}
|
45
45
|
|
@@ -54,7 +54,7 @@ module Build
|
|
54
54
|
@failed_tasks = []
|
55
55
|
@failed_outputs = Set.new
|
56
56
|
|
57
|
-
@logger = logger
|
57
|
+
@logger = logger
|
58
58
|
@monitor = Files::Monitor.new(logger: @logger)
|
59
59
|
end
|
60
60
|
|
@@ -86,7 +86,7 @@ module Build
|
|
86
86
|
def call(node, parent_task = nil)
|
87
87
|
# We try to fetch the task if it has already been invoked, otherwise we create a new task.
|
88
88
|
@tasks.fetch(node) do
|
89
|
-
@logger
|
89
|
+
@logger&.debug(self) {"Update: #{node} #{parent_task.class}"}
|
90
90
|
|
91
91
|
# This method should add the node
|
92
92
|
@update.call(self, node, parent_task)
|
@@ -112,7 +112,7 @@ module Build
|
|
112
112
|
paths.each do |path|
|
113
113
|
# Is there a task generating this output?
|
114
114
|
if outputs = @outputs[path]
|
115
|
-
@logger
|
115
|
+
@logger&.debug(self) {"Task #{task} is waiting on path #{path}"}
|
116
116
|
|
117
117
|
# When the output is ready, trigger this edge:
|
118
118
|
outputs << edge
|
@@ -139,7 +139,7 @@ module Build
|
|
139
139
|
# If there are no children like this, then done:
|
140
140
|
return true if children.size == 0
|
141
141
|
|
142
|
-
@logger
|
142
|
+
@logger&.debug(self) {"Task #{parent} is waiting on #{children.count} children"}
|
143
143
|
|
144
144
|
# Otherwise, construct an edge to track state changes:
|
145
145
|
edge = Edge.new
|
@@ -159,14 +159,19 @@ module Build
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def enter(task)
|
162
|
-
@logger
|
162
|
+
@logger&.info(self) {"Walker entering: #{task.node.process}"}
|
163
163
|
|
164
164
|
@tasks[task.node] = task
|
165
165
|
|
166
166
|
# In order to wait on outputs, they must be known before entering the task. This might seem odd, but unless we know outputs are being generated, waiting for them to complete is impossible - unless this was somehow specified ahead of time. The implications of this logic is that all tasks must be sequential in terms of output -> input chaning. This is by design and is not a problem in practice.
|
167
167
|
|
168
168
|
if outputs = task.outputs
|
169
|
-
@logger
|
169
|
+
@logger&.debug(self) do |buffer|
|
170
|
+
buffer.puts "Task will generate outputs:"
|
171
|
+
Array(outputs).each do |output|
|
172
|
+
buffer.puts output.inspect
|
173
|
+
end
|
174
|
+
end
|
170
175
|
|
171
176
|
outputs.each do |path|
|
172
177
|
# Tasks which have children tasks may list the same output twice. This is not a bug.
|
@@ -176,7 +181,7 @@ module Build
|
|
176
181
|
end
|
177
182
|
|
178
183
|
def exit(task)
|
179
|
-
@logger
|
184
|
+
@logger&.info(self) {"Walker exiting: #{task.node.process}, task #{task.failed? ? 'failed' : 'succeeded'}"}
|
180
185
|
|
181
186
|
# Fail outputs if the node failed:
|
182
187
|
if task.failed?
|
@@ -191,16 +196,10 @@ module Build
|
|
191
196
|
task.outputs.each do |path|
|
192
197
|
path = path.to_s
|
193
198
|
|
194
|
-
|
195
|
-
if task.failed?
|
196
|
-
@logger.debug "\tFile failed: #{path}"
|
197
|
-
else
|
198
|
-
@logger.debug "\tFile available: #{path}"
|
199
|
-
end
|
200
|
-
end
|
199
|
+
@logger&.debug(self) {"File #{task.failed? ? 'failed' : 'available'}: #{path}"}
|
201
200
|
|
202
201
|
if edges = @outputs.delete(path)
|
203
|
-
# @logger
|
202
|
+
# @logger&.debug "\tUpdating #{edges.count} edges..."
|
204
203
|
edges.each{|edge| edge.traverse(task)}
|
205
204
|
end
|
206
205
|
end
|
@@ -214,7 +213,7 @@ module Build
|
|
214
213
|
end
|
215
214
|
|
216
215
|
def delete(node)
|
217
|
-
@logger
|
216
|
+
@logger&.debug(self) {"Delete #{node}"}
|
218
217
|
|
219
218
|
if task = @tasks.delete(node)
|
220
219
|
@monitor.delete(task)
|
@@ -12,7 +12,6 @@ code_glob = Glob.new(program_root, "*.cpp")
|
|
12
12
|
program_path = Path.join(program_root, "dictionary-sort")
|
13
13
|
|
14
14
|
group = Process::Group.new
|
15
|
-
logger = Logger.new($stderr)
|
16
15
|
walker = Walker.for(ProcessTask, group)
|
17
16
|
|
18
17
|
top = ProcessNode.top code_glob, title: 'top' do
|
@@ -24,8 +24,6 @@ require_relative 'process_graph'
|
|
24
24
|
RSpec.describe Build::Graph do
|
25
25
|
let(:group) {Process::Group.new}
|
26
26
|
|
27
|
-
let(:logger) {Logger.new($stderr).tap{|logger| logger.level = Logger::DEBUG}}
|
28
|
-
|
29
27
|
it "shouldn't update mtime" do
|
30
28
|
test_glob = Build::Files::Glob.new(__dir__, "*.rb")
|
31
29
|
listing_output = Build::Files::Paths.directory(__dir__, ["listing.txt"])
|
@@ -3,6 +3,8 @@ require 'process/group'
|
|
3
3
|
require 'build/files'
|
4
4
|
require 'build/graph'
|
5
5
|
|
6
|
+
require 'event/shell'
|
7
|
+
|
6
8
|
class ProcessNode < Build::Graph::Node
|
7
9
|
def initialize(inputs, outputs, block, title: nil)
|
8
10
|
super(inputs, outputs, block.source_location)
|
@@ -45,7 +47,8 @@ class ProcessTask < Build::Graph::Task
|
|
45
47
|
|
46
48
|
def run(*arguments)
|
47
49
|
if wet?
|
48
|
-
|
50
|
+
@walker.logger.debug(self) {Event::Shell.for(*arguments)}
|
51
|
+
|
49
52
|
status = @group.spawn(*arguments)
|
50
53
|
|
51
54
|
if status != 0
|
@@ -25,8 +25,6 @@ require 'build/graph/task'
|
|
25
25
|
require 'build/files/glob'
|
26
26
|
|
27
27
|
RSpec.describe Build::Graph::Walker do
|
28
|
-
let(:logger) {Logger.new($stderr).tap{|logger| logger.level = Logger::DEBUG}}
|
29
|
-
|
30
28
|
it "can generate the same output from multiple tasks" do
|
31
29
|
test_glob = Build::Files::Glob.new(__dir__, "*.rb")
|
32
30
|
listing_output = Build::Files::Paths.directory(__dir__, ["listing.txt"])
|
@@ -37,7 +35,7 @@ RSpec.describe Build::Graph::Walker do
|
|
37
35
|
sequence = []
|
38
36
|
|
39
37
|
# A walker runs repeatedly, updating tasks which have been marked as dirty.
|
40
|
-
walker = Build::Graph::Walker.new
|
38
|
+
walker = Build::Graph::Walker.new do |walker, node|
|
41
39
|
task = Build::Graph::Task.new(walker, node)
|
42
40
|
|
43
41
|
task.visit do
|
@@ -73,7 +71,7 @@ RSpec.describe Build::Graph::Walker do
|
|
73
71
|
sequence = []
|
74
72
|
|
75
73
|
# A walker runs repeatedly, updating tasks which have been marked as dirty.
|
76
|
-
walker = Build::Graph::Walker.new
|
74
|
+
walker = Build::Graph::Walker.new do |walker, node|
|
77
75
|
task = Build::Graph::Task.new(walker, node)
|
78
76
|
|
79
77
|
task.visit do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: build-graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: process-group
|
@@ -39,13 +39,13 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: event
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.0'
|
48
|
-
type: :
|
48
|
+
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: build-makefile
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
type: :
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '1.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: covered
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|