build-graph 2.1.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +65 -0
- data/context/index.yaml +18 -0
- data/context/visualization.md +79 -0
- data/lib/build/graph/edge.rb +9 -20
- data/lib/build/graph/node.rb +15 -21
- data/lib/build/graph/task.rb +37 -20
- data/lib/build/graph/version.rb +7 -20
- data/lib/build/graph/visualization.rb +55 -0
- data/lib/build/graph/walker.rb +43 -43
- data/lib/build/graph.rb +9 -27
- data/license.md +21 -0
- data/readme.md +59 -0
- data/releases.md +9 -0
- data.tar.gz.sig +0 -0
- metadata +43 -142
- metadata.gz.sig +0 -0
- data/spec/build/graph/build_test.rb +0 -85
- data/spec/build/graph/edge_spec.rb +0 -39
- data/spec/build/graph/graph_spec.rb +0 -172
- data/spec/build/graph/inherit_spec.rb +0 -51
- data/spec/build/graph/listing.txt +0 -8
- data/spec/build/graph/node_spec.rb +0 -80
- data/spec/build/graph/process_graph.rb +0 -98
- data/spec/build/graph/program/Benchmark.cpp +0 -72
- data/spec/build/graph/program/Benchmark.cpp.d +0 -1
- data/spec/build/graph/program/Benchmark.cpp.o +0 -0
- data/spec/build/graph/program/Benchmark.h +0 -65
- data/spec/build/graph/program/DictionarySort.h +0 -270
- data/spec/build/graph/program/ParallelMergeSort.h +0 -278
- data/spec/build/graph/program/dictionary-sort +0 -0
- data/spec/build/graph/program/main.cpp +0 -131
- data/spec/build/graph/program/main.cpp.d +0 -1
- data/spec/build/graph/program/main.cpp.o +0 -0
- data/spec/build/graph/task_spec.rb +0 -69
- data/spec/build/graph/walker_spec.rb +0 -125
- data/spec/spec_helper.rb +0 -13
data/lib/build/graph/walker.rb
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
require 'build/files/monitor'
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2014-2026, by Samuel Williams.
|
|
24
5
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
6
|
+
require "set"
|
|
7
|
+
require "console"
|
|
8
|
+
require "build/files/monitor"
|
|
9
|
+
|
|
10
|
+
require_relative "task"
|
|
11
|
+
require_relative "node"
|
|
12
|
+
require_relative "edge"
|
|
28
13
|
|
|
29
14
|
module Build
|
|
30
15
|
module Graph
|
|
31
16
|
# A walker walks over a graph and applies a task to each node.
|
|
32
17
|
class Walker
|
|
18
|
+
# Create a walker that instantiates tasks of the given class for each visited node.
|
|
19
|
+
# @parameter task_class [Class] the task class to instantiate; must accept `(walker, node, *args)`.
|
|
20
|
+
# @returns [Walker] a new walker bound to the given task class.
|
|
33
21
|
def self.for(task_class, *args, **options)
|
|
34
22
|
self.new(**options) do |walker, node, parent_task = nil|
|
|
35
23
|
task = task_class.new(walker, node, *args)
|
|
@@ -40,7 +28,9 @@ module Build
|
|
|
40
28
|
end
|
|
41
29
|
end
|
|
42
30
|
|
|
43
|
-
|
|
31
|
+
# Create a walker with a block that is called for each node to create and run a task.
|
|
32
|
+
# @parameter block [Proc] called with `(walker, node, parent_task)` for each visited node.
|
|
33
|
+
def initialize(&block)
|
|
44
34
|
# Node -> Task mapping.
|
|
45
35
|
@tasks = {}
|
|
46
36
|
|
|
@@ -55,13 +45,9 @@ module Build
|
|
|
55
45
|
@failed_tasks = []
|
|
56
46
|
@failed_outputs = Set.new
|
|
57
47
|
|
|
58
|
-
@
|
|
59
|
-
@monitor = Files::Monitor.new(logger: @logger)
|
|
48
|
+
@monitor = Files::Monitor.new
|
|
60
49
|
end
|
|
61
50
|
|
|
62
|
-
# Primarily for debugging from within Task
|
|
63
|
-
attr :logger
|
|
64
|
-
|
|
65
51
|
# An Array of all instantiated tasks.
|
|
66
52
|
attr :tasks
|
|
67
53
|
|
|
@@ -78,16 +64,22 @@ module Build
|
|
|
78
64
|
|
|
79
65
|
attr :monitor
|
|
80
66
|
|
|
67
|
+
# Invoke the walker for each node in the given collection.
|
|
68
|
+
# @parameter nodes [Enumerable] the nodes to update.
|
|
81
69
|
def update(nodes)
|
|
82
70
|
Array(nodes).each do |node|
|
|
83
71
|
self.call(node)
|
|
84
72
|
end
|
|
85
73
|
end
|
|
86
74
|
|
|
75
|
+
# Invoke the walker for a single node, reusing an existing task if the node has already been visited.
|
|
76
|
+
# @parameter node [Node] the node to update.
|
|
77
|
+
# @parameter parent_task [Task | nil] the parent task, if any.
|
|
78
|
+
# @returns [Task] the task associated with the node.
|
|
87
79
|
def call(node, parent_task = nil)
|
|
88
80
|
# We try to fetch the task if it has already been invoked, otherwise we create a new task.
|
|
89
81
|
@tasks.fetch(node) do
|
|
90
|
-
|
|
82
|
+
Console.debug(self){"Update: #{node} #{parent_task.class}"}
|
|
91
83
|
|
|
92
84
|
# This method should add the node
|
|
93
85
|
@update.call(self, node, parent_task)
|
|
@@ -97,10 +89,15 @@ module Build
|
|
|
97
89
|
end
|
|
98
90
|
end
|
|
99
91
|
|
|
92
|
+
# @returns [Boolean] whether any tasks have failed during this walk.
|
|
100
93
|
def failed?
|
|
101
94
|
@failed_tasks.size > 0
|
|
102
95
|
end
|
|
103
96
|
|
|
97
|
+
# Block the current fiber until all tasks generating the given paths have completed.
|
|
98
|
+
# @parameter task [Task] the task waiting on these paths.
|
|
99
|
+
# @parameter paths [Build::Files::List] the paths to wait on.
|
|
100
|
+
# @returns [Boolean] true if all paths are available, false if any failed.
|
|
104
101
|
def wait_on_paths(task, paths)
|
|
105
102
|
# If there are no paths, we are done:
|
|
106
103
|
return true if paths.count == 0
|
|
@@ -113,13 +110,13 @@ module Build
|
|
|
113
110
|
paths.each do |path|
|
|
114
111
|
# Is there a task generating this output?
|
|
115
112
|
if outputs = @outputs[path]
|
|
116
|
-
|
|
113
|
+
Console.debug(self){"Task #{task} is waiting on path #{path}"}
|
|
117
114
|
|
|
118
115
|
# When the output is ready, trigger this edge:
|
|
119
116
|
outputs << edge
|
|
120
117
|
edge.increment!
|
|
121
118
|
elsif !File.exist?(path)
|
|
122
|
-
|
|
119
|
+
Console.warn(self){"Task #{task} is waiting on paths which don't exist and are not being generated!"}
|
|
123
120
|
raise RuntimeError, "File #{path} is not being generated by any active task!"
|
|
124
121
|
# What should we do about paths which haven't been registered as outputs?
|
|
125
122
|
# Either they exist - or they don't.
|
|
@@ -141,7 +138,7 @@ module Build
|
|
|
141
138
|
# If there are no children like this, then done:
|
|
142
139
|
return true if children.size == 0
|
|
143
140
|
|
|
144
|
-
|
|
141
|
+
Console.debug(self){"Task #{parent} is waiting on #{children.count} children"}
|
|
145
142
|
|
|
146
143
|
# Otherwise, construct an edge to track state changes:
|
|
147
144
|
edge = Edge.new
|
|
@@ -160,15 +157,15 @@ module Build
|
|
|
160
157
|
return edge.wait
|
|
161
158
|
end
|
|
162
159
|
|
|
160
|
+
# Register a task as active and record its declared output paths.
|
|
161
|
+
# @parameter task [Task] the task that is beginning execution.
|
|
163
162
|
def enter(task)
|
|
164
|
-
@logger&.debug(self) {"Walker entering: #{task.node}"}
|
|
165
|
-
|
|
166
163
|
@tasks[task.node] = task
|
|
167
164
|
|
|
168
165
|
# 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.
|
|
169
166
|
|
|
170
167
|
if outputs = task.outputs
|
|
171
|
-
|
|
168
|
+
Console.debug(self) do |buffer|
|
|
172
169
|
buffer.puts "Task will generate outputs:"
|
|
173
170
|
Array(outputs).each do |output|
|
|
174
171
|
buffer.puts output.inspect
|
|
@@ -182,9 +179,9 @@ module Build
|
|
|
182
179
|
end
|
|
183
180
|
end
|
|
184
181
|
|
|
182
|
+
# Mark a task as finished, resolve its output paths and notify any waiting tasks.
|
|
183
|
+
# @parameter task [Task] the task that has finished execution.
|
|
185
184
|
def exit(task)
|
|
186
|
-
@logger&.debug(self) {"Walker exiting: #{task.node}, task #{task.failed? ? 'failed' : 'succeeded'}"}
|
|
187
|
-
|
|
188
185
|
# Fail outputs if the node failed:
|
|
189
186
|
if task.failed?
|
|
190
187
|
@failed_tasks << task
|
|
@@ -198,7 +195,7 @@ module Build
|
|
|
198
195
|
task.outputs.each do |path|
|
|
199
196
|
path = path.to_s
|
|
200
197
|
|
|
201
|
-
|
|
198
|
+
Console.debug(self){"File #{task.failed? ? 'failed' : 'available'}: #{path}"}
|
|
202
199
|
|
|
203
200
|
if edges = @outputs.delete(path)
|
|
204
201
|
# @logger&.debug "\tUpdating #{edges.count} edges..."
|
|
@@ -214,14 +211,15 @@ module Build
|
|
|
214
211
|
@monitor.add(task)
|
|
215
212
|
end
|
|
216
213
|
|
|
214
|
+
# Remove a node and its associated task from the walker, e.g. after it has been invalidated.
|
|
215
|
+
# @parameter node [Node] the node to remove.
|
|
217
216
|
def delete(node)
|
|
218
|
-
@logger&.debug(self) {"Delete #{node}"}
|
|
219
|
-
|
|
220
217
|
if task = @tasks.delete(node)
|
|
221
218
|
@monitor.delete(task)
|
|
222
219
|
end
|
|
223
220
|
end
|
|
224
221
|
|
|
222
|
+
# Remove all failed tasks from the walker so they can be retried on the next update.
|
|
225
223
|
def clear_failed
|
|
226
224
|
@failed_tasks.each do |task|
|
|
227
225
|
self.delete(task.node)
|
|
@@ -231,6 +229,7 @@ module Build
|
|
|
231
229
|
@failed_outputs = Set.new
|
|
232
230
|
end
|
|
233
231
|
|
|
232
|
+
# Run an update loop, re-executing the given block whenever the monitor detects filesystem changes.
|
|
234
233
|
def run(**options)
|
|
235
234
|
yield
|
|
236
235
|
|
|
@@ -239,6 +238,7 @@ module Build
|
|
|
239
238
|
end
|
|
240
239
|
end
|
|
241
240
|
|
|
241
|
+
# @returns [String] a human-readable summary of the walker state.
|
|
242
242
|
def inspect
|
|
243
243
|
"\#<#{self.class}:0x#{self.object_id.to_s(16)} #{@tasks.count} tasks, #{@failed_tasks.count} failed>"
|
|
244
244
|
end
|
data/lib/build/graph.rb
CHANGED
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
require_relative 'graph/walker'
|
|
24
|
-
require_relative 'graph/edge'
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2014-2026, by Samuel Williams.
|
|
25
5
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
6
|
+
require_relative "graph/version"
|
|
7
|
+
require_relative "graph/task"
|
|
8
|
+
require_relative "graph/node"
|
|
9
|
+
require_relative "graph/walker"
|
|
10
|
+
require_relative "graph/edge"
|
|
11
|
+
require_relative "graph/visualization"
|
data/license.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright, 2014-2026, by Samuel Williams.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/readme.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Build::Graph
|
|
2
|
+
|
|
3
|
+
Build::Graph is a framework for build systems, with specific functionality for dealing with file based processes.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/ioquatix/build-graph/actions?workflow=Test)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Please see the [project documentation](https://ioquatix.github.io/build-graph) for more details.
|
|
10
|
+
|
|
11
|
+
- [Getting Started](https://ioquatix.github.io/build-graphguides/getting-started/index) - This guide explains how to use `build-graph` to build a dependency graph for file-based build systems.
|
|
12
|
+
|
|
13
|
+
- [Visualization](https://ioquatix.github.io/build-graphguides/visualization/index) - This guide explains how to use <code class="language-ruby">Build::Graph::Visualization</code> to generate Mermaid flowchart diagrams from a build graph.
|
|
14
|
+
|
|
15
|
+
## Releases
|
|
16
|
+
|
|
17
|
+
Please see the [project releases](https://ioquatix.github.io/build-graphreleases/index) for all releases.
|
|
18
|
+
|
|
19
|
+
### v2.3.0
|
|
20
|
+
|
|
21
|
+
- Add `Build::Graph::Visualization` for generating Mermaid diagrams of the build graph.
|
|
22
|
+
|
|
23
|
+
### v2.2.0
|
|
24
|
+
|
|
25
|
+
- Remove `logger` interface.
|
|
26
|
+
|
|
27
|
+
## Contributing
|
|
28
|
+
|
|
29
|
+
We welcome contributions to this project.
|
|
30
|
+
|
|
31
|
+
1. Fork it.
|
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
|
33
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
|
34
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
|
35
|
+
5. Create new Pull Request.
|
|
36
|
+
|
|
37
|
+
### Running Tests
|
|
38
|
+
|
|
39
|
+
To run the test suite:
|
|
40
|
+
|
|
41
|
+
``` shell
|
|
42
|
+
bundle exec sus
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Making Releases
|
|
46
|
+
|
|
47
|
+
To make a new release:
|
|
48
|
+
|
|
49
|
+
``` shell
|
|
50
|
+
bundle exec bake gem:release:patch # or minor or major
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Developer Certificate of Origin
|
|
54
|
+
|
|
55
|
+
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
|
56
|
+
|
|
57
|
+
### Community Guidelines
|
|
58
|
+
|
|
59
|
+
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
|
data/releases.md
ADDED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: build-graph
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain:
|
|
11
10
|
- |
|
|
12
11
|
-----BEGIN CERTIFICATE-----
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
12
|
+
MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
|
|
13
|
+
ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
|
|
14
|
+
CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
|
|
15
|
+
MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
|
|
16
|
+
MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
|
|
17
|
+
bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
|
18
|
+
igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
|
|
19
|
+
9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
|
|
20
|
+
sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
|
|
21
|
+
e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
|
|
22
|
+
XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
|
|
23
|
+
RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
|
|
24
|
+
tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
|
|
25
|
+
zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
|
|
26
|
+
xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
|
27
|
+
BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
|
|
28
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
|
|
29
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
|
|
30
|
+
cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
|
|
31
|
+
xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
|
|
32
|
+
c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
|
|
33
|
+
8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
|
|
34
|
+
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
|
35
|
+
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
|
36
|
+
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
|
37
|
+
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
|
38
38
|
-----END CERTIFICATE-----
|
|
39
|
-
date:
|
|
39
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
40
40
|
dependencies:
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: build-files
|
|
@@ -58,14 +58,14 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0.
|
|
61
|
+
version: '0.4'
|
|
62
62
|
type: :runtime
|
|
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: '0.
|
|
68
|
+
version: '0.4'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: console
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,127 +80,29 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '1.1'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: process-group
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - "~>"
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.1'
|
|
90
|
-
type: :runtime
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - "~>"
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '1.1'
|
|
97
|
-
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: build-makefile
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - "~>"
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '1.0'
|
|
104
|
-
type: :development
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - "~>"
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '1.0'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: bundler
|
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
|
114
|
-
requirements:
|
|
115
|
-
- - ">="
|
|
116
|
-
- !ruby/object:Gem::Version
|
|
117
|
-
version: '0'
|
|
118
|
-
type: :development
|
|
119
|
-
prerelease: false
|
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - ">="
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
version: '0'
|
|
125
|
-
- !ruby/object:Gem::Dependency
|
|
126
|
-
name: covered
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
132
|
-
type: :development
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0'
|
|
139
|
-
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: rake
|
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
|
142
|
-
requirements:
|
|
143
|
-
- - ">="
|
|
144
|
-
- !ruby/object:Gem::Version
|
|
145
|
-
version: '0'
|
|
146
|
-
type: :development
|
|
147
|
-
prerelease: false
|
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
-
requirements:
|
|
150
|
-
- - ">="
|
|
151
|
-
- !ruby/object:Gem::Version
|
|
152
|
-
version: '0'
|
|
153
|
-
- !ruby/object:Gem::Dependency
|
|
154
|
-
name: rspec
|
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
|
156
|
-
requirements:
|
|
157
|
-
- - "~>"
|
|
158
|
-
- !ruby/object:Gem::Version
|
|
159
|
-
version: '3.4'
|
|
160
|
-
type: :development
|
|
161
|
-
prerelease: false
|
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
-
requirements:
|
|
164
|
-
- - "~>"
|
|
165
|
-
- !ruby/object:Gem::Version
|
|
166
|
-
version: '3.4'
|
|
167
|
-
description:
|
|
168
|
-
email:
|
|
169
83
|
executables: []
|
|
170
84
|
extensions: []
|
|
171
85
|
extra_rdoc_files: []
|
|
172
86
|
files:
|
|
87
|
+
- context/getting-started.md
|
|
88
|
+
- context/index.yaml
|
|
89
|
+
- context/visualization.md
|
|
173
90
|
- lib/build/graph.rb
|
|
174
91
|
- lib/build/graph/edge.rb
|
|
175
92
|
- lib/build/graph/node.rb
|
|
176
93
|
- lib/build/graph/task.rb
|
|
177
94
|
- lib/build/graph/version.rb
|
|
95
|
+
- lib/build/graph/visualization.rb
|
|
178
96
|
- lib/build/graph/walker.rb
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
- spec/build/graph/inherit_spec.rb
|
|
183
|
-
- spec/build/graph/listing.txt
|
|
184
|
-
- spec/build/graph/node_spec.rb
|
|
185
|
-
- spec/build/graph/process_graph.rb
|
|
186
|
-
- spec/build/graph/program/Benchmark.cpp
|
|
187
|
-
- spec/build/graph/program/Benchmark.cpp.d
|
|
188
|
-
- spec/build/graph/program/Benchmark.cpp.o
|
|
189
|
-
- spec/build/graph/program/Benchmark.h
|
|
190
|
-
- spec/build/graph/program/DictionarySort.h
|
|
191
|
-
- spec/build/graph/program/ParallelMergeSort.h
|
|
192
|
-
- spec/build/graph/program/dictionary-sort
|
|
193
|
-
- spec/build/graph/program/main.cpp
|
|
194
|
-
- spec/build/graph/program/main.cpp.d
|
|
195
|
-
- spec/build/graph/program/main.cpp.o
|
|
196
|
-
- spec/build/graph/task_spec.rb
|
|
197
|
-
- spec/build/graph/walker_spec.rb
|
|
198
|
-
- spec/spec_helper.rb
|
|
199
|
-
homepage:
|
|
97
|
+
- license.md
|
|
98
|
+
- readme.md
|
|
99
|
+
- releases.md
|
|
200
100
|
licenses:
|
|
201
101
|
- MIT
|
|
202
|
-
metadata:
|
|
203
|
-
|
|
102
|
+
metadata:
|
|
103
|
+
documentation_uri: https://ioquatix.github.io/build-graph
|
|
104
|
+
funding_uri: https://github.com/sponsors/ioquatix
|
|
105
|
+
source_code_uri: https://github.com/ioquatix/build-graph.git
|
|
204
106
|
rdoc_options: []
|
|
205
107
|
require_paths:
|
|
206
108
|
- lib
|
|
@@ -208,15 +110,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
208
110
|
requirements:
|
|
209
111
|
- - ">="
|
|
210
112
|
- !ruby/object:Gem::Version
|
|
211
|
-
version: '
|
|
113
|
+
version: '3.3'
|
|
212
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
213
115
|
requirements:
|
|
214
116
|
- - ">="
|
|
215
117
|
- !ruby/object:Gem::Version
|
|
216
118
|
version: '0'
|
|
217
119
|
requirements: []
|
|
218
|
-
rubygems_version:
|
|
219
|
-
signing_key:
|
|
120
|
+
rubygems_version: 4.0.6
|
|
220
121
|
specification_version: 4
|
|
221
122
|
summary: Build::Graph is a framework for build systems, with specific functionality
|
|
222
123
|
for dealing with file based processes.
|
metadata.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
|
|
4
|
-
|
|
5
|
-
require 'graphviz'
|
|
6
|
-
require_relative 'process_graph'
|
|
7
|
-
|
|
8
|
-
include ProcessGraph
|
|
9
|
-
|
|
10
|
-
program_root = Path.join(__dir__, "program")
|
|
11
|
-
code_glob = Glob.new(program_root, "*.cpp")
|
|
12
|
-
program_path = Path.join(program_root, "dictionary-sort")
|
|
13
|
-
|
|
14
|
-
group = Process::Group.new
|
|
15
|
-
walker = Walker.for(ProcessTask, group)
|
|
16
|
-
|
|
17
|
-
top = ProcessNode.top code_glob, title: 'top' do
|
|
18
|
-
process code_glob, program_path, title: 'build' do
|
|
19
|
-
object_files = inputs.with(extension: ".o") do |input_path, output_path|
|
|
20
|
-
depfile_path = input_path + ".d"
|
|
21
|
-
|
|
22
|
-
dependencies = Paths.new(input_path)
|
|
23
|
-
|
|
24
|
-
if File.exist? depfile_path
|
|
25
|
-
depfile = Build::Makefile.load_file(depfile_path)
|
|
26
|
-
|
|
27
|
-
dependencies = depfile[output_path] || dependencies
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
process dependencies, output_path, title: 'compile' do
|
|
31
|
-
run("clang++", "-MMD", "-O3",
|
|
32
|
-
"-o", output_path.shortest_path(input_path.root),
|
|
33
|
-
"-c", input_path.relative_path, "-std=c++11",
|
|
34
|
-
chdir: input_path.root
|
|
35
|
-
)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
process object_files, program_path, title: 'link' do
|
|
40
|
-
run("clang++", "-O3", "-o", program_path, *object_files.to_a, "-lm", "-pthread")
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
process program_path, title: 'run' do
|
|
45
|
-
run("./" + program_path.relative_path, chdir: program_path.root)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
interrupted = false
|
|
50
|
-
|
|
51
|
-
trap(:INT) do
|
|
52
|
-
exit(0)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
viz = Graphviz::Graph.new
|
|
56
|
-
viz.attributes[:rankdir] = 'LR'
|
|
57
|
-
|
|
58
|
-
walker.run do
|
|
59
|
-
group.wait do
|
|
60
|
-
walker.update(top)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
walker.tasks.each do |node, task|
|
|
64
|
-
input_nodes = []
|
|
65
|
-
output_nodes = []
|
|
66
|
-
|
|
67
|
-
task.inputs.each do |path|
|
|
68
|
-
input_nodes << viz.add_node(path.basename)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
task.outputs.each do |path|
|
|
72
|
-
output_nodes << viz.add_node(path.basename)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
if output_nodes.size == 1
|
|
76
|
-
input_nodes.each do |input_node|
|
|
77
|
-
edge = input_node.connect(output_nodes.first)
|
|
78
|
-
edge.attributes[:label] = node.title
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
File.write('graph.dot', viz.to_dot)
|
|
84
|
-
`dot -Tpdf graph.dot > graph.pdf && open graph.pdf`
|
|
85
|
-
end
|