build 2.4.4 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b7921d3b8f07853ccccdd021aeba784001c856078cbd272bad7948dda19199a
4
- data.tar.gz: e3ae69fe9aa59716ce07eb2e0755f75d8a9fe2e2b82b66b73f73fbbcfdfcad0e
3
+ metadata.gz: 0ad08615d58ed88206dd99c9a77400daf263343bf9e00d8c724cc73050abb702
4
+ data.tar.gz: 840fde0567eccfce19a4eb3b99219f8aec9d798ca6443a67dafa825bef8c01df
5
5
  SHA512:
6
- metadata.gz: 96f81bd9b9b8d61e0d4409c66d4731083cae8836fe04b693fe68b3a2e106fc3040f4ea80f92c792dcdd894f6cdbffb252d95ecdc9e6c565ba87876b84ed2954c
7
- data.tar.gz: dd759132956ca254cbd977699ee32bdc22fcb537478de63d1a4b264462d24fb22ac6cecdcd3e043b71a9db55347cb8bca393115775eb5813dd327ce83c1faa25
6
+ metadata.gz: 86a6d619396f7215c3b816a12bfbfb4c6b3aecf57b83ae48a57549cddf94b4ee77d08a41ffcc222241c981d73fb3686b56b23f818044200512c0cfbda70fb61a
7
+ data.tar.gz: 99ff73db7486709ab8691d6243bffd28342bce8de5afc0783b90c72a396fccc15bd838e4ddfd8b3d25f212abdaa111d31ae5bf54402cd4a84306e1b7ed640794
data/.gitignore CHANGED
@@ -21,4 +21,3 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  .rspec_status
24
-
data/build.gemspec CHANGED
@@ -17,9 +17,9 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.required_ruby_version = '>= 2.0'
19
19
 
20
- spec.add_dependency "build-graph", "~> 1.3"
21
- spec.add_dependency "build-environment", "~> 1.3"
22
- spec.add_dependency "build-dependency", "~> 1.4"
20
+ spec.add_dependency "build-graph", "~> 2.1"
21
+ spec.add_dependency "build-environment", "~> 1.12"
22
+ spec.add_dependency "build-dependency", "~> 1.5"
23
23
  spec.add_dependency "build-makefile", "~> 1.0"
24
24
 
25
25
  spec.add_dependency "graphviz", "~> 1.0"
@@ -0,0 +1,181 @@
1
+ # Copyright, 2016, 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 'fileutils'
22
+ require 'build/graph'
23
+
24
+ require 'console/event/spawn'
25
+
26
+ module Build
27
+ class BuildNode < Graph::Node
28
+ def initialize(environment, provision, arguments)
29
+ @environment = environment
30
+ @provision = provision
31
+ @arguments = arguments
32
+
33
+ super(Files::List::NONE, :inherit)
34
+ end
35
+
36
+ attr :environment
37
+ attr :provision
38
+ attr :arguments
39
+
40
+ def == other
41
+ super and
42
+ @environment == other.environment and
43
+ @provision == other.provision and
44
+ @arguments == other.arguments
45
+ end
46
+
47
+ def hash
48
+ super ^ @environment.hash ^ @provision.hash ^ @arguments.hash
49
+ end
50
+
51
+ def task_class(parent_task)
52
+ task_class = Rulebook.for(@environment).with(BuildTask, environment: @environment)
53
+ end
54
+
55
+ def initial_environment
56
+ Build::Environment.new(@environment)
57
+ end
58
+
59
+ def name
60
+ @environment.name
61
+ end
62
+
63
+ def apply!(task)
64
+ output_environment = self.initial_environment
65
+
66
+ output_environment.construct!(task, *@arguments, &@provision.value)
67
+
68
+ task.output_environment = output_environment
69
+ end
70
+ end
71
+
72
+ # This task class serves as the base class for the environment specific task classes genearted when adding targets.
73
+ class BuildTask < Task
74
+ class CommandFailure < Graph::TransientError
75
+ def initialize(task, arguments, status)
76
+ @task = task
77
+ @arguments = arguments
78
+ @status = status
79
+
80
+ super "#{File.basename(executable_name).inspect} exited with status #{@status.to_i}"
81
+ end
82
+
83
+ def executable_name
84
+ if @arguments[0].kind_of? Hash
85
+ @arguments[1]
86
+ else
87
+ @arguments[0]
88
+ end
89
+ end
90
+
91
+ attr :task
92
+ attr :arguments
93
+ attr :status
94
+ end
95
+
96
+ attr_accessor :output_environment
97
+
98
+ def wet?
99
+ @node.dirty?
100
+ end
101
+
102
+ def spawn(*arguments)
103
+ if wet?
104
+ @logger&.info(self) {Console::Event::Spawn.for(*arguments)}
105
+ status = @group.spawn(*arguments)
106
+
107
+ if status != 0
108
+ raise CommandFailure.new(self, arguments, status)
109
+ end
110
+ end
111
+ end
112
+
113
+ def shell_environment
114
+ @shell_environment ||= environment.flatten.export
115
+ end
116
+
117
+ def run!(*arguments)
118
+ self.spawn(shell_environment, *arguments)
119
+ end
120
+
121
+ def touch(path)
122
+ return unless wet?
123
+
124
+ @logger&.info(self) {Console::Shell.for('touch', path)}
125
+ FileUtils.touch(path)
126
+ end
127
+
128
+ def cp(source_path, destination_path)
129
+ return unless wet?
130
+
131
+ @logger&.info(self) {Console::Shell.for('cp', source_path, destination_path)}
132
+ FileUtils.copy(source_path, destination_path)
133
+ end
134
+
135
+ def rm(path)
136
+ return unless wet?
137
+
138
+ @logger&.info(self) {Console::Shell.for('rm -rf', path)}
139
+ FileUtils.rm_rf(path)
140
+ end
141
+
142
+ def mkpath(path)
143
+ return unless wet?
144
+
145
+ unless File.exist?(path)
146
+ @logger&.info(self) {Console::Shell.for('mkpath', path)}
147
+ FileUtils.mkpath(path)
148
+ end
149
+ end
150
+
151
+ def install(source_path, destination_path)
152
+ return unless wet?
153
+
154
+ @logger&.info(self) {Console::Shell.for('install', source_path, destination_path)}
155
+ FileUtils.install(source_path, destination_path)
156
+ end
157
+
158
+ def write(path, data, mode = "w")
159
+ return unless wet?
160
+
161
+ @logger&.info(self) {Console::Shell.for("write", path, "#{data.size}bytes")}
162
+ File.open(path, mode) do |file|
163
+ file.write(data)
164
+ end
165
+ end
166
+
167
+ def invoke_rule(rule, arguments, &block)
168
+ arguments = rule.normalize(arguments, self)
169
+
170
+ @logger&.debug(self) {"-> #{rule}(#{arguments.inspect})"}
171
+
172
+ invoke(
173
+ RuleNode.new(rule, arguments, &block)
174
+ )
175
+
176
+ @logger&.debug(self) {"<- #{rule}(...) -> #{rule.result(arguments)}"}
177
+
178
+ return rule.result(arguments)
179
+ end
180
+ end
181
+ end
@@ -22,91 +22,58 @@ require 'build/files'
22
22
  require 'build/graph'
23
23
 
24
24
  require_relative 'task'
25
+ require_relative 'dependency_node'
25
26
 
26
27
  module Build
28
+ # Responsible for processing a chain into a series of dependency nodes.
27
29
  class ChainNode < Graph::Node
30
+ # @param chain [Chain] the chain to build.
31
+ # @param arguments [Array] the arguments to pass to the output environment constructor.
32
+ # @param anvironment [Build::Environment] the root environment to prepend into the chain.
28
33
  def initialize(chain, arguments, environment)
29
34
  @chain = chain
30
35
  @arguments = arguments
31
36
  @environment = environment
32
37
 
33
38
  # Wait here, for all dependent targets, to be done:
34
- super(Files::List::NONE, :inherit, chain)
39
+ super(Files::List::NONE, :inherit)
35
40
  end
36
41
 
37
- def name
38
- @environment.name
42
+ attr :chain
43
+ attr :arguments
44
+ attr :environment
45
+
46
+ def == other
47
+ super and
48
+ @chain == other.chain and
49
+ @arguments == other.arguments and
50
+ @environment == other.environment
39
51
  end
40
52
 
41
- def task_class
53
+ def hash
54
+ super ^ @chain.hash ^ @arguments.hash ^ @environment.hash
55
+ end
56
+
57
+ def task_class(parent_task)
42
58
  Task
43
59
  end
44
60
 
45
- def apply_dependency(scope, dependency)
46
- logger = scope.logger
47
-
48
- # logger.debug {"Traversing: #{dependency}..."}
49
-
50
- environments = [@environment]
51
- public_environments = []
52
- provisions = @chain.resolved[dependency]
53
- public_alias = dependency.alias?
54
-
55
- provisions.each do |provision|
56
- provision.each_dependency do |nested_dependency|
57
- if environment = apply_dependency(scope, nested_dependency)
58
- # logger.debug("Evaluating #{nested_dependency} -> #{provision} generated: #{environment}")
59
-
60
- environments << environment
61
-
62
- if public_alias || nested_dependency.public?
63
- public_environments << environment
64
- # else
65
- # logger.debug("Skipping #{nested_dependency} in public environment.")
66
- end
67
- end
68
- end
69
- end
70
-
71
- unless dependency.alias?
72
- logger.debug {"Building: #{dependency}"}
73
-
74
- # environments.each do |environment|
75
- # logger.debug {"Using #{environment}"}
76
- # end
77
-
78
- local_environment = Build::Environment.combine(*environments)&.evaluate || Build::Environment.new
79
-
80
- # logger.debug("Local Environment: #{local_environment}")
81
-
82
- task_class = Rulebook.for(local_environment).with(Task, environment: local_environment)
83
- task = task_class.new(scope.walker, self, scope.group, logger: scope.logger)
84
-
85
- output_environment = nil
86
-
87
- task.visit do
88
- output_environment = Build::Environment.new(local_environment, name: dependency.name)
89
-
90
- provisions.each do |provision|
91
- # When executing the environment build steps, we create new build nodes. But those build nodes are not capturing the right task class.
92
- output_environment.construct!(task, *@arguments, &provision.value)
93
- end
94
-
95
- public_environments << output_environment.dup(parent: nil, name: dependency.name)
96
- end
97
- end
98
-
99
- return Build::Environment.combine(*public_environments)
61
+ def name
62
+ @environment.name
100
63
  end
101
64
 
102
- def apply!(scope)
65
+ # This is the main entry point when invoking the node from `Build::Task`.
66
+ def apply!(task)
67
+ # Go through all the dependencies in order and apply them to the build graph:
103
68
  @chain.dependencies.each do |dependency|
104
- apply_dependency(scope, dependency)
69
+ task.invoke(
70
+ DependencyNode.new(@chain, dependency, @environment, @arguments)
71
+ )
105
72
  end
106
73
  end
107
74
 
108
- def to_s
109
- "#<#{self.class}>"
75
+ def inspect
76
+ "#<#{self.class} #{@environment.inspect}>"
110
77
  end
111
78
  end
112
79
  end
@@ -57,8 +57,8 @@ module Build
57
57
  attr :nodes
58
58
  attr :walker
59
59
 
60
- private def step(walker, node, parent_task = nil)
61
- task_class = parent_task&.class || Task
60
+ def step(walker, node, parent_task = nil)
61
+ task_class = node.task_class(parent_task) || Task
62
62
  task = task_class.new(walker, node, @group, logger: @logger)
63
63
 
64
64
  task.visit do
@@ -0,0 +1,127 @@
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 'build/graph'
22
+
23
+ require_relative 'provision_node'
24
+
25
+ module Build
26
+ class DependencyNode < Graph::Node
27
+ def initialize(chain, dependency, environment, arguments)
28
+ @chain = chain
29
+ @dependency = dependency
30
+ @environment = environment
31
+ @arguments = arguments
32
+
33
+ # Wait here, for all dependent targets, to be done:
34
+ super(Files::List::NONE, :inherit)
35
+ end
36
+
37
+ attr :chain
38
+ attr :dependency
39
+ attr :environment
40
+ attr :arguments
41
+
42
+ def == other
43
+ super and
44
+ @chain == other.chain and
45
+ @dependency == other.dependency and
46
+ @environment == other.environment and
47
+ @arguments == other.arguments
48
+ end
49
+
50
+ def hash
51
+ super ^ @chain.hash ^ @dependency.hash ^ @environment.hash ^ @arguments.hash
52
+ end
53
+
54
+ def task_class(parent_task)
55
+ DependencyTask
56
+ end
57
+
58
+ def name
59
+ @dependency.name
60
+ end
61
+
62
+ def provisions
63
+ @chain.resolved[@dependency]
64
+ end
65
+
66
+ def public?
67
+ @dependency.public?
68
+ end
69
+
70
+ def provision_node_for(provision)
71
+ ProvisionNode.new(@chain, provision, @environment, @arguments)
72
+ end
73
+ end
74
+
75
+ module ProvisionsFailed
76
+ def self.to_s
77
+ "Failed to build all provisions!"
78
+ end
79
+ end
80
+
81
+ class DependencyTask < Task
82
+ def initialize(*arguments, **options)
83
+ super
84
+
85
+ @provisions = []
86
+
87
+ @environments = nil
88
+ @environment = nil
89
+ end
90
+
91
+ attr :environment
92
+
93
+ def dependency
94
+ @node.dependency
95
+ end
96
+
97
+ def update
98
+ logger.debug(self) do |buffer|
99
+ buffer.puts "building #{@node} which #{@node.dependency}"
100
+ @node.provisions.each do |provision|
101
+ buffer.puts "\tbuilding #{provision.provider.name} which #{provision}"
102
+ end
103
+ end
104
+
105
+ # Lookup what things this dependency provides:
106
+ @node.provisions.each do |provision|
107
+ @provisions << invoke(
108
+ @node.provision_node_for(provision)
109
+ )
110
+ end
111
+
112
+ if wait_for_children?
113
+ update_environments!
114
+ else
115
+ fail!(ProvisionsFailed)
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def update_environments!
122
+ @environments = @provisions.flat_map(&:output_environments)
123
+
124
+ @environment = Build::Environment.combine(*@environments)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,146 @@
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 'build/graph'
22
+
23
+ require_relative 'build_node'
24
+
25
+ module Build
26
+ class ProvisionNode < Graph::Node
27
+ def initialize(chain, provision, environment, arguments)
28
+ @chain = chain
29
+ @provision = provision
30
+ @environment = environment
31
+ @arguments = arguments
32
+
33
+ # Wait here, for all dependent targets, to be done:
34
+ super(Files::List::NONE, :inherit)
35
+ end
36
+
37
+ attr :chain
38
+ attr :provision
39
+ attr :environment
40
+ attr :arguments
41
+
42
+ def == other
43
+ super and
44
+ @chain == other.chain and
45
+ @provision == other.provision and
46
+ @environment == other.environment and
47
+ @arguments == other.arguments
48
+ end
49
+
50
+ def hash
51
+ super ^ @chain.hash ^ @provision.hash ^ @environment.hash ^ @arguments.hash
52
+ end
53
+
54
+ def task_class(parent_task)
55
+ ProvisionTask
56
+ end
57
+
58
+ def name
59
+ @provision.name
60
+ end
61
+
62
+ def dependency_node_for(dependency)
63
+ DependencyNode.new(@chain, dependency, @environment, @arguments)
64
+ end
65
+ end
66
+
67
+ module DependenciesFailed
68
+ def self.to_s
69
+ "Failed to build all dependencies!"
70
+ end
71
+ end
72
+
73
+ class ProvisionTask < Task
74
+ def initialize(*arguments, **options)
75
+ super
76
+
77
+ @dependencies = []
78
+
79
+ @environments = []
80
+ @public_environments = []
81
+
82
+ @build_task = nil
83
+ end
84
+
85
+ attr :environments
86
+ attr :public_environments
87
+
88
+ attr :build_task
89
+
90
+ def provision
91
+ @node.provision
92
+ end
93
+
94
+ def update
95
+ provision.each_dependency do |dependency|
96
+ @dependencies << invoke(@node.dependency_node_for(dependency))
97
+ end
98
+
99
+ if wait_for_children?
100
+ update_environments!
101
+ else
102
+ fail!(DependenciesFailed)
103
+ end
104
+ end
105
+
106
+ def local_environment
107
+ Build::Environment.combine(@node.environment, *@environments)&.evaluate(name: @node.name).freeze
108
+ end
109
+
110
+ def output_environment
111
+ if @build_task
112
+ @build_task.output_environment.dup(parent: nil)
113
+ end
114
+ end
115
+
116
+ def output_environments
117
+ environments = @public_environments.dup
118
+
119
+ if environment = self.output_environment
120
+ environments << environment
121
+ end
122
+
123
+ return environments
124
+ end
125
+
126
+ private
127
+
128
+ def update_environments!
129
+ @dependencies.each do |task|
130
+ if environment = task.environment
131
+ @environments << environment
132
+
133
+ if task.dependency.public? || @node.provision.alias?
134
+ @public_environments << environment
135
+ end
136
+ end
137
+ end
138
+
139
+ unless @node.provision.alias?
140
+ @build_task = invoke(
141
+ BuildNode.new(local_environment, @node.provision, @node.arguments)
142
+ )
143
+ end
144
+ end
145
+ end
146
+ end
data/lib/build/rule.rb CHANGED
@@ -88,13 +88,15 @@ module Build
88
88
  def compute(arguments, scope)
89
89
  if implicit?
90
90
  # Can be replaced if supplied:
91
- arguments[@name] || scope.instance_exec(arguments, &@dynamic)
91
+ arguments[@name] || scope.instance_exec(arguments, &@dynamic) || @options[:default]
92
92
  elsif dynamic?
93
93
  # Argument is optional:
94
- scope.instance_exec(arguments[@name], arguments, &@dynamic)
95
- else
94
+ scope.instance_exec(arguments[@name], arguments, &@dynamic) || @options[:default]
95
+ elsif arguments.key?(@name)
96
96
  arguments[@name]
97
- end || @options[:default]
97
+ else
98
+ @options[:default]
99
+ end
98
100
  end
99
101
 
100
102
  def hash
@@ -30,13 +30,28 @@ module Build
30
30
 
31
31
  inputs, outputs = @rule.files(@arguments)
32
32
 
33
- super(inputs, outputs, @rule)
33
+ super(inputs, outputs)
34
34
  end
35
35
 
36
36
  attr :arguments
37
37
  attr :rule
38
38
  attr :callback
39
39
 
40
+ def == other
41
+ super and
42
+ @arguments == other.arguments and
43
+ @rule == other.rule and
44
+ @callback == other.callback
45
+ end
46
+
47
+ def hash
48
+ super ^ @arguments.hash ^ @rule.hash ^ @callback.hash
49
+ end
50
+
51
+ def task_class(parent_task)
52
+ parent_task.class
53
+ end
54
+
40
55
  def name
41
56
  @rule.name
42
57
  end
data/lib/build/task.rb CHANGED
@@ -26,28 +26,6 @@ require 'console/event/spawn'
26
26
  module Build
27
27
  # This task class serves as the base class for the environment specific task classes genearted when adding targets.
28
28
  class Task < Graph::Task
29
- class CommandFailure < Graph::TransientError
30
- def initialize(task, arguments, status)
31
- @task = task
32
- @arguments = arguments
33
- @status = status
34
-
35
- super "#{File.basename(executable_name).inspect} exited with status #{@status.to_i}"
36
- end
37
-
38
- def executable_name
39
- if @arguments[0].kind_of? Hash
40
- @arguments[1]
41
- else
42
- @arguments[0]
43
- end
44
- end
45
-
46
- attr :task
47
- attr :arguments
48
- attr :status
49
- end
50
-
51
29
  def initialize(walker, node, group, logger: nil)
52
30
  super(walker, node)
53
31
 
@@ -55,98 +33,23 @@ module Build
55
33
  @logger = logger
56
34
  end
57
35
 
58
- def to_s
59
- "\#<#{Task} #{node.name}>"
36
+ def task_class
37
+ self.class
60
38
  end
61
39
 
62
40
  attr :group
63
41
  attr :logger
64
42
 
65
- def wet?
66
- @node.dirty?
67
- end
68
-
69
- def spawn(*arguments)
70
- if wet?
71
- @logger&.info(self) {Console::Event::Spawn.for(*arguments)}
72
- status = @group.spawn(*arguments)
73
-
74
- if status != 0
75
- raise CommandFailure.new(self, arguments, status)
76
- end
77
- end
78
- end
79
-
80
- def shell_environment
81
- @shell_environment ||= environment.flatten.export
82
- end
83
-
84
- def run!(*arguments)
85
- self.spawn(shell_environment, *arguments)
86
- end
87
-
88
- def touch(path)
89
- return unless wet?
90
-
91
- @logger&.info(self) {Console::Shell.for('touch', path)}
92
- FileUtils.touch(path)
93
- end
94
-
95
- def cp(source_path, destination_path)
96
- return unless wet?
97
-
98
- @logger&.info(self) {Console::Shell.for('cp', source_path, destination_path)}
99
- FileUtils.copy(source_path, destination_path)
100
- end
101
-
102
- def rm(path)
103
- return unless wet?
104
-
105
- @logger&.info(self) {Console::Shell.for('rm -rf', path)}
106
- FileUtils.rm_rf(path)
107
- end
108
-
109
- def mkpath(path)
110
- return unless wet?
111
-
112
- unless File.exist?(path)
113
- @logger&.info(self) {Console::Shell.for('mkpath', path)}
114
- FileUtils.mkpath(path)
115
- end
116
- end
117
-
118
- def install(source_path, destination_path)
119
- return unless wet?
120
-
121
- @logger&.info(self) {Console::Shell.for('install', source_path, destination_path)}
122
- FileUtils.install(source_path, destination_path)
123
- end
124
-
125
- def write(path, data, mode = "w")
126
- return unless wet?
127
-
128
- @logger&.info(self) {Console::Shell.for("write", path, "#{data.size}bytes")}
129
- File.open(path, mode) do |file|
130
- file.write(data)
131
- end
132
- end
133
-
134
43
  def update
135
44
  @node.apply!(self)
136
45
  end
137
46
 
138
- def invoke_rule(rule, arguments, &block)
139
- arguments = rule.normalize(arguments, self)
140
-
141
- @logger&.debug(self) {"-> #{rule}(#{arguments.inspect})"}
142
-
143
- invoke(
144
- RuleNode.new(rule, arguments, &block)
145
- )
146
-
147
- @logger&.debug(self) {"<- #{rule}(...) -> #{rule.result(arguments)}"}
148
-
149
- return rule.result(arguments)
47
+ def name
48
+ self.to_s
49
+ end
50
+
51
+ def node_string
52
+ @node.name
150
53
  end
151
54
  end
152
55
  end
data/lib/build/version.rb CHANGED
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Build
22
- VERSION = "2.4.4"
22
+ VERSION = "2.6.0"
23
23
  end
@@ -46,7 +46,7 @@ RSpec.describe Build::Controller do
46
46
  let(:build_target) do
47
47
  Target.new("foo") do |target|
48
48
  target.depends "make"
49
-
49
+
50
50
  target.provides "foo" do
51
51
  foo_path = Build::Files::Path['foo']
52
52
 
@@ -32,4 +32,22 @@ RSpec.describe Build::Rule do
32
32
  expect(rule.applicable?(source: 'foo', destination: 'bar')).to be_truthy
33
33
  expect(rule.applicable?(source: 'foo')).to be_falsey
34
34
  end
35
+
36
+ it "respects false argument" do
37
+ rule = Build::Rule.new("compile", "cpp")
38
+
39
+ rule.parameter :install, default: true
40
+
41
+ expect(
42
+ rule.normalize({}, binding)
43
+ ).to be == {install: true}
44
+
45
+ expect(
46
+ rule.normalize({install: true}, binding)
47
+ ).to be == {install: true}
48
+
49
+ expect(
50
+ rule.normalize({install: false}, binding)
51
+ ).to be == {install: false}
52
+ end
35
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: build
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.4
4
+ version: 2.6.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-09-14 00:00:00.000000000 Z
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: build-graph
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '2.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: build-environment
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: '1.12'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: '1.12'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: build-dependency
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.4'
47
+ version: '1.5'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.4'
54
+ version: '1.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: build-makefile
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -166,10 +166,13 @@ files:
166
166
  - Rakefile
167
167
  - build.gemspec
168
168
  - lib/build.rb
169
+ - lib/build/build_node.rb
169
170
  - lib/build/chain_node.rb
170
171
  - lib/build/controller.rb
172
+ - lib/build/dependency_node.rb
171
173
  - lib/build/graphviz.rb
172
174
  - lib/build/name.rb
175
+ - lib/build/provision_node.rb
173
176
  - lib/build/rule.rb
174
177
  - lib/build/rule_node.rb
175
178
  - lib/build/rulebook.rb