rub 0.4.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.
@@ -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