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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/context/getting-started.md +65 -0
  4. data/context/index.yaml +18 -0
  5. data/context/visualization.md +79 -0
  6. data/lib/build/graph/edge.rb +9 -20
  7. data/lib/build/graph/node.rb +15 -21
  8. data/lib/build/graph/task.rb +37 -20
  9. data/lib/build/graph/version.rb +7 -20
  10. data/lib/build/graph/visualization.rb +55 -0
  11. data/lib/build/graph/walker.rb +43 -43
  12. data/lib/build/graph.rb +9 -27
  13. data/license.md +21 -0
  14. data/readme.md +59 -0
  15. data/releases.md +9 -0
  16. data.tar.gz.sig +0 -0
  17. metadata +43 -142
  18. metadata.gz.sig +0 -0
  19. data/spec/build/graph/build_test.rb +0 -85
  20. data/spec/build/graph/edge_spec.rb +0 -39
  21. data/spec/build/graph/graph_spec.rb +0 -172
  22. data/spec/build/graph/inherit_spec.rb +0 -51
  23. data/spec/build/graph/listing.txt +0 -8
  24. data/spec/build/graph/node_spec.rb +0 -80
  25. data/spec/build/graph/process_graph.rb +0 -98
  26. data/spec/build/graph/program/Benchmark.cpp +0 -72
  27. data/spec/build/graph/program/Benchmark.cpp.d +0 -1
  28. data/spec/build/graph/program/Benchmark.cpp.o +0 -0
  29. data/spec/build/graph/program/Benchmark.h +0 -65
  30. data/spec/build/graph/program/DictionarySort.h +0 -270
  31. data/spec/build/graph/program/ParallelMergeSort.h +0 -278
  32. data/spec/build/graph/program/dictionary-sort +0 -0
  33. data/spec/build/graph/program/main.cpp +0 -131
  34. data/spec/build/graph/program/main.cpp.d +0 -1
  35. data/spec/build/graph/program/main.cpp.o +0 -0
  36. data/spec/build/graph/task_spec.rb +0 -69
  37. data/spec/build/graph/walker_spec.rb +0 -125
  38. data/spec/spec_helper.rb +0 -13
@@ -1,35 +1,23 @@
1
- # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
- require 'set'
22
- require 'console'
23
- require 'build/files/monitor'
3
+ # Released under the MIT License.
4
+ # Copyright, 2014-2026, by Samuel Williams.
24
5
 
25
- require_relative 'task'
26
- require_relative 'node'
27
- require_relative 'edge'
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
- def initialize(logger: Console.logger, &block)
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
- @logger = logger
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
- @logger&.debug(self) {"Update: #{node} #{parent_task.class}"}
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
- @logger&.debug(self) {"Task #{task} is waiting on path #{path}"}
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
- @logger&.warn(self) {"Task #{task} is waiting on paths which don't exist and are not being generated!"}
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
- @logger&.debug(self) {"Task #{parent} is waiting on #{children.count} children"}
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
- @logger&.debug(self) do |buffer|
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
- @logger&.debug(self) {"File #{task.failed? ? 'failed' : 'available'}: #{path}"}
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
- # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
- require_relative 'graph/task'
22
- require_relative 'graph/node'
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
- module Build
27
- module Graph
28
- end
29
- end
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
+ [![Development Status](https://github.com/ioquatix/build-graph/workflows/Test/badge.svg)](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
@@ -0,0 +1,9 @@
1
+ # Releases
2
+
3
+ ## v2.3.0
4
+
5
+ - Add `Build::Graph::Visualization` for generating Mermaid diagrams of the build graph.
6
+
7
+ ## v2.2.0
8
+
9
+ - Remove `logger` interface.
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.1.1
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
- MIIEhDCCAuygAwIBAgIBATANBgkqhkiG9w0BAQsFADA3MTUwMwYDVQQDDCxzYW11
14
- ZWwud2lsbGlhbXMvREM9b3Jpb250cmFuc2Zlci9EQz1jby9EQz1uejAeFw0yMTA4
15
- MTYwNjMzNDRaFw0yMjA4MTYwNjMzNDRaMDcxNTAzBgNVBAMMLHNhbXVlbC53aWxs
16
- aWFtcy9EQz1vcmlvbnRyYW5zZmVyL0RDPWNvL0RDPW56MIIBojANBgkqhkiG9w0B
17
- AQEFAAOCAY8AMIIBigKCAYEAyXLSS/cw+fXJ5e7hi+U/TeChPWeYdwJojDsFY1xr
18
- xvtqbTTL8gbLHz5LW3QD2nfwCv3qTlw0qI3Ie7a9VMJMbSvgVEGEfQirqIgJXWMj
19
- eNMDgKsMJtC7u/43abRKx7TCURW3iWyR19NRngsJJmaR51yGGGm2Kfsr+JtKKLtL
20
- L188Wm3f13KAx7QJU8qyuBnj1/gWem076hzdA7xi1DbrZrch9GCRz62xymJlrJHn
21
- 9iZEZ7AxrS7vokhMlzSr/XMUihx/8aFKtk+tMLClqxZSmBWIErWdicCGTULXCBNb
22
- E/mljo4zEVKhlTWpJklMIhr55ZRrSarKFuW7en0+tpJrfsYiAmXMJNi4XAYJH7uL
23
- rgJuJwSaa/dMz+VmUoo7VKtSfCoOI+6v5/z0sK3oT6sG6ZwyI47DBq2XqNC6tnAj
24
- w+XmCywiTQrFzMMAvcA7rPI4F0nU1rZId51rOvvfxaONp+wgTi4P8owZLw0/j0m4
25
- 8C20DYi6EYx4AHDXiLpElWh3AgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8E
26
- BAMCBLAwHQYDVR0OBBYEFB6ZaeWKxQjGTI+pmz7cKRmMIywwMC4GA1UdEQQnMCWB
27
- I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWB
28
- I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEB
29
- CwUAA4IBgQBVoM+pu3dpdUhZM1w051iw5GfiqclAr1Psypf16Tiod/ho//4oAu6T
30
- 9fj3DPX/acWV9P/FScvqo4Qgv6g4VWO5ZU7z2JmPoTXZtYMunRAmQPFL/gSUc6aK
31
- vszMHIyhtyzRc6DnfW2AiVOjMBjaYv8xXZc9bduniRVPrLR4J7ozmGLh4o4uJp7w
32
- x9KCFaR8Lvn/r0oJWJOqb/DMAYI83YeN2Dlt3jpwrsmsONrtC5S3gOUle5afSGos
33
- bYt5ocnEpKSomR9ZtnCGljds/aeO1Xgpn2r9HHcjwnH346iNrnHmMlC7BtHUFPDg
34
- Ts92S47PTOXzwPBDsrFiq3VLbRjHSwf8rpqybQBH9MfzxGGxTaETQYOd6b4e4Ag6
35
- y92abGna0bmIEb4+Tx9rQ10Uijh1POzvr/VTH4bbIPy9FbKrRsIQ24qDbNJRtOpE
36
- RAOsIl+HOBTb252nx1kIRN5hqQx272AJCbCjKx8egcUQKffFVVCI0nye09v5CK+a
37
- HiLJ8VOFx6w=
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: 2022-05-23 00:00:00.000000000 Z
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.2'
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.2'
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
- - spec/build/graph/build_test.rb
180
- - spec/build/graph/edge_spec.rb
181
- - spec/build/graph/graph_spec.rb
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
- post_install_message:
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: '2.0'
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: 3.3.7
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