mswin-build 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cfe42674ee22526c93c3fd0347034be4f0af2f48
4
+ data.tar.gz: 599a68351770263a39ab8b8accf35d9eaa9a9915
5
+ SHA512:
6
+ metadata.gz: e90cc66dfc5614f26af3d2ecd259a78b4aeb7bd423ce4b50789d205e82dc72b2fb23d8a712344b6288ddec03451fee7d517363dba3e4a797b1c4ebad80178fff
7
+ data.tar.gz: b76b8068667a7c70447810af98fe555bd5fc8ad305694b86f7cf69f8bf234ba85d1a04b47d9b4b9edc79a018c6d041b415179dbe836ffca4e3c27c428241a4ee
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ logs
2
+ pkg
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.0.0
5
+ - 1.9.3
6
+ script:
7
+ - bundle exec rake build
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mswin-build.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ mswin-build
2
+ ===========
3
+
4
+ This software is originally published at https://github.com/unak/mswin-build .
5
+
6
+
7
+ What's This?
8
+ ------------
9
+
10
+ A low quality clone of https://github.com/akr/chkbuild for mswin.
11
+
12
+
13
+ Requirements
14
+ ------------
15
+
16
+ * ruby 1.9.3 or 2.0.0 or newer, with fiddle
17
+ * sed
18
+ * bison
19
+ * svn
20
+ * gzip
21
+ * and of cource, Visual C++ 6 or newer
22
+
23
+
24
+ How to Use
25
+ ----------
26
+
27
+ Write a config file in config directory, and run `bin/build.rb`.
28
+
29
+
30
+ License
31
+ -------
32
+
33
+ Copyright (c) 2013 NAKAMURA Usaku usa@garbagecollect.jp
34
+
35
+ Redistribution and use in source and binary forms, with or without
36
+ modification, are permitted provided that the following conditions are met:
37
+
38
+ 1. Redistributions of source code must retain the above copyright notice,
39
+ this list of conditions and the following disclaimer.
40
+ 2. Redistributions in binary form must reproduce the above copyright notice,
41
+ this list of conditions and the following disclaimer in the documentation
42
+ and/or other materials provided with the distribution.
43
+
44
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
45
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
48
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # -*- Ruby -*-
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask.rb"
4
+
5
+ namespace "test" do
6
+ Rake::TestTask.new do |t|
7
+ t.name = "units"
8
+ t.pattern = "test/unit/test_*.rb"
9
+ end
10
+ end
11
+
12
+ desc "Run all tests"
13
+ task test: ["test:units"]
data/bin/build.rb ADDED
@@ -0,0 +1,33 @@
1
+ #! ruby
2
+ # expected ruby 1.9.x or later.
3
+ libdir = File.expand_path("../lib", File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(libdir) if File.directory?(libdir)
5
+ require "optparse"
6
+ require "rbconfig"
7
+ require "mswin-build/builder"
8
+
9
+ $debug = $DEBUG
10
+ opt = OptionParser.new
11
+ opt.banner = "Usage: ruby #$0 [options] <target name>"
12
+ opt.separator ""
13
+ opt.separator " This script automatically loads config/<target name>.yaml."
14
+ opt.separator ""
15
+ opt.separator "Options:"
16
+ opt.on('-v', '--verbose', 'Be verbose.') { $debug = true }
17
+
18
+ begin
19
+ opt.parse!(ARGV)
20
+ target = ARGV.shift
21
+ raise "target name is not specified." unless target
22
+ rescue RuntimeError => ex
23
+ puts ex.message
24
+ puts
25
+ puts opt.help
26
+ exit 1
27
+ end
28
+
29
+ # use this running ruby as BASERUBY
30
+ baseruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
31
+
32
+ builder = MswinBuild::Builder.new(target: target, baseruby: baseruby, settings: File.expand_path("../config/#{target}.yaml", File.dirname(__FILE__)))
33
+ exit builder.run
data/bin/kicker.rb ADDED
@@ -0,0 +1,49 @@
1
+ #!ruby
2
+ $LOAD_PATH.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
3
+ require "tmpdir"
4
+ require "optparse"
5
+ require "rbconfig"
6
+ require "mswin-build/builder"
7
+
8
+ # use this running ruby as BASERUBY by default
9
+ baseruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
10
+ interval = 60
11
+ force_build = 24 * 60 * 60 # force build at least once in every day
12
+
13
+ opt = OptionParser.new
14
+ opt.banner = "Usage: ruby #$0 [options] <target name>"
15
+ opt.separator ""
16
+ opt.separator " This script automatically loads config/<target name>.yaml."
17
+ opt.separator ""
18
+ opt.separator "Options:"
19
+ opt.on('-v', '--verbose', "Be verbose. default = #{!$debug.nil? && $debug}") { $debug = true }
20
+ opt.on('-b <baseruby>', '--baseruby=<baserbuby>', "specify baseruby. default: #{baseruby}") { |v| baseruby = v }
21
+ opt.on('-i <seconds>', '--interval=<seconds>', "interval between each build. default: #{interval}") { |v| interval = Integer(v) }
22
+ opt.on('-f <seconds>', '--force-build=<seconds>', "force build after specified seconds from last bulid. default: #{force_build}") { |v| fource_build = Integer(v) }
23
+
24
+ begin
25
+ opt.parse!(ARGV)
26
+ raise "target name is not specified." if ARGV.empty?
27
+ rescue RuntimeError => ex
28
+ puts ex.message
29
+ puts
30
+ puts opt.help
31
+ exit 1
32
+ end
33
+
34
+ loop do
35
+ ARGV.each do |target|
36
+ builder = MswinBuild::Builder.new(target: target, baseruby: baseruby, settings: File.expand_path("../config/#{target}.yaml", File.dirname(__FILE__)))
37
+ if !builder.get_last_build_time || builder.get_last_build_time + force_build < Time.now || builder.get_last_revision != builder.get_current_revision
38
+ cmd = [baseruby, File.expand_path("build.rb", File.dirname(__FILE__)), target]
39
+ cmd << "-v" if $debug
40
+ puts "+++ #{Time.now} Start #{target} +++" if $debug
41
+ system(*cmd)
42
+ puts "--- #{Time.now} Finish #{target} ---" if $debug
43
+ else
44
+ puts "=== #{Time.now} Skipped #{target} ===" if $debug
45
+ end
46
+ end
47
+ puts "=== #{Time.now} Pausing #{interval} seconds ===" if $debug
48
+ sleep interval
49
+ end
data/bin/tinyhttpd.rb ADDED
@@ -0,0 +1,32 @@
1
+ #! ruby
2
+ # expected ruby 1.9.x or later.
3
+
4
+ require "webrick"
5
+
6
+ class WEBrick::HTTPServer
7
+ alias :__rewrite_old_service :service
8
+ def service(req, res)
9
+ ret = __rewrite_old_service(req, res)
10
+ if /\.html\.gz\z/ =~ req.path
11
+ res.header["content-encoding"] = "gzip"
12
+ res.header["content-type"] = "text/html"
13
+ end
14
+ end
15
+ end
16
+
17
+ root = ARGV.shift
18
+ unless root
19
+ puts "Usage: ruby #$0 <document root>"
20
+ exit 1
21
+ end
22
+
23
+ options = {
24
+ DocumentRoot: root,
25
+ }
26
+
27
+ server = WEBrick::HTTPServer.new(options)
28
+ shutdown = proc { server.shutdown }
29
+ (%w"TERM QUIT HUP INT" & Signal.list.keys).each do |sig|
30
+ Signal.trap(sig, shutdown)
31
+ end
32
+ server.start
@@ -0,0 +1,3 @@
1
+ baseruby:
2
+ repository: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_9_3
3
+ logdir: logs/vc10-x86/ruby-1.9.3
@@ -0,0 +1,3 @@
1
+ baseruby:
2
+ repository: http://svn.ruby-lang.org/repos/ruby/branches/ruby_2_0_0
3
+ logdir: logs/vc10-x86/ruby-2.0.0
@@ -0,0 +1,3 @@
1
+ baseruby:
2
+ repository: http://svn.ruby-lang.org/repos/ruby/trunk
3
+ logdir: logs/vc10-x86/ruby-trunk
@@ -0,0 +1,589 @@
1
+ require "cgi"
2
+ require "fileutils"
3
+ require "socket"
4
+ require "time"
5
+ require "timeout"
6
+ require "tmpdir"
7
+ require "yaml"
8
+ require "mswin-build/process_tree"
9
+
10
+ module MswinBuild
11
+ class Builder
12
+ def initialize(h)
13
+ @target = h.delete(:target) || raise("target not specified")
14
+ baseruby = h.delete(:baseruby)
15
+ yaml = h.delete(:settings) || raise("settings not specified")
16
+ unless h.empty?
17
+ raise "unknown option(s): #{h}"
18
+ end
19
+ @config = YAML.load(IO.read(yaml, encoding: "utf-8"))
20
+ @config["baseruby"] = baseruby if baseruby
21
+ @config["bison"] ||= "bison"
22
+ @config["svn"] ||= "svn"
23
+ @config["gzip"] ||= "gzip"
24
+
25
+ raise "baseruby not specified" unless @config["baseruby"]
26
+ raise "repository not specified" unless @config["repository"]
27
+ raise "logdir not specfied" unless @config["logdir"]
28
+
29
+ @title = []
30
+ @links = {}
31
+
32
+ @config["timeout"] ||= {}
33
+ @config["timeout"]["default"] ||= 10 * 60 # default 10 min
34
+ @config["timeout"]["default_short"] ||= 60 # default 1 min
35
+ @config["timeout"]["default_long"] ||= 30 * 60 # default 30 min
36
+ @config["timeout"]["start"] ||= @config["timeout"]["default_short"]
37
+ @config["timeout"]["bison-version"] ||= @config["timeout"]["default_short"]
38
+ @config["timeout"]["svn/ruby"] ||= @config["timeout"]["default"]
39
+ @config["timeout"]["svn/info"] ||= @config["timeout"]["default_short"]
40
+ @config["timeout"]["configure"] ||= @config["timeout"]["default"]
41
+ @config["timeout"]["cc-version"] ||= @config["timeout"]["default_short"]
42
+ @config["timeout"]["miniruby"] ||= @config["timeout"]["default"]
43
+ @config["timeout"]["miniversion"] ||= @config["timeout"]["default_short"]
44
+ @config["timeout"]["btest"] ||= @config["timeout"]["default"]
45
+ @config["timeout"]["test.rb"] ||= @config["timeout"]["default"]
46
+ @config["timeout"]["showflags"] ||= @config["timeout"]["default_short"]
47
+ @config["timeout"]["main"] ||= @config["timeout"]["default_long"]
48
+ @config["timeout"]["docs"] ||= @config["timeout"]["default"]
49
+ @config["timeout"]["version"] ||= @config["timeout"]["default_short"]
50
+ @config["timeout"]["install-nodoc"] ||= @config["timeout"]["default"]
51
+ @config["timeout"]["install-doc"] ||= @config["timeout"]["default"]
52
+ @config["timeout"]["test-knownbug"] ||= @config["timeout"]["default"]
53
+ @config["timeout"]["test-all"] ||= @config["timeout"]["default_long"]
54
+
55
+ @last_status = nil
56
+ end
57
+
58
+ def run
59
+ begin
60
+ orig_path = insert_path("PATH", @config["path_add"])
61
+ orig_include = insert_path("INCLUDE", @config["include_add"])
62
+ orig_lib = insert_path("LIB", @config["lib_add"])
63
+ if @config["tmpdir"]
64
+ @config["env"] ||= {}
65
+ @config["env"]["TMP"] ||= @config["tmpdir"].gsub(%r(/), '\\')
66
+ @config["env"]["TEMP"] ||= @config["tmpdir"].gsub(%r(/), '\\')
67
+ end
68
+ orig_env = {}
69
+ (@config["env"] || {}).each do |name, value|
70
+ orig_env[name] = ENV[name]
71
+ ENV[name] = value
72
+ end
73
+ files = []
74
+ Dir.mktmpdir("mswin-build", @config["tmpdir"]) do |tmpdir|
75
+ files << baseinfo(tmpdir)
76
+ files << checkout(tmpdir)
77
+ if @last_status && @last_status.success?
78
+ files << configure(tmpdir)
79
+ files << cc_version(tmpdir)
80
+ files << miniruby(tmpdir)
81
+ files << miniversion(tmpdir)
82
+ files << btest(tmpdir)
83
+ files << testrb(tmpdir)
84
+ #files << method_list(tmpdir)
85
+ files << showflags(tmpdir) if ruby_version >= "1.9.3"
86
+ files << main(tmpdir)
87
+ files << docs(tmpdir)
88
+ files << version(tmpdir)
89
+ files << install_nodoc(tmpdir)
90
+ files << install_doc(tmpdir)
91
+ #files << version_list(tmpdir)
92
+ files << test_knownbug(tmpdir)
93
+ files << test_all(tmpdir)
94
+ files << rubyspec(tmpdir)
95
+ end
96
+ files << end_(tmpdir)
97
+ logfile = gather_log(files, tmpdir)
98
+ difffile = diff(tmpdir, logfile)
99
+ logfile = gzip(logfile)
100
+ gzip(difffile)
101
+ add_recent(logfile)
102
+ add_summary(logfile)
103
+ end
104
+ true
105
+ rescue
106
+ STDERR.puts $!
107
+ STDERR.puts $!.backtrace
108
+ false
109
+ ensure
110
+ orig_env.each_pair do |name, value|
111
+ if value
112
+ ENV[name] = value
113
+ else
114
+ ENV.delete(name)
115
+ end
116
+ end
117
+ ENV["LIB"] = orig_lib if orig_lib
118
+ ENV["INCLUDE"] = orig_include if orig_include
119
+ ENV["PATH"] = orig_path if orig_path
120
+ end
121
+ end
122
+
123
+ def get_current_revision
124
+ orig_lang = ENV["LANG"]
125
+ ENV["LANG"] = "C"
126
+ begin
127
+ if /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ `#{@config['svn']} info #{@config['repository']}`
128
+ $1
129
+ else
130
+ nil
131
+ end
132
+ rescue
133
+ nil
134
+ ensure
135
+ ENV["LANG"] = orig_lang
136
+ end
137
+ end
138
+
139
+ def get_last_revision
140
+ recent = File.join(@config["logdir"], "recent.html")
141
+ return nil unless File.exist?(recent)
142
+ file = nil
143
+ open(recent, "r") do |f|
144
+ f.read.scan(/^<a href="(.+?)".*?<br>$/) do |line|
145
+ file = $1
146
+ break
147
+ end
148
+ end
149
+ return nil unless file
150
+
151
+ cmd = "#{@config['gzip']} -d -c #{File.join(@config['logdir'], file)}"
152
+ `#{cmd}`.scan(/^(?:SVN )?Last Changed Rev: (\d+)$/) do |line|
153
+ return $1
154
+ end
155
+ nil
156
+ end
157
+
158
+ def get_last_build_time
159
+ recent = File.join(@config["logdir"], "recent.html")
160
+ return nil unless File.exist?(recent)
161
+ open(recent, "r") do |f|
162
+ f.read.scan(/^<a href="(.+?)".*?<br>$/) do |line|
163
+ return Time.parse(File.basename($1, ".log.html"))
164
+ end
165
+ end
166
+ return nil
167
+ end
168
+
169
+ private
170
+ def u(str)
171
+ CGI.escape(str)
172
+ end
173
+
174
+ def h(str)
175
+ CGI.escapeHTML(str)
176
+ end
177
+
178
+ def insert_path(env, add)
179
+ return nil unless add
180
+ orig = ENV[env]
181
+ if orig
182
+ add += ";" unless add[-1] == ?;
183
+ ENV[env] = add + orig
184
+ else
185
+ ENV[env] = add
186
+ end
187
+ orig
188
+ end
189
+
190
+ def spawn_with_timeout(name, command, io)
191
+ pid = nil
192
+ begin
193
+ ret = nil
194
+ timeout(@config["timeout"][name] || @config["timeout"]["default"]) do
195
+ begin
196
+ pid = Process.spawn(command, out: io, err: io)
197
+ _, ret = Process.waitpid2(pid)
198
+ rescue
199
+ ret = nil
200
+ end
201
+ end
202
+ ret
203
+ rescue Timeout::Error => ex
204
+ MswinBuild::ProcessTree.terminate_process_tree(pid) if pid
205
+ raise ex
206
+ end
207
+ end
208
+
209
+ def do_command(io, name, command, in_builddir = false, check_retval = true, lang = "C")
210
+ heading(io, name)
211
+ status = nil
212
+ if lang
213
+ orig_lang = ENV["LANG"]
214
+ ENV["LANG"] = lang
215
+ end
216
+ begin
217
+ if $debug
218
+ puts "+ #{command}"
219
+ $stdout.flush
220
+ end
221
+ io.puts "+ #{command}"
222
+ io.flush
223
+ if in_builddir
224
+ if File.exist?(@builddir)
225
+ Dir.chdir(@builddir) do
226
+ status = spawn_with_timeout(name, command, io)
227
+ end
228
+ else
229
+ status = nil
230
+ end
231
+ else
232
+ status = spawn_with_timeout(name, command, io)
233
+ end
234
+
235
+ if status.nil? || !status.success?
236
+ io.puts "exit #{status.to_i}" unless status.nil?
237
+ io.puts "failed(#{name})"
238
+ @title << "failed(#{name})" if check_retval || status.nil?
239
+ @links[name] << "failed"
240
+ if $debug
241
+ puts %'failed(#{name}) #{status.nil? ? "because maybe command not found" : "with status #{status.to_i}"}'
242
+ $stdout.flush
243
+ end
244
+ end
245
+ rescue Timeout::Error
246
+ io.puts
247
+ io.printf "|output interval exceeds %.1f seconds. (CommandTimeout)", @config["timeout"][name] || @config["timeout"]["default"]
248
+ io.puts $!.backtrace.join("\n| ")
249
+ io.puts "failed(#{name} CommandTimeout)"
250
+ @title << "failed(#{name} CommandTimeout)"
251
+ @links[name] << "failed"
252
+ if $debug
253
+ puts "failed(#{name} CommandTimeout)"
254
+ $stdout.flush
255
+ end
256
+ ensure
257
+ ENV["LANG"] = orig_lang if lang
258
+ end
259
+ @last_status = status
260
+ status.nil? ? nil : status.success?
261
+ end
262
+
263
+ def heading(io, name)
264
+ if $debug
265
+ puts "== #{name}"
266
+ $stdout.flush
267
+ end
268
+ anchor = u name.to_s.tr('_', '-')
269
+ text = h name.to_s.tr('_', '-')
270
+ io.puts %'<a name="#{anchor}">== #{text}</a> \# #{h Time.now.iso8601}'
271
+ @links[name] = [anchor, text]
272
+ end
273
+
274
+ def self.define_buildmethod(method, &blk)
275
+ define_method("bare_#{method.to_s}", blk)
276
+ define_method(method) do |tmpdir|
277
+ io = open(File.join(tmpdir, method.to_s), "w+")
278
+ begin
279
+ __send__("bare_#{method.to_s}", io, tmpdir)
280
+ ensure
281
+ io.close
282
+ end
283
+ io
284
+ end
285
+ end
286
+
287
+ define_buildmethod(:baseinfo) do |io, tmpdir|
288
+ @start_time = Time.now
289
+ # target
290
+ heading(io, @target)
291
+ host = Socket.gethostname.split(/\./).first
292
+ @title << "(#{host})"
293
+ io.puts "Nickname: #{host}"
294
+ io.puts "#{`ver`.gsub(/\r?\n/, '')} #{ENV['OS']} #{ENV['ProgramW6432'] ? 'x64' : 'i386'}"
295
+
296
+ # start
297
+ heading(io, "start")
298
+
299
+ # cpu-info
300
+ #heading(io, "cpu-info")
301
+
302
+ # bison-version
303
+ do_command(io, "bison-version", "#{@config['bison']} --version")
304
+ end
305
+
306
+ define_buildmethod(:checkout) do |io, tmpdir|
307
+ # svn/ruby
308
+ Dir.chdir(tmpdir) do
309
+ do_command(io, "svn/ruby", "#{@config['svn']} checkout #{@config['repository']} ruby")
310
+ end
311
+
312
+ # svn-info/ruby
313
+ @builddir = File.join(tmpdir, "ruby")
314
+ do_command(io, "svn-info/ruby", "#{@config['svn']} info", true)
315
+ end
316
+
317
+ define_buildmethod(:configure) do |io, tmpdir|
318
+ options = " --with-baseruby=#{@config['baseruby'].gsub(%r(/), '\\')}" if ruby_version >= "1.9.0"
319
+ do_command(io, "configure", "win32/configure.bat --prefix=#{destdir(tmpdir)}#{options}", true)
320
+ end
321
+
322
+ define_buildmethod(:cc_version) do |io, tmpdir|
323
+ do_command(io, "cc-version", "cl")
324
+ end
325
+
326
+ define_buildmethod(:miniruby) do |io, tmpdir|
327
+ do_command(io, "miniruby", "nmake -l miniruby", true)
328
+ end
329
+
330
+ define_buildmethod(:miniversion) do |io, tmpdir|
331
+ do_command(io, "miniversion", "./miniruby -v", true)
332
+ end
333
+
334
+ define_buildmethod(:btest) do |io, tmpdir|
335
+ ret = do_command(io, "btest", 'nmake -l "OPTS=-v -q" btest', true, false)
336
+ if !ret && !ret.nil?
337
+ io.rewind
338
+ if %r'^FAIL (\d+)/\d+' =~ io.read
339
+ @title << "#{$1}BFail"
340
+ else
341
+ @title << "failed(btest)"
342
+ end
343
+ end
344
+ end
345
+
346
+ define_buildmethod(:testrb) do |io, tmpdir|
347
+ ret = do_command(io, "test.rb", "./miniruby sample/test.rb", true, false)
348
+ if !ret && !ret.nil?
349
+ io.rewind
350
+ if %r'^not ok/test: \d+ failed (\d+)' =~ io.read
351
+ @title << "#{$1}NotOK"
352
+ else
353
+ @title << "failed(test.rb)"
354
+ end
355
+ end
356
+ end
357
+
358
+ define_buildmethod(:showflags) do |io, tmpdir|
359
+ do_command(io, "showflags", "nmake -l showflags", true)
360
+ end
361
+
362
+ define_buildmethod(:main) do |io, tmpdir|
363
+ do_command(io, "main", "nmake -l main", true)
364
+ end
365
+
366
+ define_buildmethod(:docs) do |io, tmpdir|
367
+ do_command(io, "docs", "nmake -l docs", true)
368
+ end
369
+
370
+ define_buildmethod(:version) do |io, tmpdir|
371
+ if do_command(io, "version", "./ruby -v", true)
372
+ io.rewind
373
+ @title.unshift(io.read.split(/\r?\n/).last.chomp)
374
+ else
375
+ @title.unshift(@target)
376
+ end
377
+ end
378
+
379
+ define_buildmethod(:install_nodoc) do |io, tmpdir|
380
+ options = " DESTDIR=#{destdir(tmpdir)}" if ruby_version < "1.9.0"
381
+ do_command(io, "install-nodoc", "nmake -l install-nodoc#{options}", true)
382
+ end
383
+
384
+ define_buildmethod(:install_doc) do |io, tmpdir|
385
+ options = " DESTDIR=#{destdir(tmpdir)}" if ruby_version < "1.9.0"
386
+ do_command(io, "install-doc", "nmake -l install-doc#{options}", true)
387
+ end
388
+
389
+ define_buildmethod(:test_knownbug) do |io, tmpdir|
390
+ do_command(io, "test-knownbug", 'nmake -l "OPTS=-v -q" test-knownbug', true, false)
391
+ end
392
+
393
+ define_buildmethod(:test_all) do |io, tmpdir|
394
+ ret = do_command(io, "test-all", "nmake -l TESTS=-v RUBYOPT=-w test-all", true, false, nil)
395
+ if !ret && !ret.nil?
396
+ io.rewind
397
+ if %r'^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors, (\d+) skips' =~ io.read
398
+ @title << "#{$1}F#{$2}E"
399
+ else
400
+ @title << "failed(test-all)"
401
+ end
402
+ end
403
+ end
404
+
405
+ define_buildmethod(:rubyspec) do |io, tmpdir|
406
+ heading(io, "rubyspec")
407
+ io.puts "skipped."
408
+ @links["rubyspec"] << "skipped"
409
+ end
410
+
411
+ define_buildmethod(:end_) do |io, tmpdir|
412
+ unless /failed|BFail|NotOK|\d+F\d+E/ =~ @title.join
413
+ heading(io, "success")
414
+ @title << "success"
415
+ end
416
+
417
+ heading(io, "end")
418
+ diff = Time.now - @start_time
419
+ io.printf "elapsed %.1fs = %dm %04.1fs\n", diff, diff / 60, diff % 60
420
+ end
421
+
422
+ def destdir(tmpdir)
423
+ File.join(tmpdir, 'install')
424
+ end
425
+
426
+ def ruby_version
427
+ if /_(\d)_(\d)(?:_(\d+))?$/ =~ @config["repository"]
428
+ return "#{$1}.#{$2}.#{$3 || 9}"
429
+ else
430
+ return "9.9.9" # means unknown (maybe trunk)
431
+ end
432
+ end
433
+
434
+ def header(io)
435
+ title = @title.join(' ')
436
+ io.puts <<-EOH
437
+ <html>
438
+ <head>
439
+ <title>#{h title}</title>
440
+ <meta name="author" content="mswin-build">
441
+ <meta name="generator" content="mswin-build">
442
+ </head>
443
+ <body>
444
+ <h1>#{h title}</h1>
445
+ <p>
446
+ <a href="../../">mswin-build</a>
447
+ <a href="../summary.html">summary</a>
448
+ <a href="../recent.html">recent</a>
449
+ </p>
450
+ EOH
451
+ end
452
+
453
+ def footer(io)
454
+ io.puts <<-EOH
455
+ <hr>
456
+ <p>
457
+ <a href="../../">mswin-build</a>
458
+ <a href="../summary.html">summary</a>
459
+ <a href="../recent.html">recent</a>
460
+ </p>
461
+ </body>
462
+ </html>
463
+ EOH
464
+ end
465
+
466
+ def gather_log(files, tmpdir)
467
+ logdir = File.join(@config["logdir"], "log")
468
+ FileUtils.mkdir_p(logdir)
469
+ logfile = File.join(logdir, @start_time.dup.utc.strftime('%Y%m%dT%H%M%SZ.log.html'))
470
+ warns = 0
471
+ revision = nil
472
+ open(File.join(tmpdir, "gathered"), "w") do |out|
473
+ files.each_with_index do |io, i|
474
+ next unless io
475
+ io.reopen(io.path, "r")
476
+ begin
477
+ io.each_line do |line|
478
+ line = h(line) unless /^<a / =~ line
479
+ out.write line
480
+ warns += line.scan(/warn/i).length
481
+ if File.basename(io.path) == "checkout" && /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ line
482
+ revision = $1
483
+ end
484
+ end
485
+ ensure
486
+ io.close
487
+ io.unlink rescue nil
488
+ end
489
+ end
490
+ end
491
+ @title.insert(2, "#{warns}W") if warns > 0
492
+ @title.unshift("r#{revision}") if revision
493
+ open(logfile, "w") do |out|
494
+ header(out)
495
+ out.puts " <ul>"
496
+ @links.each_value do |anchor, text, result = nil|
497
+ out.puts %' <li><a href="\##{anchor}">#{text}</a>#{" #{result}" if result}</li>'
498
+ end
499
+ out.puts " </ul>"
500
+ out.puts " <pre>"
501
+ out.write IO.read(File.join(tmpdir, "gathered"))
502
+ out.puts " </pre>"
503
+ footer(out)
504
+ end
505
+ logfile
506
+ end
507
+
508
+ def diff(tmpdir, logfile)
509
+ filename = logfile.sub(/\.log/, ".diff")
510
+ open(filename, "w") do |out|
511
+ header(out)
512
+ out.puts %'<p>Skipped. See the <a href="#{u File.basename(logfile)}.gz">full build log</a>.</p>'
513
+ footer(out)
514
+ end
515
+ filename
516
+ end
517
+
518
+ def gzip(file)
519
+ system("#{@config['gzip']} #{file}")
520
+ file + ".gz"
521
+ end
522
+
523
+ def add_recent(logfile)
524
+ add_recent_summary(logfile, :recent)
525
+ end
526
+
527
+ def add_summary(logfile)
528
+ add_recent_summary(logfile, :summary)
529
+ end
530
+
531
+ def add_recent_summary(logfile, mode)
532
+ if mode == :recent
533
+ filename = File.join(@config["logdir"], "recent.html")
534
+ else
535
+ filename = File.join(@config["logdir"], "summary.html")
536
+ end
537
+ old = []
538
+ if File.exist?(filename)
539
+ open(filename, "r") do |f|
540
+ f.read.scan(/^(<a .*?<br>)$/) do |line| #"
541
+ old << line
542
+ end
543
+ end
544
+ end
545
+
546
+ title = @title.join(' ')
547
+ time = File.basename(logfile, ".log.html.gz")
548
+ line = %'<a href="log/#{u time}.log.html.gz" name="#{u time}">#{h time}</a> #{h title} (<a href="log/#{u time}.diff.html.gz">#{@diff ? h(@diff) : "no diff"}</a>)<br>'
549
+ if mode == :recent
550
+ old = old[0..99]
551
+ old.unshift(line)
552
+ else
553
+ old.push(line)
554
+ end
555
+ open(filename, "w") do |f|
556
+ f.print <<-EOH
557
+ <html>
558
+ <head>
559
+ <title>#{h File.basename(@config['logdir'])} #{h mode.to_s} build summary (#{h @target})</title>
560
+ <meta name="author" content="mswin-build">
561
+ <meta name="generator" content="mswin-build">
562
+ </head>
563
+ <body>
564
+ <h1>#{h File.basename(@config['logdir'])} #{h mode.to_s} build summary (#{h @target})</h1>
565
+ <p>
566
+ <a href="../">mswin-build</a>
567
+ <a href="./summary.html">summary</a>
568
+ <a href="./recent.html">recent</a>
569
+ </p>
570
+ EOH
571
+
572
+ old.each do |line|
573
+ f.puts line
574
+ end
575
+
576
+ f.print <<-EOH
577
+ <hr>
578
+ <p>
579
+ <a href="../">mswin-build</a>
580
+ <a href="./summary.html">summary</a>
581
+ <a href="./recent.html">recent</a>
582
+ </p>
583
+ </body>
584
+ </html>
585
+ EOH
586
+ end
587
+ end
588
+ end
589
+ end
@@ -0,0 +1,80 @@
1
+ begin
2
+ require "fiddle/import"
3
+ require "fiddle/types"
4
+ rescue LoadError
5
+ # 1.9?
6
+ require "dl/import"
7
+ require "dl/types"
8
+
9
+ Fiddle::Importer = DL::Importer
10
+ Fiddle::Win32Types = DL::Win32Types
11
+ end
12
+
13
+ module MswinBuild
14
+ module ProcessTree
15
+ extend Fiddle::Importer
16
+
17
+ dlload "kernel32.dll", "ntdll.dll"
18
+
19
+ include Fiddle::Win32Types
20
+ if /64/ =~ RUBY_PLATFORM
21
+ typealias "ULONG_PTR", "unsigned long long"
22
+ else
23
+ typealias "ULONG_PTR", "unsigned long"
24
+ end
25
+ typealias "TCHAR", "char"
26
+
27
+ # from tlhelp32.h
28
+ TH32CS_SNAPPROCESS = 0x00000002
29
+ PROCESSENTRY32 = struct([
30
+ "DWORD dwSize",
31
+ "DWORD cntUsage",
32
+ "DWORD th32ProcessID",
33
+ "ULONG_PTR th32DefaultHeapID",
34
+ "DWORD th32ModuleID",
35
+ "DWORD cntThreads",
36
+ "DWORD th32ParentProcessID",
37
+ "long pcPriClassBase",
38
+ "DWORD dwFlags",
39
+ "TCHAR szExeFile[260]", # [MAX_PATH]
40
+ ])
41
+
42
+ # from kernel32.dll
43
+ extern "BOOL CloseHandle(HANDLE)"
44
+ extern "HANDLE CreateToolhelp32Snapshot(DWORD, DWORD)"
45
+ extern "BOOL Process32First(HANDLE, VOID*)"
46
+ extern "BOOL Process32Next(HANDLE, VOID*)"
47
+ extern "DWORD GetLastError(void)"
48
+
49
+ def self.terminate_process_tree(pid, code = 0)
50
+ begin
51
+ terminated = 0
52
+ h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
53
+ unless pid == Process.pid
54
+ Process.kill(:KILL, pid)
55
+ terminated += 1
56
+ end
57
+ pe32 = PROCESSENTRY32.malloc
58
+ pe32.dwSize = PROCESSENTRY32.size
59
+ if Process32First(h, pe32) != 0
60
+ begin
61
+ if pe32.th32ParentProcessID == pid
62
+ terminated += terminate_process_tree(pe32.th32ProcessID, code)
63
+ end
64
+ end while Process32Next(h, pe32) != 0
65
+ else
66
+ raise sprintf("Cannot get processes: %d", GetLastError())
67
+ end
68
+ ensure
69
+ CloseHandle(h) if h
70
+ end
71
+
72
+ if pid == Process.pid
73
+ Process.kill(:KILL, pid)
74
+ terminated += 1
75
+ end
76
+
77
+ terminated
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ module MswinBuild
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ # -*- Ruby -*-
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'mswin-build/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "mswin-build"
9
+ spec.version = MswinBuild::VERSION
10
+ spec.authors = ["U.Nakamura"]
11
+ spec.email = ["usa@garbagecollect.jp"]
12
+ spec.description = %q{A low quality clone of https://github.com/akr/chkbuild for mswin.}
13
+ spec.summary = %q{A low quality clone of https://github.com/akr/chkbuild for mswin.}
14
+ spec.homepage = "https://github.com/unak/mswin-build"
15
+ spec.license = "BSD-2-Clause"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "test-unit"
25
+ end
@@ -0,0 +1,260 @@
1
+ require "fileutils"
2
+ require "tmpdir"
3
+ require "tempfile"
4
+ require "test/unit"
5
+ require "mswin-build/builder.rb"
6
+
7
+ module ProcessMock
8
+ @callback = nil
9
+
10
+ def self.spawn(*args)
11
+ @status = @callback.call(args, @param)
12
+ @status.pid
13
+ end
14
+
15
+ def self.waitpid2(pid, flags = 0)
16
+ [pid, @status]
17
+ end
18
+
19
+ def self.set_callback(param = nil, &blk)
20
+ @param = param
21
+ @callback = blk
22
+ end
23
+ end
24
+
25
+ class StatusMock
26
+ attr_accessor :to_i, :pid
27
+ alias to_int to_i
28
+
29
+ def initialize(retval, pid = rand(65536))
30
+ @to_i = retval
31
+ @pid = pid
32
+ end
33
+
34
+ def success?
35
+ @to_i.zero?
36
+ end
37
+ end
38
+
39
+ class TestBuilder < Test::Unit::TestCase
40
+ def setup
41
+ @tmpdir = Dir.mktmpdir('TestBuilder')
42
+ @yaml = Tempfile.open('TestBuilder', @tmpdir)
43
+ @yaml.puts <<-EOY
44
+ baseruby: ruby
45
+ repository: dummy_repository
46
+ logdir: #{@tmpdir}
47
+ tmpdir: #{@tmpdir}
48
+ env:
49
+ DUMMY: foo
50
+ EOY
51
+ @yaml.open # rewind for reading
52
+ end
53
+
54
+ def teardown
55
+ @yaml.close!
56
+ FileUtils.rm_r(@tmpdir)
57
+ end
58
+
59
+ def run_builder(hash = {}, &blk)
60
+ builder = MswinBuild::Builder.new(target: "dummy", settings: @yaml.path)
61
+ if !hash.empty?
62
+ config = builder.instance_variable_get(:@config)
63
+ config["timeout"]["test-all"] = hash[:timeout] if hash[:timeout]
64
+ builder.instance_variable_set(:@config, config)
65
+ end
66
+ begin
67
+ origProcess = Process
68
+ Object.class_eval do
69
+ remove_const :Process
70
+ const_set :Process, ProcessMock
71
+ end
72
+
73
+ commands = [
74
+ /^bison --version$/,
75
+ /^svn checkout dummy_repository ruby$/,
76
+ /^svn info$/,
77
+ /^win32\/configure\.bat --prefix=[^ ]+ --with-baseruby=ruby$/,
78
+ /^cl$/,
79
+ /^nmake -l miniruby$/,
80
+ /^\.\/miniruby -v$/,
81
+ /^nmake -l "OPTS=-v -q" btest$/,
82
+ /^\.\/miniruby sample\/test\.rb/,
83
+ /^nmake -l showflags$/,
84
+ /^nmake -l main$/,
85
+ /^nmake -l docs$/,
86
+ /^\.\/ruby -v$/,
87
+ /^nmake -l install-nodoc$/,
88
+ /^nmake -l install-doc$/,
89
+ /^nmake -l "OPTS=-v -q" test-knownbug$/,
90
+ /^nmake -l TESTS=-v RUBYOPT=-w test-all$/,
91
+ ]
92
+
93
+ ProcessMock.set_callback(commands, &blk)
94
+
95
+ builder.run
96
+
97
+ assert_empty commands
98
+ assert_equal hash[:revision].to_s, builder.get_last_revision if hash[:revision]
99
+ ensure
100
+ Object.class_eval do
101
+ remove_const :Process
102
+ const_set :Process, origProcess
103
+ end
104
+ end
105
+
106
+ assert File.exist?(File.join(@tmpdir, "recent.html"))
107
+ assert File.exist?(File.join(@tmpdir, "summary.html"))
108
+ assert File.directory?(File.join(@tmpdir, "log"))
109
+ files = Dir.glob(File.join(@tmpdir, "log", "*"))
110
+ assert files.reject! {|e| /\.log\.html\.gz\z/ =~ e}
111
+ assert files.reject! {|e| /\.diff\.html\.gz\z/ =~ e}
112
+ assert_empty files
113
+ end
114
+
115
+ def test_run_success
116
+ assert_raise(ArgumentError) do
117
+ MswinBuild::Builder.new
118
+ end
119
+
120
+ assert_raise(RuntimeError) do
121
+ MswinBuild::Builder.new(target: "dummy")
122
+ end
123
+
124
+ assert_raise(RuntimeError) do
125
+ MswinBuild::Builder.new(settings: @yaml.path)
126
+ end
127
+
128
+ assert_raise(RuntimeError) do
129
+ MswinBuild::Builder.new(target: "dummy", settings: @yaml.path, foo: nil)
130
+ end
131
+
132
+ run_builder(revision: 12345) do |args, commands|
133
+ assert_not_empty commands, "for ``#{args[0]}''"
134
+ assert_match commands.shift, args[0]
135
+
136
+ case args[0]
137
+ when /^svn checkout\b/
138
+ Dir.mkdir("ruby")
139
+ when /^svn info\b/
140
+ if args[1].is_a?(Hash) && args[1][:out]
141
+ args[1][:out].puts "Revision: 54321"
142
+ args[1][:out].puts "Last Changed Rev: 12345"
143
+ end
144
+ end
145
+
146
+ StatusMock.new(0)
147
+ end
148
+
149
+ recent = File.read(File.join(@tmpdir, "recent.html"))
150
+ assert_match /\bsuccess\b/, recent
151
+ assert_match /^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent
152
+ end
153
+
154
+ def test_run_btest_failure
155
+ run_builder do |args, commands|
156
+ commands.shift
157
+
158
+ status = 0
159
+ case args[0]
160
+ when /^svn checkout\b/
161
+ Dir.mkdir("ruby")
162
+ when /\bbtest\b/
163
+ if args[1].is_a?(Hash) && args[1][:out]
164
+ args[1][:out].puts "FAIL 3/456"
165
+ end
166
+ status = 3
167
+ end
168
+
169
+ StatusMock.new(status)
170
+ end
171
+
172
+ recent = File.read(File.join(@tmpdir, "recent.html"))
173
+ assert_match /\b3BFail\b/, recent
174
+ assert_not_match /\bfailed\b/, recent
175
+ end
176
+
177
+ def test_run_testrb_failure
178
+ run_builder do |args, commands|
179
+ commands.shift
180
+
181
+ status = 0
182
+ case args[0]
183
+ when /^svn checkout\b/
184
+ Dir.mkdir("ruby")
185
+ when /\btest\.rb\b/
186
+ if args[1].is_a?(Hash) && args[1][:out]
187
+ args[1][:out].puts "not ok/test: 123 failed 4"
188
+ end
189
+ status = 3
190
+ end
191
+
192
+ StatusMock.new(status)
193
+ end
194
+
195
+ recent = File.read(File.join(@tmpdir, "recent.html"))
196
+ assert_match /\b4NotOK\b/, recent
197
+ assert_not_match /\bfailed\b/, recent
198
+ end
199
+
200
+ def test_run_test_all_failure
201
+ run_builder do |args, commands|
202
+ commands.shift
203
+
204
+ status = 0
205
+ case args[0]
206
+ when /^svn checkout\b/
207
+ Dir.mkdir("ruby")
208
+ when /\btest-all\b/
209
+ if args[1].is_a?(Hash) && args[1][:out]
210
+ args[1][:out].puts "123 tests, 4567 assertions, 2 failures, 1 errors, 4 skips"
211
+ end
212
+ status = 3
213
+ end
214
+
215
+ StatusMock.new(status)
216
+ end
217
+
218
+ recent = File.read(File.join(@tmpdir, "recent.html"))
219
+ assert_match /\b2F1E\b/, recent
220
+ assert_not_match /\bfailed\b/, recent
221
+ end
222
+
223
+ def test_run_timeout
224
+ run_builder(timeout: 0.1) do |args, commands|
225
+ commands.shift
226
+
227
+ case args[0]
228
+ when /^svn checkout\b/
229
+ Dir.mkdir("ruby")
230
+ when /\btest-all\b/
231
+ StatusMock.new(nil)
232
+ sleep 2
233
+ break
234
+ end
235
+
236
+ StatusMock.new(0)
237
+ end
238
+
239
+ recent = File.read(File.join(@tmpdir, "recent.html"))
240
+ assert_match /\bfailed\(test-all CommandTimeout\)/, recent
241
+ end
242
+
243
+ def test_get_current_revision
244
+ TOPLEVEL_BINDING.eval <<-EOS
245
+ alias orig_backquote ` #`
246
+ def `(cmd) #`
247
+ "Revision: 54321\nLast Changed Rev: 12345\n"
248
+ end
249
+ EOS
250
+
251
+ begin
252
+ builder = MswinBuild::Builder.new(target: "dummy", settings: @yaml.path)
253
+ assert_equal "12345", builder.get_current_revision
254
+ ensure
255
+ TOPLEVEL_BINDING.eval <<-EOS
256
+ alias ` orig_backquote #`
257
+ EOS
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,26 @@
1
+ require "test/unit"
2
+ require "mswin-build/process_tree"
3
+
4
+ class TestProcessTree < Test::Unit::TestCase
5
+ def setup
6
+ @makefile = "Makefile"
7
+ open(@makefile, "w") do |f|
8
+ f.puts <<-EOM
9
+ all:
10
+ @ruby -e "Process.waitpid Process.spawn('ruby -e \"sleep\"')"
11
+ EOM
12
+ end
13
+ end
14
+
15
+ def teardown
16
+ File.delete(@makefile) if File.exist?(@makefile)
17
+ end
18
+
19
+ def test_s_terminate_process_tree
20
+ pid = Process.spawn("nmake -l")
21
+ sleep 1
22
+
23
+ assert_nil Process.waitpid(pid, Process::WNOHANG)
24
+ assert_equal 3, MswinBuild::ProcessTree.terminate_process_tree(pid)
25
+ end
26
+ end if /mswin|mingw/ =~ RUBY_PLATFORM
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mswin-build
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - U.Nakamura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A low quality clone of https://github.com/akr/chkbuild for mswin.
56
+ email:
57
+ - usa@garbagecollect.jp
58
+ executables:
59
+ - build.rb
60
+ - kicker.rb
61
+ - tinyhttpd.rb
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".gitignore"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - README.md
69
+ - Rakefile
70
+ - bin/build.rb
71
+ - bin/kicker.rb
72
+ - bin/tinyhttpd.rb
73
+ - config/vc10-x86-1_9_3.yaml
74
+ - config/vc10-x86-2_0_0.yaml
75
+ - config/vc10-x86-trunk.yaml
76
+ - lib/mswin-build/builder.rb
77
+ - lib/mswin-build/process_tree.rb
78
+ - lib/mswin-build/version.rb
79
+ - mswin-build.gemspec
80
+ - test/unit/test_builder.rb
81
+ - test/unit/test_process_tree.rb
82
+ homepage: https://github.com/unak/mswin-build
83
+ licenses:
84
+ - BSD-2-Clause
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.2.2
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: A low quality clone of https://github.com/akr/chkbuild for mswin.
106
+ test_files:
107
+ - test/unit/test_builder.rb
108
+ - test/unit/test_process_tree.rb