build 2.4.2 → 2.5.1

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: 94281feda7cae3256e0e31ddc228b8d721e9ec666e166e8a5624774062e19a04
4
- data.tar.gz: f8e4db89acdc0a5da9330fc31b4fc174dcf481dab143819e9aed7a8b93b54b8e
3
+ metadata.gz: 1a584085143f5ed2e6ea2bc4dd34688402a07e09b86174342d40ecbbf4c3ca75
4
+ data.tar.gz: f830204ab793ae014d4c78e28b50a9f0a7d9c890bf61f978e94e33a76ba8362f
5
5
  SHA512:
6
- metadata.gz: d8d1c9a6836cd95b2cf26f05fbcd7eff1f00de6f51fe6f4ab422cd527ea4462b7083192b9ebd66d756846f143f5c6b6ce518d0194488ed5ff38d4df50a4c2048
7
- data.tar.gz: 4aa70fbc51b87ab726406d25b6e7d8558632d7859c5f4f1bc1408463babaa12dac18b43802b18eb019f5a9c1286f660a9f14dd164a09c28ff8846deb71089b10
6
+ metadata.gz: 1ede532310d8e76e5565c35893e68924f3eb30b034d4dda3aececee3848920576f78c7ccaa50aab484e9c4d71fd953680c30ccf3cf88105797f8afc55b7c4e3f
7
+ data.tar.gz: c60e8d539f50fdfcaeea102d325e61f0580f57f595d3edc4c0fa243aa591152f2502a4642750ceda2e8daa24f42b4587a6cc8153fb7cdbad0be4182871c29f04
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,7 +17,7 @@ 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"
20
+ spec.add_dependency "build-graph", "~> 2.0"
21
21
  spec.add_dependency "build-environment", "~> 1.3"
22
22
  spec.add_dependency "build-dependency", "~> 1.4"
23
23
  spec.add_dependency "build-makefile", "~> 1.0"
@@ -0,0 +1,186 @@
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, dependency, provisions, arguments)
29
+ @environment = environment
30
+ @dependency = dependency
31
+ @provisions = provisions
32
+ @arguments = arguments
33
+
34
+ super(Files::List::NONE, :inherit)
35
+ end
36
+
37
+ attr :environment
38
+ attr :dependency
39
+ attr :provisions
40
+ attr :arguments
41
+
42
+ def == other
43
+ super and
44
+ @environment == other.environment and
45
+ @dependency == other.dependency and
46
+ @provisions == other.provisions and
47
+ @arguments == other.arguments
48
+ end
49
+
50
+ def hash
51
+ super ^ @environment.hash ^ @dependency.hash ^ @provisions.hash ^ @arguments.hash
52
+ end
53
+
54
+ def task_class(parent_task)
55
+ task_class = Rulebook.for(@environment).with(BuildTask, environment: @environment)
56
+ end
57
+
58
+ def initial_environment
59
+ Build::Environment.new(@environment, name: @dependency.name)
60
+ end
61
+
62
+ def name
63
+ @dependency.name
64
+ end
65
+
66
+ def apply!(task)
67
+ output_environment = self.initial_environment
68
+
69
+ @provisions.each do |provision|
70
+ output_environment.construct!(task, *@arguments, &provision.value)
71
+ end
72
+
73
+ task.output_environment = output_environment
74
+ end
75
+ end
76
+
77
+ # This task class serves as the base class for the environment specific task classes genearted when adding targets.
78
+ class BuildTask < Task
79
+ class CommandFailure < Graph::TransientError
80
+ def initialize(task, arguments, status)
81
+ @task = task
82
+ @arguments = arguments
83
+ @status = status
84
+
85
+ super "#{File.basename(executable_name).inspect} exited with status #{@status.to_i}"
86
+ end
87
+
88
+ def executable_name
89
+ if @arguments[0].kind_of? Hash
90
+ @arguments[1]
91
+ else
92
+ @arguments[0]
93
+ end
94
+ end
95
+
96
+ attr :task
97
+ attr :arguments
98
+ attr :status
99
+ end
100
+
101
+ attr_accessor :output_environment
102
+
103
+ def wet?
104
+ @node.dirty?
105
+ end
106
+
107
+ def spawn(*arguments)
108
+ if wet?
109
+ @logger&.info(self) {Console::Event::Spawn.for(*arguments)}
110
+ status = @group.spawn(*arguments)
111
+
112
+ if status != 0
113
+ raise CommandFailure.new(self, arguments, status)
114
+ end
115
+ end
116
+ end
117
+
118
+ def shell_environment
119
+ @shell_environment ||= environment.flatten.export
120
+ end
121
+
122
+ def run!(*arguments)
123
+ self.spawn(shell_environment, *arguments)
124
+ end
125
+
126
+ def touch(path)
127
+ return unless wet?
128
+
129
+ @logger&.info(self) {Console::Shell.for('touch', path)}
130
+ FileUtils.touch(path)
131
+ end
132
+
133
+ def cp(source_path, destination_path)
134
+ return unless wet?
135
+
136
+ @logger&.info(self) {Console::Shell.for('cp', source_path, destination_path)}
137
+ FileUtils.copy(source_path, destination_path)
138
+ end
139
+
140
+ def rm(path)
141
+ return unless wet?
142
+
143
+ @logger&.info(self) {Console::Shell.for('rm -rf', path)}
144
+ FileUtils.rm_rf(path)
145
+ end
146
+
147
+ def mkpath(path)
148
+ return unless wet?
149
+
150
+ unless File.exist?(path)
151
+ @logger&.info(self) {Console::Shell.for('mkpath', path)}
152
+ FileUtils.mkpath(path)
153
+ end
154
+ end
155
+
156
+ def install(source_path, destination_path)
157
+ return unless wet?
158
+
159
+ @logger&.info(self) {Console::Shell.for('install', source_path, destination_path)}
160
+ FileUtils.install(source_path, destination_path)
161
+ end
162
+
163
+ def write(path, data, mode = "w")
164
+ return unless wet?
165
+
166
+ @logger&.info(self) {Console::Shell.for("write", path, "#{data.size}bytes")}
167
+ File.open(path, mode) do |file|
168
+ file.write(data)
169
+ end
170
+ end
171
+
172
+ def invoke_rule(rule, arguments, &block)
173
+ arguments = rule.normalize(arguments, self)
174
+
175
+ @logger&.debug(self) {"-> #{rule}(#{arguments.inspect})"}
176
+
177
+ invoke(
178
+ RuleNode.new(rule, arguments, &block)
179
+ )
180
+
181
+ @logger&.debug(self) {"<- #{rule}(...) -> #{rule.result(arguments)}"}
182
+
183
+ return rule.result(arguments)
184
+ end
185
+ end
186
+ end
@@ -22,87 +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 task_class
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
51
+ end
52
+
53
+ def hash
54
+ super ^ @chain.hash ^ @arguments.hash ^ @environment.hash
55
+ end
56
+
57
+ def task_class(parent_task)
38
58
  Task
39
59
  end
40
60
 
41
- def apply_dependency(scope, dependency)
42
- logger = scope.logger
43
-
44
- # logger.debug {"Traversing: #{dependency}..."}
45
-
46
- environments = [@environment]
47
- public_environments = []
48
- provisions = @chain.resolved[dependency]
49
- public_alias = dependency.alias?
50
-
51
- provisions.each do |provision|
52
- provision.each_dependency do |nested_dependency|
53
- if environment = apply_dependency(scope, nested_dependency)
54
- # logger.debug("Evaluating #{nested_dependency} -> #{provision} generated: #{environment}")
55
-
56
- environments << environment
57
-
58
- if public_alias || nested_dependency.public?
59
- public_environments << environment
60
- # else
61
- # logger.debug("Skipping #{nested_dependency} in public environment.")
62
- end
63
- end
64
- end
65
- end
66
-
67
- unless dependency.alias?
68
- logger.debug {"Building: #{dependency}"}
69
-
70
- # environments.each do |environment|
71
- # logger.debug {"Using #{environment}"}
72
- # end
73
-
74
- local_environment = Build::Environment.combine(*environments)&.evaluate || Build::Environment.new
75
-
76
- # logger.debug("Local Environment: #{local_environment}")
77
-
78
- task_class = Rulebook.for(local_environment).with(Task, environment: local_environment)
79
- task = task_class.new(scope.walker, self, scope.group, logger: scope.logger)
80
-
81
- output_environment = nil
82
-
83
- task.visit do
84
- output_environment = Build::Environment.new(local_environment, name: dependency.name)
85
-
86
- provisions.each do |provision|
87
- # When executing the environment build steps, we create new build nodes. But those build nodes are not capturing the right task class.
88
- output_environment.construct!(task, *@arguments, &provision.value)
89
- end
90
-
91
- public_environments << output_environment.dup(parent: nil, name: dependency.name)
92
- end
93
- end
94
-
95
- return Build::Environment.combine(*public_environments)
61
+ def name
62
+ @environment.name
96
63
  end
97
64
 
98
- 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:
99
68
  @chain.dependencies.each do |dependency|
100
- apply_dependency(scope, dependency)
69
+ node = DependencyNode.new(@chain, dependency, @environment, @arguments)
70
+
71
+ task.invoke(node)
101
72
  end
102
73
  end
103
74
 
104
- def to_s
105
- "#<#{self.class}>"
75
+ def inspect
76
+ "#<#{self.class} #{@environment.inspect}>"
106
77
  end
107
78
  end
108
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,163 @@
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 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 ^ @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 alias?
67
+ @dependency.alias?
68
+ end
69
+
70
+ def public?
71
+ @dependency.public?
72
+ end
73
+
74
+ # This is the main entry point when invoking the node from `Build::Task`.
75
+ def apply!(task)
76
+ # Go through all the dependencies in order and apply them to the build graph:
77
+ @chain.dependencies.each do |dependency|
78
+ node = DependencyNode.new(@chain, dependency, @environment, @arguments)
79
+
80
+ task.invoke(node)
81
+ end
82
+ end
83
+
84
+ def dependency_node_for(dependency)
85
+ DependencyNode.new(@chain, dependency, @environment, @arguments)
86
+ end
87
+ end
88
+
89
+ class DependencyTask < Task
90
+ def initialize(*arguments, **options)
91
+ super
92
+
93
+ @environment = nil
94
+ @tasks = []
95
+ end
96
+
97
+ attr :group
98
+ attr :logger
99
+
100
+ attr :environment
101
+
102
+ def update
103
+ logger.debug(self) do |buffer|
104
+ buffer.puts "building #{@node} which #{@node.dependency}"
105
+ @node.provisions.each do |provision|
106
+ buffer.puts "\tbuilding #{provision.provider.name} which #{provision}"
107
+ end
108
+ end
109
+
110
+ # Lookup what things this dependency provides:
111
+ @node.provisions.each do |provision|
112
+ provision.each_dependency do |nested_dependency|
113
+ @tasks << invoke(@node.dependency_node_for(nested_dependency))
114
+ end
115
+ end
116
+ end
117
+
118
+ def update_outputs
119
+ dependency = @node.dependency
120
+ environments = [@node.environment]
121
+
122
+ public_environments = []
123
+ public_alias = @node.alias?
124
+
125
+ @tasks.each do |task|
126
+ if environment = task.environment
127
+ environments << environment
128
+
129
+ if public_alias || task.node.public?
130
+ public_environments << environment
131
+ # else
132
+ # logger.debug("Skipping #{nested_dependency} in public environment.")
133
+ end
134
+ end
135
+ end
136
+
137
+ unless public_alias
138
+ logger.debug(self) {"Building: #{dependency} <- #{@tasks.join}"}
139
+
140
+ # environments.each do |environment|
141
+ # logger.debug {"Using #{environment}"}
142
+ # end
143
+
144
+ local_environment = Build::Environment.combine(*environments)&.evaluate || Build::Environment.new
145
+
146
+ # logger.debug("Local Environment: #{local_environment}")
147
+
148
+ build_task = invoke(
149
+ BuildNode.new(local_environment, dependency, @node.provisions, @node.arguments)
150
+ )
151
+
152
+ if wait_for_children?
153
+ output_environment = build_task.output_environment
154
+ public_environments << output_environment.dup(parent: nil, name: dependency.name)
155
+ end
156
+ end
157
+
158
+ @environment = Build::Environment.combine(*public_environments)
159
+
160
+ super
161
+ end
162
+ end
163
+ end
data/lib/build/rule.rb CHANGED
@@ -43,6 +43,7 @@ module Build
43
43
  attr :name
44
44
 
45
45
  attr :options
46
+ attr :dynamic
46
47
 
47
48
  def input?
48
49
  @direction == :input
@@ -87,13 +88,24 @@ module Build
87
88
  def compute(arguments, scope)
88
89
  if implicit?
89
90
  # Can be replaced if supplied:
90
- arguments[@name] || scope.instance_exec(arguments, &@dynamic)
91
+ arguments[@name] || scope.instance_exec(arguments, &@dynamic) || @options[:default]
91
92
  elsif dynamic?
92
93
  # Argument is optional:
93
- scope.instance_exec(arguments[@name], arguments, &@dynamic)
94
- else
94
+ scope.instance_exec(arguments[@name], arguments, &@dynamic) || @options[:default]
95
+ elsif arguments.key?(@name)
95
96
  arguments[@name]
96
- end || @options[:default]
97
+ else
98
+ @options[:default]
99
+ end
100
+ end
101
+
102
+ def hash
103
+ [self.class, @direction, @name, @options].hash
104
+ end
105
+
106
+ # TODO fix implementation
107
+ def eql? other
108
+ other.kind_of?(self.class) and @direction.eql?(other.direction) and @name.eql?(other.name) and @options.eql?(other.options) # and @dynamic == other.dynamic
97
109
  end
98
110
 
99
111
  def inspect
@@ -217,8 +229,12 @@ module Build
217
229
  end
218
230
  end
219
231
 
220
- def ==(other)
221
- other.kind_of?(self.class) and @name == other.name and @parameters == other.parameters
232
+ def hash
233
+ [self.class, @name, @parameters].hash
234
+ end
235
+
236
+ def eql?(other)
237
+ other.kind_of?(self.class) and @name.eql?(other.name) and @parameters.eql?(other.parameters)
222
238
  end
223
239
 
224
240
  def to_s
@@ -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
@@ -21,33 +21,11 @@
21
21
  require 'fileutils'
22
22
  require 'build/graph'
23
23
 
24
- require 'console/shell'
24
+ require 'console/event/spawn'
25
25
 
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,94 +33,23 @@ module Build
55
33
  @logger = logger
56
34
  end
57
35
 
58
- attr :group
59
- attr :logger
60
-
61
- def wet?
62
- @node.dirty?
63
- end
64
-
65
- def spawn(*arguments)
66
- if wet?
67
- @logger&.info(self) {Console::Shell.for(*arguments)}
68
- status = @group.spawn(*arguments)
69
-
70
- if status != 0
71
- raise CommandFailure.new(self, arguments, status)
72
- end
73
- end
74
- end
75
-
76
- def shell_environment
77
- @shell_environment ||= environment.flatten.export
78
- end
79
-
80
- def run!(*arguments)
81
- self.spawn(shell_environment, *arguments)
82
- end
83
-
84
- def touch(path)
85
- return unless wet?
86
-
87
- @logger&.info(self) {Console::Shell.for('touch', path)}
88
- FileUtils.touch(path)
89
- end
90
-
91
- def cp(source_path, destination_path)
92
- return unless wet?
93
-
94
- @logger&.info(self) {Console::Shell.for('cp', source_path, destination_path)}
95
- FileUtils.copy(source_path, destination_path)
96
- end
97
-
98
- def rm(path)
99
- return unless wet?
100
-
101
- @logger&.info(self) {Console::Shell.for('rm -rf', path)}
102
- FileUtils.rm_rf(path)
103
- end
104
-
105
- def mkpath(path)
106
- return unless wet?
107
-
108
- unless File.exist?(path)
109
- @logger&.info(self) {Console::Shell.for('mkpath', path)}
110
- FileUtils.mkpath(path)
111
- end
36
+ def task_class
37
+ self.class
112
38
  end
113
39
 
114
- def install(source_path, destination_path)
115
- return unless wet?
116
-
117
- @logger&.info(self) {Console::Shell.for('install', source_path, destination_path)}
118
- FileUtils.install(source_path, destination_path)
119
- end
120
-
121
- def write(path, data, mode = "w")
122
- return unless wet?
123
-
124
- @logger&.info(self) {Console::Shell.for("write", path, "#{data.size}bytes")}
125
- File.open(path, mode) do |file|
126
- file.write(data)
127
- end
128
- end
40
+ attr :group
41
+ attr :logger
129
42
 
130
43
  def update
131
44
  @node.apply!(self)
132
45
  end
133
46
 
134
- def invoke_rule(rule, arguments, &block)
135
- arguments = rule.normalize(arguments, self)
136
-
137
- @logger&.debug(self) {"-> #{rule}(#{arguments.inspect})"}
138
-
139
- invoke(
140
- RuleNode.new(rule, arguments, &block)
141
- )
142
-
143
- @logger&.debug(self) {"<- #{rule}(...) -> #{rule.result(arguments)}"}
144
-
145
- return rule.result(arguments)
47
+ def name
48
+ self.to_s
49
+ end
50
+
51
+ def node_string
52
+ @node.name
146
53
  end
147
54
  end
148
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.2"
22
+ VERSION = "2.5.1"
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.2
4
+ version: 2.5.1
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-03-29 00:00:00.000000000 Z
11
+ date: 2019-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: build-graph
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '2.0'
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.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: build-environment
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -166,8 +166,10 @@ 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
173
175
  - lib/build/rule.rb
@@ -200,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
202
  - !ruby/object:Gem::Version
201
203
  version: '0'
202
204
  requirements: []
203
- rubygems_version: 3.0.2
205
+ rubygems_version: 3.0.4
204
206
  signing_key:
205
207
  specification_version: 4
206
208
  summary: Build is a framework for working with task based build systems.