build-graph 2.1.0 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb179cd3a48c30a2fb5dcc01ade33eb66aab7b597dc7d0c4ae1739f0562edddc
4
- data.tar.gz: ec3a78844f5b0f50c577a5587acdde79b83c38f09c6fe8b559cdf2c486354478
3
+ metadata.gz: c1db7b0de55419c77b5c17f17e93f4e62304a93872265545cce248c58d78e1c8
4
+ data.tar.gz: 989d5bae8d7eb3b324648cf64eecdd999c8f5104a849bd5715cab8cd7ad26079
5
5
  SHA512:
6
- metadata.gz: 9d4466a13a69a633ac5c287b555ea5ee18a1da102bfae04c4fb6e899f52ec1d991bcbbfc45dc3aff0d9d8cc83e9cd30d25c2e6d2cd1a47036d9f24479641ab59
7
- data.tar.gz: 5253545e060ddb2712b766df41973e2d2b5747d3f3c5b22e2f4956aa245101fe90b1cbcd5c9a1215faf24b36949b6351b9f4994ee46c85418d2f50f007da80c8
6
+ metadata.gz: 93c3f170fb2ad8da49f56d30248e8403e504f8fef5e562f19cd3280cfa60471cc09b0dc440a6d7f3c63fef7c8da25e1da5e6faacce446c91cbb6e3d9ced740fb
7
+ data.tar.gz: '0382b9651118034b7aebdfcfa7a0599adf430172ac3ec0243905728b2a2326ca621c44011d7d5a071308e4c1e3bdb83977292fd6a3f9ef2c0b141488edf27329'
checksums.yaml.gz.sig ADDED
Binary file
@@ -1,29 +1,16 @@
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 'fiber'
3
+ # Released under the MIT License.
4
+ # Copyright, 2014-2026, by Samuel Williams.
5
+
6
+ require "fiber"
22
7
 
23
8
  module Build
24
9
  module Graph
25
10
  # Represents a set of inputs to a graph node.
26
11
  class Edge
12
+ # Create a new edge, optionally pre-populated with a number of pending traversals.
13
+ # @parameter count [Integer] the initial number of pending traversals.
27
14
  def initialize(count = 0)
28
15
  @fiber = Fiber.current
29
16
 
@@ -48,10 +35,12 @@ module Build
48
35
  succeeded?
49
36
  end
50
37
 
38
+ # @returns [Boolean] whether any traversing task failed.
51
39
  def failed?
52
40
  @failed.size != 0
53
41
  end
54
42
 
43
+ # @returns [Boolean] whether all traversing tasks succeeded.
55
44
  def succeeded?
56
45
  @failed.size == 0
57
46
  end
@@ -1,25 +1,10 @@
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 'build/files/state'
22
- require 'build/files'
3
+ # Released under the MIT License.
4
+ # Copyright, 2014-2026, by Samuel Williams.
5
+
6
+ require "build/files/state"
7
+ require "build/files"
23
8
 
24
9
  module Build
25
10
  module Graph
@@ -44,6 +29,7 @@ module Build
44
29
  @inputs.map{|path| path.modified_time}.max
45
30
  end
46
31
 
32
+ # @returns [Boolean] whether any input or output file is missing from the filesystem.
47
33
  def missing?
48
34
  @outputs.any?{|path| !path.exist?} || @inputs.any?{|path| !path.exist?}
49
35
  end
@@ -74,6 +60,7 @@ module Build
74
60
  return false
75
61
  end
76
62
 
63
+ # @returns [Boolean] whether this node is equal to another by comparing inputs and outputs.
77
64
  def == other
78
65
  self.equal?(other) or
79
66
  self.class == other.class and
@@ -81,18 +68,25 @@ module Build
81
68
  @outputs == other.outputs
82
69
  end
83
70
 
71
+ # @returns [Boolean] whether this node is equal to another, for use in Hash and Set.
84
72
  def eql?(other)
85
73
  self.equal?(other) or self == other
86
74
  end
87
75
 
76
+ # @returns [Integer] a hash value derived from inputs and outputs.
88
77
  def hash
89
78
  @inputs.hash ^ @outputs.hash
90
79
  end
91
80
 
81
+ # @returns [String] a human-readable representation of the node.
92
82
  def inspect
93
83
  "#<#{self.class} #{@inputs.inspect} => #{@outputs.inspect}>"
94
84
  end
95
85
 
86
+ # Create a top-level node that inherits its outputs from its children.
87
+ # @parameter inputs [Build::Files::List] the input files for this node.
88
+ # @parameter outputs [Symbol] the output strategy, defaults to `:inherit`.
89
+ # @returns [Node] the constructed top-level node.
96
90
  def self.top(inputs = Files::Paths::NONE, outputs = :inherit, **options, &block)
97
91
  self.new(inputs, outputs, block, **options)
98
92
  end
@@ -1,41 +1,35 @@
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
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2015-2026, by Samuel Williams.
20
5
 
21
6
  module Build
22
7
  module Graph
8
+ # An error that represents a transient build failure which can be retried.
23
9
  class TransientError < StandardError
24
10
  end
25
11
 
12
+ # Mixed in to errors raised when child tasks have failed.
26
13
  module ChildrenFailed
14
+ # @returns [String] a human-readable error message.
27
15
  def self.to_s
28
16
  "Children tasks failed!"
29
17
  end
30
18
  end
31
19
 
20
+ # Mixed in to errors raised when tasks generating inputs have failed.
32
21
  module InputsFailed
22
+ # @returns [String] a human-readable error message.
33
23
  def self.to_s
34
24
  "Tasks generating inputs failed!"
35
25
  end
36
26
  end
37
27
 
28
+ # Represents a single unit of work within a build graph walk.
38
29
  class Task
30
+ # Create a new task associated with the given walker and node.
31
+ # @parameter walker [Walker] the walker driving the graph traversal.
32
+ # @parameter node [Node] the node this task is responsible for updating.
39
33
  def initialize(walker, node)
40
34
  @walker = walker
41
35
 
@@ -124,10 +118,12 @@ module Build
124
118
  return child_task
125
119
  end
126
120
 
121
+ # @returns [Boolean] whether the task has failed.
127
122
  def failed?
128
123
  @state == :failed
129
124
  end
130
125
 
126
+ # @returns [Boolean] whether the task has completed successfully.
131
127
  def complete?
132
128
  @state == :complete
133
129
  end
@@ -142,18 +138,22 @@ module Build
142
138
  end
143
139
  end
144
140
 
141
+ # Resets the node in the walker if inputs or outputs have changed since the last run.
145
142
  def changed!
146
143
  @walker.delete(@node) if (@inputs.update! or @outputs.update!)
147
144
  end
148
145
 
146
+ # @returns [Array(String)] the list of root directories for all input and output paths.
149
147
  def directories
150
148
  (@inputs.roots + @outputs.roots).collect{|path| path.to_s}
151
149
  end
152
150
 
151
+ # @returns [String] a short human-readable summary of the task.
153
152
  def to_s
154
153
  "#<#{self.class} #{node_string} #{state_string}>"
155
154
  end
156
155
 
156
+ # @returns [String] a detailed human-readable representation including object identity.
157
157
  def inspect
158
158
  "\#<#{self.class}:0x#{self.object_id.to_s(16)} #{node_string} #{state_string}>"
159
159
  end
@@ -210,7 +210,7 @@ module Build
210
210
 
211
211
  # Fail the task with the given error. Any task which is waiting on this task will also fail (eventually).
212
212
  def fail!(error)
213
- @walker.logger&.error(self) {error}
213
+ Console.error(self, "Task failed!", exception: error)
214
214
 
215
215
  @error = error
216
216
  @state = :failed
@@ -1,25 +1,12 @@
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
 
3
+ # Released under the MIT License.
4
+ # Copyright, 2014-2026, by Samuel Williams.
5
+
6
+ # @namespace
21
7
  module Build
8
+ # @namespace
22
9
  module Graph
23
- VERSION = "2.1.0"
10
+ VERSION = "2.2.0"
24
11
  end
25
12
  end
@@ -1,34 +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'
3
+ # Released under the MIT License.
4
+ # Copyright, 2014-2026, by Samuel Williams.
23
5
 
24
- require_relative 'task'
25
- require_relative 'node'
26
- 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"
27
13
 
28
14
  module Build
29
15
  module Graph
30
16
  # A walker walks over a graph and applies a task to each node.
31
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.
32
21
  def self.for(task_class, *args, **options)
33
22
  self.new(**options) do |walker, node, parent_task = nil|
34
23
  task = task_class.new(walker, node, *args)
@@ -39,7 +28,9 @@ module Build
39
28
  end
40
29
  end
41
30
 
42
- 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)
43
34
  # Node -> Task mapping.
44
35
  @tasks = {}
45
36
 
@@ -54,13 +45,9 @@ module Build
54
45
  @failed_tasks = []
55
46
  @failed_outputs = Set.new
56
47
 
57
- @logger = logger
58
- @monitor = Files::Monitor.new(logger: @logger)
48
+ @monitor = Files::Monitor.new
59
49
  end
60
50
 
61
- # Primarily for debugging from within Task
62
- attr :logger
63
-
64
51
  # An Array of all instantiated tasks.
65
52
  attr :tasks
66
53
 
@@ -77,16 +64,22 @@ module Build
77
64
 
78
65
  attr :monitor
79
66
 
67
+ # Invoke the walker for each node in the given collection.
68
+ # @parameter nodes [Enumerable] the nodes to update.
80
69
  def update(nodes)
81
70
  Array(nodes).each do |node|
82
71
  self.call(node)
83
72
  end
84
73
  end
85
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.
86
79
  def call(node, parent_task = nil)
87
80
  # We try to fetch the task if it has already been invoked, otherwise we create a new task.
88
81
  @tasks.fetch(node) do
89
- @logger&.debug(self) {"Update: #{node} #{parent_task.class}"}
82
+ Console.debug(self){"Update: #{node} #{parent_task.class}"}
90
83
 
91
84
  # This method should add the node
92
85
  @update.call(self, node, parent_task)
@@ -96,10 +89,15 @@ module Build
96
89
  end
97
90
  end
98
91
 
92
+ # @returns [Boolean] whether any tasks have failed during this walk.
99
93
  def failed?
100
94
  @failed_tasks.size > 0
101
95
  end
102
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.
103
101
  def wait_on_paths(task, paths)
104
102
  # If there are no paths, we are done:
105
103
  return true if paths.count == 0
@@ -112,13 +110,13 @@ module Build
112
110
  paths.each do |path|
113
111
  # Is there a task generating this output?
114
112
  if outputs = @outputs[path]
115
- @logger&.debug(self) {"Task #{task} is waiting on path #{path}"}
113
+ Console.debug(self){"Task #{task} is waiting on path #{path}"}
116
114
 
117
115
  # When the output is ready, trigger this edge:
118
116
  outputs << edge
119
117
  edge.increment!
120
118
  elsif !File.exist?(path)
121
- @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!"}
122
120
  raise RuntimeError, "File #{path} is not being generated by any active task!"
123
121
  # What should we do about paths which haven't been registered as outputs?
124
122
  # Either they exist - or they don't.
@@ -140,7 +138,7 @@ module Build
140
138
  # If there are no children like this, then done:
141
139
  return true if children.size == 0
142
140
 
143
- @logger&.debug(self) {"Task #{parent} is waiting on #{children.count} children"}
141
+ Console.debug(self){"Task #{parent} is waiting on #{children.count} children"}
144
142
 
145
143
  # Otherwise, construct an edge to track state changes:
146
144
  edge = Edge.new
@@ -159,15 +157,16 @@ module Build
159
157
  return edge.wait
160
158
  end
161
159
 
160
+ # Register a task as active and record its declared output paths.
161
+ # @parameter task [Task] the task that is beginning execution.
162
162
  def enter(task)
163
- @logger&.debug(self) {"Walker entering: #{task.node}"}
164
163
 
165
164
  @tasks[task.node] = task
166
165
 
167
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.
168
167
 
169
168
  if outputs = task.outputs
170
- @logger&.debug(self) do |buffer|
169
+ Console.debug(self) do |buffer|
171
170
  buffer.puts "Task will generate outputs:"
172
171
  Array(outputs).each do |output|
173
172
  buffer.puts output.inspect
@@ -181,8 +180,9 @@ module Build
181
180
  end
182
181
  end
183
182
 
183
+ # Mark a task as finished, resolve its output paths and notify any waiting tasks.
184
+ # @parameter task [Task] the task that has finished execution.
184
185
  def exit(task)
185
- @logger&.debug(self) {"Walker exiting: #{task.node}, task #{task.failed? ? 'failed' : 'succeeded'}"}
186
186
 
187
187
  # Fail outputs if the node failed:
188
188
  if task.failed?
@@ -197,7 +197,7 @@ module Build
197
197
  task.outputs.each do |path|
198
198
  path = path.to_s
199
199
 
200
- @logger&.debug(self) {"File #{task.failed? ? 'failed' : 'available'}: #{path}"}
200
+ Console.debug(self){"File #{task.failed? ? 'failed' : 'available'}: #{path}"}
201
201
 
202
202
  if edges = @outputs.delete(path)
203
203
  # @logger&.debug "\tUpdating #{edges.count} edges..."
@@ -213,14 +213,16 @@ module Build
213
213
  @monitor.add(task)
214
214
  end
215
215
 
216
+ # Remove a node and its associated task from the walker, e.g. after it has been invalidated.
217
+ # @parameter node [Node] the node to remove.
216
218
  def delete(node)
217
- @logger&.debug(self) {"Delete #{node}"}
218
-
219
+
219
220
  if task = @tasks.delete(node)
220
221
  @monitor.delete(task)
221
222
  end
222
223
  end
223
224
 
225
+ # Remove all failed tasks from the walker so they can be retried on the next update.
224
226
  def clear_failed
225
227
  @failed_tasks.each do |task|
226
228
  self.delete(task.node)
@@ -230,6 +232,7 @@ module Build
230
232
  @failed_outputs = Set.new
231
233
  end
232
234
 
235
+ # Run an update loop, re-executing the given block whenever the monitor detects filesystem changes.
233
236
  def run(**options)
234
237
  yield
235
238
 
@@ -238,6 +241,7 @@ module Build
238
241
  end
239
242
  end
240
243
 
244
+ # @returns [String] a human-readable summary of the walker state.
241
245
  def inspect
242
246
  "\#<#{self.class}:0x#{self.object_id.to_s(16)} #{@tasks.count} tasks, #{@failed_tasks.count} failed>"
243
247
  end
data/lib/build/graph.rb CHANGED
@@ -1,29 +1,10 @@
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"
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,37 @@
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
+ ## Releases
14
+
15
+ Please see the [project releases](https://ioquatix.github.io/build-graphreleases/index) for all releases.
16
+
17
+ ### v2.2.0
18
+
19
+ - Remove `logger` interface.
20
+
21
+ ## Contributing
22
+
23
+ We welcome contributions to this project.
24
+
25
+ 1. Fork it.
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
28
+ 4. Push to the branch (`git push origin my-new-feature`).
29
+ 5. Create new Pull Request.
30
+
31
+ ### Developer Certificate of Origin
32
+
33
+ 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.
34
+
35
+ ### Community Guidelines
36
+
37
+ 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,5 @@
1
+ # Releases
2
+
3
+ ## v2.2.0
4
+
5
+ - Remove `logger` interface.
data.tar.gz.sig ADDED
Binary file