build-graph 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ # Copyright, 2012, 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.
20
+
21
+ require 'test/unit'
22
+
23
+ require 'build/graph'
24
+ require 'build/files'
25
+ require 'build/system/pool'
26
+
27
+ class TestGraph < Test::Unit::TestCase
28
+ # The graph node is created once, so a graph has a fixed number of nodes, which store per-vertex state and connectivity.
29
+ class Node < Build::Node
30
+ def initialize(graph, inputs, outputs, &update)
31
+ @update = update
32
+
33
+ super(graph, inputs, outputs)
34
+ end
35
+
36
+ def apply!(scope)
37
+ scope.instance_eval(&@update)
38
+ end
39
+
40
+ # This ensures that enclosed nodes are run if they are dirty. The top level node has no inputs or outputs by default, so children who become dirty wouldn't mark it as dirty and thus wouldn't be run.
41
+ def requires_update?
42
+ if outputs.count == 0
43
+ return true
44
+ else
45
+ super
46
+ end
47
+ end
48
+ end
49
+
50
+ # The task is the context in which a vertex is updated. Because nodes may initially create other nodes, it is also responsible for looking up and creating new nodes.
51
+ class Task < Build::Task
52
+ def initialize(graph, walker, node, pool = nil)
53
+ super(graph, walker, node)
54
+
55
+ @pool = pool
56
+ end
57
+
58
+ def wet?
59
+ @pool# and @node.dirty?
60
+ end
61
+
62
+ def process(inputs, outputs, &block)
63
+ child_node = @graph.nodes.fetch([inputs, outputs]) do |key|
64
+ @graph.nodes[key] = Node.new(@graph, inputs, outputs, &block)
65
+ end
66
+
67
+ @children << child_node
68
+
69
+ # State saved in update!
70
+ child_node.update!(@walker)
71
+ end
72
+
73
+ def run(*arguments)
74
+ if wet?
75
+ status = @pool.run(*arguments)
76
+
77
+ if status != 0
78
+ raise CommandFailure.new(arguments, status)
79
+ end
80
+ end
81
+ end
82
+
83
+ def visit
84
+ super do
85
+ @node.apply!(self)
86
+ end
87
+ end
88
+ end
89
+
90
+ class Graph < Build::Graph
91
+ def initialize
92
+ yield self
93
+
94
+ super()
95
+ end
96
+
97
+ attr_accessor :top
98
+
99
+ def traverse!(walker)
100
+ @top.update!(walker)
101
+ end
102
+
103
+ def build_graph!
104
+ puts "Building graph..."
105
+
106
+ super do |walker, node|
107
+ Task.new(self, walker, node)
108
+ end
109
+ end
110
+
111
+ def update!
112
+ puts "Updating graph..."
113
+
114
+ pool = Build::System::Pool.new
115
+
116
+ super do |walker, node|
117
+ Task.new(self, walker, node, pool)
118
+ end
119
+
120
+ pool.wait
121
+ end
122
+ end
123
+
124
+ def test_minimal_graph
125
+ test_glob = Build::Files::Glob.new(__dir__, "*.rb")
126
+ output_paths = Build::Files::Paths.new(__dir__, ["listing.txt"])
127
+
128
+ FileUtils.rm_f output_paths.to_a
129
+
130
+ graph = Graph.new do |graph|
131
+ graph.top = Node.new(graph, Build::Files::NONE, Build::Files::NONE) do
132
+ process test_glob, output_paths do
133
+ run("ls", "-la", *test_glob, :out => output_paths.first)
134
+ end
135
+ end
136
+ end
137
+
138
+ graph.update!
139
+
140
+ mtime = File.mtime(output_paths.first)
141
+
142
+ graph.update!
143
+
144
+ assert_equal mtime, File.mtime(output_paths.first)
145
+
146
+ FileUtils.rm_f output_paths.to_a
147
+ end
148
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: build-graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: system
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rainbow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: "\tBuild::Graph is a framework for managing file-system based build processes.
70
+ It provides graph based build functionality which monitors the file-system for changes.
71
+ Because of this, it can efficiently manage large and complex process based builds.\n"
72
+ email:
73
+ - samuel.williams@oriontransfer.co.nz
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - Gemfile
80
+ - README.md
81
+ - Rakefile
82
+ - build-graph.gemspec
83
+ - lib/build.rb
84
+ - lib/build/edge.rb
85
+ - lib/build/error.rb
86
+ - lib/build/files.rb
87
+ - lib/build/graph.rb
88
+ - lib/build/node.rb
89
+ - lib/build/system/monitor.rb
90
+ - lib/build/system/pool.rb
91
+ - lib/build/system/state.rb
92
+ - lib/build/version.rb
93
+ - lib/build/walker.rb
94
+ - test/test_files.rb
95
+ - test/test_graph.rb
96
+ homepage: ''
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Build::Graph is a framework for build systems, with specific functionality
120
+ for dealing with file based processes.
121
+ test_files:
122
+ - test/test_files.rb
123
+ - test/test_graph.rb