mswin-build 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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