rub 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,89 @@
1
+ # Copyright 2013 Kevin Cox
2
+
3
+ ################################################################################
4
+ # #
5
+ # This software is provided 'as-is', without any express or implied #
6
+ # warranty. In no event will the authors be held liable for any damages #
7
+ # arising from the use of this software. #
8
+ # #
9
+ # Permission is granted to anyone to use this software for any purpose, #
10
+ # including commercial applications, and to alter it and redistribute it #
11
+ # freely, subject to the following restrictions: #
12
+ # #
13
+ # 1. The origin of this software must not be misrepresented; you must not #
14
+ # claim that you wrote the original software. If you use this software in #
15
+ # a product, an acknowledgment in the product documentation would be #
16
+ # appreciated but is not required. #
17
+ # #
18
+ # 2. Altered source versions must be plainly marked as such, and must not be #
19
+ # misrepresented as being the original software. #
20
+ # #
21
+ # 3. This notice may not be removed or altered from any source distribution. #
22
+ # #
23
+ ################################################################################
24
+
25
+ module L::LD
26
+ LinkerGCC = Linker.clone
27
+ module LinkerGCC
28
+ def self.name
29
+ :gcc
30
+ end
31
+
32
+ def self.available?
33
+ !!find
34
+ end
35
+
36
+ # Find the linker executable.
37
+ # @return [Pathname,nil] The path of the executable.
38
+ def self.find
39
+ C.find_command 'gcc'
40
+ end
41
+
42
+ def self.link_command(opt, files, libs, out, format)
43
+ files = R::Tool.make_set_paths files
44
+ libs = R::Tool.make_set libs
45
+ out = C.path(out)
46
+
47
+ c = [find, "-o#{out}"]
48
+
49
+ c << opt.args
50
+
51
+ c << case format
52
+ when :exe
53
+ []
54
+ when :shared
55
+ ['-shared']
56
+ else
57
+ raise "Unknown/unsupported output #{format}."
58
+ end
59
+
60
+ c << case opt.optimize
61
+ when :none
62
+ D:debug ? '-Og' : '-O0'
63
+ when :some
64
+ '-O1'
65
+ when :full
66
+ '-O2'
67
+ when :max
68
+ '-O3'
69
+ else
70
+ raise "Invalid optimization level #{opt.optimize}."
71
+ end
72
+
73
+ c << if opt.static
74
+ '-static'
75
+ else
76
+ []
77
+ end
78
+
79
+ c << opt.library_dirs.map{|d| "-L#{d}"}
80
+
81
+ #c << libs.map{|l| "-l#{l}" }
82
+ c << libs.map{|l| "#{l}" }
83
+ c << files.to_a
84
+
85
+ c.flatten
86
+ end
87
+ end
88
+ L::LD.linkers[:gcc] = LinkerGCC
89
+ end
@@ -0,0 +1,91 @@
1
+ # Copyright 2013 Kevin Cox
2
+
3
+ ################################################################################
4
+ # #
5
+ # This software is provided 'as-is', without any express or implied #
6
+ # warranty. In no event will the authors be held liable for any damages #
7
+ # arising from the use of this software. #
8
+ # #
9
+ # Permission is granted to anyone to use this software for any purpose, #
10
+ # including commercial applications, and to alter it and redistribute it #
11
+ # freely, subject to the following restrictions: #
12
+ # #
13
+ # 1. The origin of this software must not be misrepresented; you must not #
14
+ # claim that you wrote the original software. If you use this software in #
15
+ # a product, an acknowledgment in the product documentation would be #
16
+ # appreciated but is not required. #
17
+ # #
18
+ # 2. Altered source versions must be plainly marked as such, and must not be #
19
+ # misrepresented as being the original software. #
20
+ # #
21
+ # 3. This notice may not be removed or altered from any source distribution. #
22
+ # #
23
+ ################################################################################
24
+
25
+ module L::LD
26
+ LinkerLD = Linker.clone
27
+ module LinkerLD
28
+ def self.name
29
+ :ld
30
+ end
31
+
32
+ def self.available?
33
+ !!find
34
+ end
35
+
36
+ # Find the linker command.
37
+ # @return [Pathname,nil] The command.
38
+ def self.find
39
+ C.find_command 'ld'
40
+ end
41
+
42
+ def self.link_command(opt, files, libs, out, format)
43
+ files = R::Tool.make_set_paths files
44
+ libs = R::Tool.make_set libs
45
+ out = C.path out
46
+
47
+ c = [find, "-o#{out}"]
48
+
49
+ c << opt.args
50
+
51
+ c << case format
52
+ when :exe
53
+ []
54
+ when :shared
55
+ ['-shared']
56
+ else
57
+ raise "Unknown/unsupported output #{format}."
58
+ end
59
+
60
+ c << case opt.optimize
61
+ when :none
62
+ '-O0'
63
+ when :some
64
+ '-O0'
65
+ when :full
66
+ '-O1'
67
+ when :max
68
+ '-O9'
69
+ else
70
+ raise "Invalid optimization level #{opt.optimize}."
71
+ end
72
+
73
+ c << if opt.static
74
+ '-static'
75
+ else
76
+ []
77
+ end
78
+
79
+ c << opt.library_dirs.map{|d| "-L#{d}"}
80
+
81
+ #c << libs.map{|l| "-l#{l}" }
82
+ c << libs.map{|l| "#{l}" }
83
+ c << files.to_a
84
+
85
+ c.flatten
86
+ end
87
+ end
88
+ L::LD.linkers[:ld] = LinkerLD
89
+
90
+ D.append(:l_ld_linker, :ld)
91
+ end
@@ -0,0 +1,92 @@
1
+ # Copyright 2013 Kevin Cox
2
+
3
+ ################################################################################
4
+ # #
5
+ # This software is provided 'as-is', without any express or implied #
6
+ # warranty. In no event will the authors be held liable for any damages #
7
+ # arising from the use of this software. #
8
+ # #
9
+ # Permission is granted to anyone to use this software for any purpose, #
10
+ # including commercial applications, and to alter it and redistribute it #
11
+ # freely, subject to the following restrictions: #
12
+ # #
13
+ # 1. The origin of this software must not be misrepresented; you must not #
14
+ # claim that you wrote the original software. If you use this software in #
15
+ # a product, an acknowledgment in the product documentation would be #
16
+ # appreciated but is not required. #
17
+ # #
18
+ # 2. Altered source versions must be plainly marked as such, and must not be #
19
+ # misrepresented as being the original software. #
20
+ # #
21
+ # 3. This notice may not be removed or altered from any source distribution. #
22
+ # #
23
+ ################################################################################
24
+
25
+ require 'erb'
26
+ require 'ostruct'
27
+
28
+ # Templates for generating files.
29
+ module L::Template
30
+ class Renderer < OpenStruct
31
+ def render(template, filename: 'ERB String')
32
+ t = ERB.new(template, nil, '-')
33
+ t.filename = filename.to_s
34
+ t.result(binding)
35
+ end
36
+ def render_file(f)
37
+ f = C.path f
38
+
39
+ render f.read, filename: f
40
+ end
41
+ end
42
+
43
+ class TargetRenderer < R::TargetSmart
44
+ def initialize(inp, out, values)
45
+ super()
46
+
47
+ @template = inp
48
+ @resultf = out
49
+
50
+ if inp.is_a? Pathname
51
+ input << inp
52
+ end
53
+ output << out
54
+
55
+ @renderer = Renderer.new values
56
+ end
57
+
58
+ def build_self
59
+ r = if @template.is_a? String
60
+ @renderer.render @template
61
+ else
62
+ @renderer.render_file @template
63
+ end
64
+
65
+ @resultf.dirname.mkpath
66
+ @resultf.open('w') do |f|
67
+ f.write r
68
+ end
69
+
70
+ bs = R::BuildStep.new
71
+ bs.desc = "Rendering #{@resultf}"
72
+ bs.print
73
+ end
74
+ end
75
+
76
+ #def render(template, values)
77
+ # Renderer.new(values).render(template)
78
+ #end
79
+ #def render_file(f, values)
80
+ # Renderer.new(values).render_file(f)
81
+ #end
82
+
83
+ def self.generate_file(inp, out, values={})
84
+ inp = C.path inp
85
+ out = R::Env.out_dir + 'l/template/' + C.unique_segment([inp, values]) + out
86
+
87
+ t = TargetRenderer.new(inp, out, values)
88
+ t.register
89
+
90
+ return out
91
+ end
92
+ end
@@ -0,0 +1,256 @@
1
+ # Copyright 2013 Kevin Cox
2
+
3
+ ################################################################################
4
+ # #
5
+ # This software is provided 'as-is', without any express or implied #
6
+ # warranty. In no event will the authors be held liable for any damages #
7
+ # arising from the use of this software. #
8
+ # #
9
+ # Permission is granted to anyone to use this software for any purpose, #
10
+ # including commercial applications, and to alter it and redistribute it #
11
+ # freely, subject to the following restrictions: #
12
+ # #
13
+ # 1. The origin of this software must not be misrepresented; you must not #
14
+ # claim that you wrote the original software. If you use this software in #
15
+ # a product, an acknowledgment in the product documentation would be #
16
+ # appreciated but is not required. #
17
+ # #
18
+ # 2. Altered source versions must be plainly marked as such, and must not be #
19
+ # misrepresented as being the original software. #
20
+ # #
21
+ # 3. This notice may not be removed or altered from any source distribution. #
22
+ # #
23
+ ################################################################################
24
+
25
+ require 'singleton'
26
+ require 'stringio'
27
+
28
+ require 'minitest'
29
+ require 'minitest/spec'
30
+ require 'minitest/mock'
31
+
32
+ class Minitest::Runnable
33
+ @@rub_oldinherited = method :inherited
34
+ def self.inherited klass
35
+ ::L::Test.make_test klass
36
+
37
+ @@rub_oldinherited.call klass
38
+ end
39
+
40
+ # The Rub target, this is set automatically.
41
+ #
42
+ # @return [R::Target]
43
+ cattr_accessor :rub_target
44
+
45
+ # Add a dependency
46
+ #
47
+ # Add a dependency to the test. It will be available before the test is
48
+ # run.
49
+ #
50
+ # @param d [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
51
+ # The dependencies.
52
+ def self.rub_require(d)
53
+ d = R::Tool.make_set_paths d
54
+
55
+ @rub_deps ||= Set.new
56
+
57
+ @rub_deps.merge d
58
+ end
59
+
60
+ # Get tests dependencies.
61
+ #
62
+ # @private
63
+ def self.rub_get_dependancies
64
+ @rub_deps || Set.new
65
+ end
66
+ end
67
+
68
+ # Testing.
69
+ #
70
+ # This testing is powered by Minitest. Look up the docs for that.
71
+ #
72
+ # All test are defined as regular Minitest tests and they will be automatically
73
+ # picked up and have tags created for them.
74
+ #
75
+ # When defining the test class there will be an additional method
76
+ # {Minitest::Runnable#rub_add_dependency} that will allow the test to depend
77
+ # on any target. Therefore you can ensure that what you are testing has been
78
+ # built.
79
+ #
80
+ # @example Defining dependencies.
81
+ #
82
+ # Minitest::Test
83
+ # rub_add_dependancy $myexe # Ensure $myexe will be available when test are run.
84
+ #
85
+ # def test_help
86
+ # c = R::Command.new [$myexe, '--help']
87
+ # c.run
88
+ #
89
+ # assert c.success?, 'Help exited with a good status code'
90
+ # end
91
+ # end
92
+ #
93
+ module L::Test
94
+ def self.make_test(klass)
95
+ @tests ||= {}
96
+
97
+ sklass = klass.to_s
98
+ if sklass =~ /^Test/
99
+ name = sklass
100
+ .gsub(/(?<=[a-z0-9])([A-Z])/, '-\1')
101
+ .gsub(/(?<=[^0-9])([0-9])/, '-\1')
102
+ .gsub('_', '-')
103
+ .downcase.to_sym
104
+ #pp name
105
+
106
+ @tests[name] ||= TargetTestCase.new(klass, name)
107
+ end
108
+ end
109
+
110
+ class Reporter < Minitest::AbstractReporter
111
+ def initialize(opt = {})
112
+ @passed = true
113
+
114
+ @io = opt[:io] || $stdout
115
+ end
116
+
117
+ ##
118
+ # Starts reporting on the run.
119
+ def start
120
+ end
121
+
122
+ ##
123
+ # Record a result and output the Runnable#result_code. Stores the
124
+ # result of the run if the run did not pass.
125
+ def record(r)
126
+ pres = if r.skipped?
127
+ "\e[34;1mSKIP\e[0m"
128
+ elsif r.passed?
129
+ "\e[32;1mPASS\e[0m"
130
+ else
131
+ "\e[31;1mFAIL\e[0m"
132
+ end
133
+
134
+ @io.puts "[#{pres}] #{r.class}##{r.name}"
135
+ end
136
+
137
+ ##
138
+ # Outputs the summary of the run.
139
+ def report
140
+ end
141
+
142
+ ##
143
+ # Did this run pass?
144
+ def passed?
145
+ @passed
146
+ end
147
+ end
148
+
149
+ class TargetTest < R::Target
150
+ def input
151
+ Minitest::Runnable.runnables.map do |r|
152
+ r.rub_target
153
+ end.compact.map do |t|
154
+ t.input.to_a
155
+ end.flatten.to_set
156
+ end
157
+
158
+ def output
159
+ Set[:test]
160
+ end
161
+
162
+ def initialize
163
+ super()
164
+
165
+ register
166
+ end
167
+
168
+ def run_tests(reporter, options)
169
+ Minitest::Runnable.runnables.each do |r|
170
+ r.rub_target or next
171
+
172
+ r.rub_target.run_tests reporter, options
173
+ end
174
+ end
175
+
176
+ def build_self
177
+ out = StringIO.new("", "w")
178
+
179
+ options = {
180
+ io: out,
181
+ verbose: true
182
+ }
183
+
184
+ reporter = Minitest::CompositeReporter.new
185
+ reporter << Minitest::SummaryReporter.new(options[:io], options)
186
+
187
+ reporter.start
188
+ out.string = '' # We don't want the start text.
189
+
190
+ run_tests reporter, options
191
+ reporter.report
192
+
193
+ bs = R::BuildStep.new
194
+ bs.desc = "Test Results"
195
+ bs.status = reporter.passed? ? 0 : 1
196
+ bs.out = out.string
197
+ bs.print
198
+ end
199
+ end
200
+ TargetTest.new # Create :test
201
+
202
+ class TargetTestCase < TargetTest
203
+ def input
204
+ @klass.rub_get_dependancies
205
+ end
206
+
207
+ def output
208
+ Set[@tag]
209
+ end
210
+
211
+ def initialize(klass, t)
212
+ @tag = t.to_sym
213
+ @klass = klass
214
+
215
+ klass.rub_target = self
216
+
217
+ super()
218
+ end
219
+
220
+ def run_tests(reporter, options)
221
+ out = StringIO.new("", "w")
222
+ options = {
223
+ io: out,
224
+ verbose: true
225
+ }
226
+ pr = Reporter.new(options)
227
+ reporter << pr
228
+
229
+ @klass.run reporter, options
230
+
231
+ reporter.reporters.delete pr
232
+
233
+ bs = R::BuildStep.new
234
+ bs.desc = "Running test case :#{@tag}"
235
+ bs.out = out.string
236
+ bs.status = pr.passed? ? 0 : 1
237
+ bs.print
238
+ end
239
+ end
240
+
241
+ class TargetTestExecutable < R::TargetGenerator
242
+ def build
243
+ build_dependancies
244
+
245
+ R::run(@cmd[0], "#@action #{@output.to_a.join", "}") or exit 1
246
+ end
247
+ end
248
+
249
+ def self.external(cmd, name)
250
+ t = TargetTestExecutable.new
251
+ t.add_cmd cmd
252
+ t.output << name
253
+
254
+ t.register
255
+ end
256
+ end