mswin-build 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cfe42674ee22526c93c3fd0347034be4f0af2f48
4
- data.tar.gz: 599a68351770263a39ab8b8accf35d9eaa9a9915
3
+ metadata.gz: ea4522da05a50075fbbb6e7cfc25d221312a7e37
4
+ data.tar.gz: 2c95e422c2abeb72b3e50c6fb6fc27b3a2fd1843
5
5
  SHA512:
6
- metadata.gz: e90cc66dfc5614f26af3d2ecd259a78b4aeb7bd423ce4b50789d205e82dc72b2fb23d8a712344b6288ddec03451fee7d517363dba3e4a797b1c4ebad80178fff
7
- data.tar.gz: b76b8068667a7c70447810af98fe555bd5fc8ad305694b86f7cf69f8bf234ba85d1a04b47d9b4b9edc79a018c6d041b415179dbe836ffca4e3c27c428241a4ee
6
+ metadata.gz: 52f6c484f354119931fb4db8288441175e53ada21d86b7cd5814c2881f2989a111d6dba8137efd708bcc2fc485727e05e5a340965cf155f96821be8f088e332d
7
+ data.tar.gz: 7ab23c4af24e811a00cd27255fde6f7d0377a989fa5ee2e98a133f0357a9c3d1b4d0e76e0ac979a7e9e5ec04c7fa98e00d3ca5000c0a424e4aa58650fe678229
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
+ Gemfile.lock
1
2
  logs
2
3
  pkg
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.1
4
- - 2.0.0
5
- - 1.9.3
3
+ - 2.4.1
4
+ - 2.3.4
5
+ - 2.2.7
6
+ - 2.1.10
6
7
  script:
7
8
  - bundle exec rake build
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Build Status](https://img.shields.io/travis/unak/mswin-build.svg)](https://travis-ci.org/unak/mswin-build)
2
+ [![Version ](https://img.shields.io/gem/v/mswin-build.svg)](https://rubygems.org/gems/mswin-build)
3
+
1
4
  mswin-build
2
5
  ===========
3
6
 
@@ -13,7 +16,7 @@ A low quality clone of https://github.com/akr/chkbuild for mswin.
13
16
  Requirements
14
17
  ------------
15
18
 
16
- * ruby 1.9.3 or 2.0.0 or newer, with fiddle
19
+ * ruby 2.1 or later
17
20
  * sed
18
21
  * bison
19
22
  * svn
data/bin/build.rb CHANGED
@@ -1,4 +1,4 @@
1
- #! ruby
1
+ #!ruby
2
2
  # expected ruby 1.9.x or later.
3
3
  libdir = File.expand_path("../lib", File.dirname(__FILE__))
4
4
  $LOAD_PATH.unshift(libdir) if File.directory?(libdir)
@@ -6,14 +6,14 @@ require "optparse"
6
6
  require "rbconfig"
7
7
  require "mswin-build/builder"
8
8
 
9
- $debug = $DEBUG
10
9
  opt = OptionParser.new
11
10
  opt.banner = "Usage: ruby #$0 [options] <target name>"
12
11
  opt.separator ""
13
12
  opt.separator " This script automatically loads config/<target name>.yaml."
14
13
  opt.separator ""
15
14
  opt.separator "Options:"
16
- opt.on('-v', '--verbose', 'Be verbose.') { $debug = true }
15
+ opt.on('-v', '--verbose', 'Be verbose.') { $DEBUG = true }
16
+ opt.on('-a KEY', '--azure-key=KEY', 'Upload results by KEY') {|v| $azure_key = v }
17
17
 
18
18
  begin
19
19
  opt.parse!(ARGV)
@@ -29,5 +29,12 @@ end
29
29
  # use this running ruby as BASERUBY
30
30
  baseruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
31
31
 
32
- builder = MswinBuild::Builder.new(target: target, baseruby: baseruby, settings: File.expand_path("../config/#{target}.yaml", File.dirname(__FILE__)))
32
+ options = {
33
+ target: target,
34
+ baseruby: baseruby,
35
+ settings: File.expand_path("../config/#{target}.yaml",
36
+ File.dirname(__FILE__))
37
+ }
38
+ options[:azure_key] = $azure_key if $azure_key
39
+ builder = MswinBuild::Builder.new(options)
33
40
  exit builder.run
data/bin/kicker.rb CHANGED
@@ -9,6 +9,7 @@ require "mswin-build/builder"
9
9
  baseruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
10
10
  interval = 60
11
11
  force_build = 24 * 60 * 60 # force build at least once in every day
12
+ cmd_dir = ENV['TEMP']
12
13
 
13
14
  opt = OptionParser.new
14
15
  opt.banner = "Usage: ruby #$0 [options] <target name>"
@@ -19,7 +20,8 @@ opt.separator "Options:"
19
20
  opt.on('-v', '--verbose', "Be verbose. default = #{!$debug.nil? && $debug}") { $debug = true }
20
21
  opt.on('-b <baseruby>', '--baseruby=<baserbuby>', "specify baseruby. default: #{baseruby}") { |v| baseruby = v }
21
22
  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
+ opt.on('-f <seconds>', '--force-build=<seconds>', "force build after specified seconds from last bulid. default: #{force_build}") { |v| force_build = Integer(v) }
24
+ opt.on('-t <directory>', '--command-dir=<directory>', "specify force-build command directory. default: ENV['TEMP'] (#{ENV['TEMP']})") { |v| cmd_dir = v }
23
25
 
24
26
  begin
25
27
  opt.parse!(ARGV)
@@ -34,7 +36,13 @@ end
34
36
  loop do
35
37
  ARGV.each do |target|
36
38
  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
39
+ if File.exist?(File.join(cmd_dir, target))
40
+ force = true
41
+ File.unlink(File.join(cmd_dir, target)) rescue nil
42
+ else
43
+ force = false
44
+ end
45
+ if force || !builder.get_last_build_time || builder.get_last_build_time + force_build < Time.now || builder.get_last_revision != builder.get_current_revision
38
46
  cmd = [baseruby, File.expand_path("build.rb", File.dirname(__FILE__)), target]
39
47
  cmd << "-v" if $debug
40
48
  puts "+++ #{Time.now} Start #{target} +++" if $debug
@@ -0,0 +1,79 @@
1
+ # lib/azure/core/service.rb
2
+ module Azure
3
+ module Core
4
+ class Service
5
+ def call(method, uri, body=nil, headers=nil)
6
+ request = Core::Http::HttpRequest.new(method, uri, body)
7
+ request.headers.merge!(headers) if headers
8
+
9
+ request.headers['connection'] = 'keep-alive' if request.respond_to? :headers
10
+
11
+ yield request if block_given?
12
+
13
+ response = request.call
14
+
15
+ response
16
+ end
17
+ end
18
+
19
+
20
+ module Http
21
+ class HttpRequest
22
+ def default_headers(current_time)
23
+ headers["User-Agent"] = "Azure-SDK-For-Ruby/" + Azure::Version.to_s
24
+ headers["x-ms-date"] = current_time
25
+ headers["x-ms-version"] = "2012-02-12"
26
+ headers["DataServiceVersion"] = "1.0;NetFx"
27
+ headers["MaxDataServiceVersion"] = "2.0;NetFx"
28
+
29
+ if body
30
+ headers["Content-Type"] = "application/atom+xml; charset=utf-8"
31
+ if IO === body
32
+ headers["Content-Length"] = body.size.to_s
33
+ headers["Content-MD5"] = Digest::MD5.file(body.path).base64digest
34
+ else
35
+ headers["Content-Length"] = body.bytesize.to_s
36
+ headers["Content-MD5"] = Base64.strict_encode64(Digest::MD5.digest(body))
37
+ end
38
+ else
39
+ headers["Content-Length"] = "0"
40
+ headers["Content-Type"] = ""
41
+ end
42
+ end
43
+
44
+ def call
45
+ request = http_request_class.new(uri.request_uri, headers)
46
+ if IO === body
47
+ request.body_stream = body
48
+ elsif body
49
+ request.body = body
50
+ end
51
+
52
+ http = nil
53
+ if ENV['HTTP_PROXY'] || ENV['HTTPS_PROXY']
54
+ if ENV['HTTP_PROXY']
55
+ proxy_uri = URI::parse(ENV['HTTP_PROXY'])
56
+ else
57
+ proxy_uri = URI::parse(ENV['HTTPS_PROXY'])
58
+ end
59
+
60
+ http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new(uri.host, uri.port)
61
+ else
62
+ http = Net::HTTP.new(uri.host, uri.port)
63
+ end
64
+
65
+ if uri.scheme.downcase == 'https'
66
+ # require 'net/https'
67
+ http.use_ssl = true
68
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
69
+ end
70
+
71
+ response = HttpResponse.new(http.request(request))
72
+ response.uri = uri
73
+ raise response.error unless response.success?
74
+ response
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -6,6 +6,7 @@ require "timeout"
6
6
  require "tmpdir"
7
7
  require "yaml"
8
8
  require "mswin-build/process_tree"
9
+ require "mswin-build/upload"
9
10
 
10
11
  module MswinBuild
11
12
  class Builder
@@ -13,6 +14,7 @@ module MswinBuild
13
14
  @target = h.delete(:target) || raise("target not specified")
14
15
  baseruby = h.delete(:baseruby)
15
16
  yaml = h.delete(:settings) || raise("settings not specified")
17
+ azure_key = h.delete(:azure_key)
16
18
  unless h.empty?
17
19
  raise "unknown option(s): #{h}"
18
20
  end
@@ -26,9 +28,18 @@ module MswinBuild
26
28
  raise "repository not specified" unless @config["repository"]
27
29
  raise "logdir not specfied" unless @config["logdir"]
28
30
 
31
+ @config["azure_key"] = azure_key if azure_key
32
+ if@config["azure_key"]
33
+ ENV['AZURE_STORAGE_ACCESS_KEY'] = @config["azure_key"]
34
+ MswinBuild.register_azure_upload(@config["logdir"])
35
+ end
36
+
37
+ @data = {}
29
38
  @title = []
30
39
  @links = {}
31
40
 
41
+ @diff = nil
42
+
32
43
  @config["timeout"] ||= {}
33
44
  @config["timeout"]["default"] ||= 10 * 60 # default 10 min
34
45
  @config["timeout"]["default_short"] ||= 60 # default 1 min
@@ -76,13 +87,16 @@ module MswinBuild
76
87
  files << checkout(tmpdir)
77
88
  if @last_status && @last_status.success?
78
89
  files << configure(tmpdir)
90
+ files << update_unicode(tmpdir)
91
+ files << update_gems(tmpdir)
92
+ files << extract_extlibs(tmpdir)
79
93
  files << cc_version(tmpdir)
80
94
  files << miniruby(tmpdir)
81
95
  files << miniversion(tmpdir)
82
96
  files << btest(tmpdir)
83
97
  files << testrb(tmpdir)
84
98
  #files << method_list(tmpdir)
85
- files << showflags(tmpdir) if ruby_version >= "1.9.3"
99
+ files << showflags(tmpdir)
86
100
  files << main(tmpdir)
87
101
  files << docs(tmpdir)
88
102
  files << version(tmpdir)
@@ -97,9 +111,13 @@ module MswinBuild
97
111
  logfile = gather_log(files, tmpdir)
98
112
  difffile = diff(tmpdir, logfile)
99
113
  logfile = gzip(logfile)
100
- gzip(difffile)
114
+ @data[:compressed_loghtml_relpath] = File.join("log", File.basename(logfile))
115
+ difffile = gzip(difffile)
116
+ @data[:compressed_diffhtml_relpath] = File.join("log", File.basename(difffile))
101
117
  add_recent(logfile)
102
118
  add_summary(logfile)
119
+
120
+ MswinBuild.run_upload_hooks
103
121
  end
104
122
  true
105
123
  rescue
@@ -124,7 +142,7 @@ module MswinBuild
124
142
  orig_lang = ENV["LANG"]
125
143
  ENV["LANG"] = "C"
126
144
  begin
127
- if /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ `#{@config['svn']} info #{@config['repository']}`
145
+ if /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ `#{@config['svn']} info #{@config['repository']} 2> NUL`
128
146
  $1
129
147
  else
130
148
  nil
@@ -191,7 +209,7 @@ module MswinBuild
191
209
  pid = nil
192
210
  begin
193
211
  ret = nil
194
- timeout(@config["timeout"][name] || @config["timeout"]["default"]) do
212
+ Timeout.timeout(@config["timeout"][name] || @config["timeout"]["default"]) do
195
213
  begin
196
214
  pid = Process.spawn(command, out: io, err: io)
197
215
  _, ret = Process.waitpid2(pid)
@@ -206,7 +224,7 @@ module MswinBuild
206
224
  end
207
225
  end
208
226
 
209
- def do_command(io, name, command, in_builddir = false, check_retval = true, lang = "C")
227
+ def do_command(io, name, command, in_builddir = false, check_retval = true, lang = "C", &blk)
210
228
  heading(io, name)
211
229
  status = nil
212
230
  if lang
@@ -214,7 +232,7 @@ module MswinBuild
214
232
  ENV["LANG"] = lang
215
233
  end
216
234
  begin
217
- if $debug
235
+ if $DEBUG
218
236
  puts "+ #{command}"
219
237
  $stdout.flush
220
238
  end
@@ -224,20 +242,23 @@ module MswinBuild
224
242
  if File.exist?(@builddir)
225
243
  Dir.chdir(@builddir) do
226
244
  status = spawn_with_timeout(name, command, io)
245
+ blk.call(status) if blk
227
246
  end
228
247
  else
229
248
  status = nil
230
249
  end
231
250
  else
232
251
  status = spawn_with_timeout(name, command, io)
252
+ blk.call(status) if blk
233
253
  end
234
254
 
235
255
  if status.nil? || !status.success?
236
256
  io.puts "exit #{status.to_i}" unless status.nil?
237
257
  io.puts "failed(#{name})"
238
258
  @title << "failed(#{name})" if check_retval || status.nil?
259
+ @data[:result] = "failure"
239
260
  @links[name] << "failed"
240
- if $debug
261
+ if $DEBUG
241
262
  puts %'failed(#{name}) #{status.nil? ? "because maybe command not found" : "with status #{status.to_i}"}'
242
263
  $stdout.flush
243
264
  end
@@ -248,8 +269,9 @@ module MswinBuild
248
269
  io.puts $!.backtrace.join("\n| ")
249
270
  io.puts "failed(#{name} CommandTimeout)"
250
271
  @title << "failed(#{name} CommandTimeout)"
272
+ @data[:result] = "failure"
251
273
  @links[name] << "failed"
252
- if $debug
274
+ if $DEBUG
253
275
  puts "failed(#{name} CommandTimeout)"
254
276
  $stdout.flush
255
277
  end
@@ -261,7 +283,7 @@ module MswinBuild
261
283
  end
262
284
 
263
285
  def heading(io, name)
264
- if $debug
286
+ if $DEBUG
265
287
  puts "== #{name}"
266
288
  $stdout.flush
267
289
  end
@@ -286,10 +308,12 @@ module MswinBuild
286
308
 
287
309
  define_buildmethod(:baseinfo) do |io, tmpdir|
288
310
  @start_time = Time.now
311
+ @data[:start_time] = @start_time.dup.utc.strftime('%Y%m%dT%H%M%SZ')
289
312
  # target
290
313
  heading(io, @target)
291
314
  host = Socket.gethostname.split(/\./).first
292
315
  @title << "(#{host})"
316
+ @data[:host] = host
293
317
  io.puts "Nickname: #{host}"
294
318
  io.puts "#{`ver`.gsub(/\r?\n/, '')} #{ENV['OS']} #{ENV['ProgramW6432'] ? 'x64' : 'i386'}"
295
319
 
@@ -311,14 +335,52 @@ module MswinBuild
311
335
 
312
336
  # svn-info/ruby
313
337
  @builddir = File.join(tmpdir, "ruby")
314
- do_command(io, "svn-info/ruby", "#{@config['svn']} info", true)
338
+ do_command(io, "svn-info/ruby", "#{@config['svn']} info", true) do |s|
339
+ if /^URL: (.*)$/ =~ `#{@config['svn']} info 2> NUL`
340
+ @data[:svn_url] = $1
341
+ end
342
+ end
315
343
  end
316
344
 
317
345
  define_buildmethod(:configure) do |io, tmpdir|
318
346
  options = " --with-baseruby=#{@config['baseruby'].gsub(%r(/), '\\')}" if ruby_version >= "1.9.0"
347
+ options << " #{@config['configure_args']}"
319
348
  do_command(io, "configure", "win32/configure.bat --prefix=#{destdir(tmpdir)}#{options}", true)
320
349
  end
321
350
 
351
+ define_buildmethod(:update_unicode) do |io, tmpdir|
352
+ begin
353
+ open(File.join(@builddir, 'common.mk')) do |f|
354
+ if /^update-unicode:/ =~ f.read
355
+ do_command(io, "update-unicode", "nmake -l update-unicode", true)
356
+ end
357
+ end
358
+ rescue Errno::ENOENT
359
+ end
360
+ end
361
+
362
+ define_buildmethod(:update_gems) do |io, tmpdir|
363
+ begin
364
+ open(File.join(@builddir, 'common.mk')) do |f|
365
+ if /^update-gems:/ =~ f.read
366
+ do_command(io, "update-gems", "nmake -l update-gems", true)
367
+ end
368
+ end
369
+ rescue Errno::ENOENT
370
+ end
371
+ end
372
+
373
+ define_buildmethod(:extract_extlibs) do |io, tmpdir|
374
+ begin
375
+ open(File.join(@builddir, 'common.mk')) do |f|
376
+ if /^extract-extlibs:/ =~ f.read
377
+ do_command(io, "extract-extlibs", "nmake -l extract-extlibs", true)
378
+ end
379
+ end
380
+ rescue Errno::ENOENT
381
+ end
382
+ end
383
+
322
384
  define_buildmethod(:cc_version) do |io, tmpdir|
323
385
  do_command(io, "cc-version", "cl")
324
386
  end
@@ -340,6 +402,7 @@ module MswinBuild
340
402
  else
341
403
  @title << "failed(btest)"
342
404
  end
405
+ @data[:result] = "failure"
343
406
  end
344
407
  end
345
408
 
@@ -352,11 +415,19 @@ module MswinBuild
352
415
  else
353
416
  @title << "failed(test.rb)"
354
417
  end
418
+ @data[:result] = "failure"
355
419
  end
356
420
  end
357
421
 
358
422
  define_buildmethod(:showflags) do |io, tmpdir|
359
- do_command(io, "showflags", "nmake -l showflags", true)
423
+ begin
424
+ open(File.join(@builddir, 'common.mk')) do |f|
425
+ if /^showflags:/ =~ f.read
426
+ do_command(io, "showflags", "nmake -l showflags", true)
427
+ end
428
+ end
429
+ rescue Errno::ENOENT
430
+ end
360
431
  end
361
432
 
362
433
  define_buildmethod(:main) do |io, tmpdir|
@@ -374,6 +445,7 @@ module MswinBuild
374
445
  else
375
446
  @title.unshift(@target)
376
447
  end
448
+ @data[:version] = @title.first
377
449
  end
378
450
 
379
451
  define_buildmethod(:install_nodoc) do |io, tmpdir|
@@ -396,8 +468,10 @@ module MswinBuild
396
468
  io.rewind
397
469
  if %r'^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors, (\d+) skips' =~ io.read
398
470
  @title << "#{$1}F#{$2}E"
471
+ @data[:result] = "failure" if $1.to_i + $2.to_i > 0
399
472
  else
400
473
  @title << "failed(test-all)"
474
+ @data[:result] = "failure"
401
475
  end
402
476
  end
403
477
  end
@@ -412,6 +486,7 @@ module MswinBuild
412
486
  unless /failed|BFail|NotOK|\d+F\d+E/ =~ @title.join
413
487
  heading(io, "success")
414
488
  @title << "success"
489
+ @data[:result] = "success"
415
490
  end
416
491
 
417
492
  heading(io, "end")
@@ -466,7 +541,7 @@ module MswinBuild
466
541
  def gather_log(files, tmpdir)
467
542
  logdir = File.join(@config["logdir"], "log")
468
543
  FileUtils.mkdir_p(logdir)
469
- logfile = File.join(logdir, @start_time.dup.utc.strftime('%Y%m%dT%H%M%SZ.log.html'))
544
+ logfile = File.join(logdir, @data[:start_time] + '.log.html')
470
545
  warns = 0
471
546
  revision = nil
472
547
  open(File.join(tmpdir, "gathered"), "w") do |out|
@@ -484,12 +559,19 @@ module MswinBuild
484
559
  end
485
560
  ensure
486
561
  io.close
487
- io.unlink rescue nil
562
+ File.unlink(io.path) rescue nil
488
563
  end
489
564
  end
490
565
  end
491
566
  @title.insert(2, "#{warns}W") if warns > 0
492
- @title.unshift("r#{revision}") if revision
567
+ @data[:warn] = "#{warns}W"
568
+ url = @data.delete(:svn_url)
569
+ if revision
570
+ @title.unshift("r#{revision}")
571
+ @data[:ruby_rev] = "r#{revision}"
572
+ @data[:version] = "#{@data[:ruby_rev]} #{@data[:version]}"
573
+ @data[url] = revision
574
+ end
493
575
  open(logfile, "w") do |out|
494
576
  header(out)
495
577
  out.puts " <ul>"
@@ -544,13 +626,14 @@ module MswinBuild
544
626
  end
545
627
 
546
628
  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>'
629
+ @data[:title] = title
630
+ time = @data[:start_time]
631
+ latest = %'<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
632
  if mode == :recent
550
633
  old = old[0..99]
551
- old.unshift(line)
634
+ old.unshift(latest)
552
635
  else
553
- old.push(line)
636
+ old.push(latest)
554
637
  end
555
638
  open(filename, "w") do |f|
556
639
  f.print <<-EOH
@@ -584,6 +667,33 @@ module MswinBuild
584
667
  </html>
585
668
  EOH
586
669
  end
670
+
671
+ if mode == :recent
672
+ old = []
673
+ filename = File.join(@config["logdir"], "recent.ltsv")
674
+ if File.exist?(filename)
675
+ open(filename, "r") do |f|
676
+ f.each_line do |line|
677
+ old << line.chomp
678
+ end
679
+ end
680
+ end
681
+
682
+ latest = @data.map{|k, v|
683
+ k = k.to_s
684
+ k = k.gsub(/:/, '\\x3A')
685
+ v = v.gsub(/\t/, ' ')
686
+ k = %'"#{k}"' if /\W/ =~ k
687
+ "#{k}:#{v}"
688
+ }.join("\t")
689
+ old.unshift(latest)
690
+
691
+ open(filename, "w") do |f|
692
+ old.take(100).each do |line|
693
+ f.puts line
694
+ end
695
+ end
696
+ end
587
697
  end
588
698
  end
589
699
  end
@@ -0,0 +1,139 @@
1
+ # derived from chkbuild/upload.rb, but changed for mswin-build.
2
+ # original copyright is below:
3
+
4
+ # chkbuild/upload.rb - upload method definition
5
+ #
6
+ # Copyright (C) 2006-2011 Tanaka Akira <akr@fsij.org>
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions
10
+ # are met:
11
+ #
12
+ # 1. Redistributions of source code must retain the above copyright
13
+ # notice, this list of conditions and the following disclaimer.
14
+ # 2. Redistributions in binary form must reproduce the above
15
+ # copyright notice, this list of conditions and the following
16
+ # disclaimer in the documentation and/or other materials provided
17
+ # with the distribution.
18
+ # 3. The name of the author may not be used to endorse or promote
19
+ # products derived from this software without specific prior
20
+ # written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+
34
+
35
+ module MswinBuild
36
+ @upload_hooks = []
37
+ def self.add_upload_hook(&block)
38
+ @upload_hooks << block
39
+ end
40
+
41
+ def self.run_upload_hooks
42
+ @upload_hooks.reverse_each do |block|
43
+ begin
44
+ block.call
45
+ rescue Exception
46
+ p $!
47
+ end
48
+ end
49
+ end
50
+
51
+ def self.register_azure_upload(logdir)
52
+ ENV['AZURE_STORAGE_ACCOUNT'] ||= 'rubyci'
53
+ raise 'no AZURE_STORAGE_ACCESS_KEY env' unless ENV['AZURE_STORAGE_ACCESS_KEY']
54
+
55
+ require 'azure'
56
+ require_relative 'azure-patch'
57
+ service = Azure::BlobService.new
58
+ service.with_filter do |req, _next|
59
+ i = 0
60
+ begin
61
+ next _next.call
62
+ rescue
63
+ case $!
64
+ when Errno::ETIMEOUT
65
+ if i < 3
66
+ i += 1
67
+ retry
68
+ end
69
+ end
70
+ raise $!
71
+ end
72
+ end
73
+
74
+ add_upload_hook do
75
+ azure_upload(service, logdir)
76
+ end
77
+ end
78
+
79
+ def self.azure_upload(service, logdir)
80
+ logdir = File.dirname(File.join(logdir, 'dummy'))
81
+ branch = File.basename(logdir)
82
+ container = File.basename(File.dirname(logdir))
83
+ begin
84
+ _res, body = service.get_blob(container, "#{branch}/recent.html")
85
+ server_start_time = body[/^<a href=.*+ name="(\w+)">/, 1]
86
+ rescue Azure::Core::Http::HTTPError => e
87
+ server_start_time = '00000000T000000Z'
88
+ if e.type == 'ContainerNotFound'
89
+ service.create_container(container, :public_access_level => 'container')
90
+ end
91
+ end
92
+ puts "Azure: #{branch} start_time: #{server_start_time}" if $DEBUG
93
+
94
+ IO.foreach("#{logdir}/recent.html") do |line|
95
+ break line[/^<a href=.*+ name="(\w+)">/, 1]
96
+ end
97
+
98
+ Dir.foreach(File.join(logdir, "log")).each do |file|
99
+ next unless file.end_with?('.gz')
100
+ blobname = File.join(branch, "log", file)
101
+ filepath = File.join(logdir, "log", file)
102
+ if (service.get_blob_metadata(container, blobname) rescue false)
103
+ File.unlink filepath
104
+ next
105
+ end
106
+ if azure_upload_file(service, container, blobname, filepath)
107
+ File.unlink filepath
108
+ end
109
+ end
110
+
111
+ %w"summary.html recent.html".each do |file|
112
+ blobname = File.join(branch, file)
113
+ filepath = File.join(logdir, file)
114
+ azure_upload_file(service, container, blobname, filepath)
115
+ end
116
+ end
117
+
118
+ def self.azure_upload_file(service, container, blobname, filepath)
119
+ unless File.exist?(filepath)
120
+ puts "File '#{filepath}' is not found"
121
+ return false
122
+ end
123
+
124
+ options = {}
125
+ case filepath
126
+ when /\.html\.gz\z/
127
+ options[:content_type] = "text/html"
128
+ options[:content_encoding] = "gzip"
129
+ when /\.html\z/
130
+ options[:content_type] = "text/html"
131
+ end
132
+
133
+ open(filepath, 'rb') do |f|
134
+ puts "uploading '#{filepath}' as '#{blobname}'..." if $DEBUG
135
+ service.create_block_blob(container, blobname, f, options)
136
+ end
137
+ true
138
+ end
139
+ end
@@ -1,3 +1,3 @@
1
1
  module MswinBuild
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -37,6 +37,24 @@ class StatusMock
37
37
  end
38
38
 
39
39
  class TestBuilder < Test::Unit::TestCase
40
+ def self.startup
41
+ Kernel.module_eval do
42
+ alias orig_backquote ` #`
43
+ def `(cmd) #`
44
+ "Revision: 54321\n" +
45
+ "URL: http://example.com/svn/ruby\n" +
46
+ "Last Changed Rev: 12345\n"
47
+ end
48
+ end
49
+ end
50
+
51
+ def self.shutdown
52
+ Kernel.module_eval do
53
+ undef ` #`
54
+ alias ` orig_backquote #`
55
+ end
56
+ end
57
+
40
58
  def setup
41
59
  @tmpdir = Dir.mktmpdir('TestBuilder')
42
60
  @yaml = Tempfile.open('TestBuilder', @tmpdir)
@@ -56,11 +74,11 @@ env:
56
74
  FileUtils.rm_r(@tmpdir)
57
75
  end
58
76
 
59
- def run_builder(hash = {}, &blk)
77
+ def run_builder(**opt, &blk)
60
78
  builder = MswinBuild::Builder.new(target: "dummy", settings: @yaml.path)
61
- if !hash.empty?
79
+ if !opt.empty?
62
80
  config = builder.instance_variable_get(:@config)
63
- config["timeout"]["test-all"] = hash[:timeout] if hash[:timeout]
81
+ config["timeout"]["test-all"] = opt[:timeout] if opt[:timeout]
64
82
  builder.instance_variable_set(:@config, config)
65
83
  end
66
84
  begin
@@ -71,31 +89,30 @@ env:
71
89
  end
72
90
 
73
91
  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$/,
92
+ /^bison --version\s*$/,
93
+ /^svn checkout dummy_repository ruby\s*$/,
94
+ /^svn info\s*$/,
95
+ /^win32\/configure\.bat --prefix=[^ ]+ --with-baseruby=ruby\s*$/,
96
+ /^cl\s*$/,
97
+ /^nmake -l miniruby\s*$/,
98
+ /^\.\/miniruby -v\s*$/,
99
+ /^nmake -l "OPTS=-v -q" btest\s*$/,
100
+ /^\.\/miniruby sample\/test\.rb\b/,
101
+ /^nmake -l main\s*$/,
102
+ /^nmake -l docs\s*$/,
103
+ /^\.\/ruby -v\s*$/,
104
+ /^nmake -l install-nodoc\s*$/,
105
+ /^nmake -l install-doc\s*$/,
106
+ /^nmake -l "OPTS=-v -q" test-knownbug\s*$/,
107
+ /^nmake -l TESTS=-v RUBYOPT=-w test-all\s*$/,
91
108
  ]
92
109
 
93
110
  ProcessMock.set_callback(commands, &blk)
94
111
 
95
- builder.run
112
+ assert builder.run, "returned error status"
96
113
 
97
114
  assert_empty commands
98
- assert_equal hash[:revision].to_s, builder.get_last_revision if hash[:revision]
115
+ assert_equal opt[:revision].to_s, builder.get_last_revision if opt[:revision]
99
116
  ensure
100
117
  Object.class_eval do
101
118
  remove_const :Process
@@ -104,6 +121,7 @@ env:
104
121
  end
105
122
 
106
123
  assert File.exist?(File.join(@tmpdir, "recent.html"))
124
+ assert File.exist?(File.join(@tmpdir, "recent.ltsv"))
107
125
  assert File.exist?(File.join(@tmpdir, "summary.html"))
108
126
  assert File.directory?(File.join(@tmpdir, "log"))
109
127
  files = Dir.glob(File.join(@tmpdir, "log", "*"))
@@ -138,8 +156,36 @@ env:
138
156
  Dir.mkdir("ruby")
139
157
  when /^svn info\b/
140
158
  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"
159
+ args[1][:out].puts `svn info`
160
+ end
161
+ end
162
+
163
+ StatusMock.new(0)
164
+ end
165
+
166
+ recent = File.read(File.join(@tmpdir, "recent.html"))
167
+ assert_match(/\bsuccess\b/, recent)
168
+ assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent)
169
+ assert_not_match(/\bfailed\b/, recent)
170
+
171
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
172
+ assert_match(/\bresult:success\b/, recent)
173
+ assert_match(/\bruby_rev:r12345\b/, recent)
174
+ assert_match(/"http\\x3A\/\/[^:]+":12345\b/, recent)
175
+ assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
176
+
177
+ sleep 2
178
+
179
+ run_builder(revision: 12345) do |args, commands|
180
+ assert_not_empty commands, "for ``#{args[0]}''"
181
+ assert_match commands.shift, args[0]
182
+
183
+ case args[0]
184
+ when /^svn checkout\b/
185
+ Dir.mkdir("ruby")
186
+ when /^svn info\b/
187
+ if args[1].is_a?(Hash) && args[1][:out]
188
+ args[1][:out].puts `svn info`
143
189
  end
144
190
  end
145
191
 
@@ -147,8 +193,15 @@ env:
147
193
  end
148
194
 
149
195
  recent = File.read(File.join(@tmpdir, "recent.html"))
150
- assert_match /\bsuccess\b/, recent
151
- assert_match /^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent
196
+ assert_match(/\bsuccess\b/, recent)
197
+ assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent)
198
+ assert_not_match(/\bfailed\b/, recent)
199
+
200
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
201
+ assert_match(/\bresult:success\b/, recent)
202
+ assert_match(/\bruby_rev:r12345\b/, recent)
203
+ assert_match(/"http\\x3A\/\/[^:]+":12345\b/, recent)
204
+ assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
152
205
  end
153
206
 
154
207
  def test_run_btest_failure
@@ -170,8 +223,13 @@ env:
170
223
  end
171
224
 
172
225
  recent = File.read(File.join(@tmpdir, "recent.html"))
173
- assert_match /\b3BFail\b/, recent
174
- assert_not_match /\bfailed\b/, recent
226
+ assert_match(/\b3BFail\b/, recent)
227
+ assert_not_match(/\bfailed\b/, recent)
228
+
229
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
230
+ assert_match(/\bresult:failure\b/, recent)
231
+ assert_match(/\btitle:[^\t]*\b3BFail\b/, recent)
232
+ assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
175
233
  end
176
234
 
177
235
  def test_run_testrb_failure
@@ -193,8 +251,13 @@ env:
193
251
  end
194
252
 
195
253
  recent = File.read(File.join(@tmpdir, "recent.html"))
196
- assert_match /\b4NotOK\b/, recent
197
- assert_not_match /\bfailed\b/, recent
254
+ assert_match(/\b4NotOK\b/, recent)
255
+ assert_not_match(/\bfailed\b/, recent)
256
+
257
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
258
+ assert_match(/\bresult:failure\b/, recent)
259
+ assert_match(/\btitle:[^\t]*\b4NotOK\b/, recent)
260
+ assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
198
261
  end
199
262
 
200
263
  def test_run_test_all_failure
@@ -216,8 +279,13 @@ env:
216
279
  end
217
280
 
218
281
  recent = File.read(File.join(@tmpdir, "recent.html"))
219
- assert_match /\b2F1E\b/, recent
220
- assert_not_match /\bfailed\b/, recent
282
+ assert_match(/\b2F1E\b/, recent)
283
+ assert_not_match(/\bfailed\b/, recent)
284
+
285
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
286
+ assert_match(/\bresult:failure\b/, recent)
287
+ assert_match(/\btitle:[^\t]*\b2F1E\b/, recent)
288
+ assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
221
289
  end
222
290
 
223
291
  def test_run_timeout
@@ -237,24 +305,15 @@ env:
237
305
  end
238
306
 
239
307
  recent = File.read(File.join(@tmpdir, "recent.html"))
240
- assert_match /\bfailed\(test-all CommandTimeout\)/, recent
308
+ assert_match(/\bfailed\(test-all CommandTimeout\)/, recent)
309
+
310
+ recent = File.read(File.join(@tmpdir, "recent.ltsv"))
311
+ assert_match(/\bresult:failure\b/, recent)
312
+ assert_match(/\btitle:[^\t]*\bfailed\(test-all CommandTimeout\)/, recent)
241
313
  end
242
314
 
243
315
  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
316
+ builder = MswinBuild::Builder.new(target: "dummy", settings: @yaml.path)
317
+ assert_equal "12345", builder.get_current_revision
259
318
  end
260
319
  end
@@ -0,0 +1,142 @@
1
+ require "fileutils"
2
+ require "test/unit"
3
+ require "tmpdir"
4
+ require "mswin-build/upload"
5
+
6
+ alias mock_orig_require require
7
+ def require(feature)
8
+ mock_orig_require(feature) unless feature == "azure"
9
+ end
10
+
11
+ # Azure mock
12
+ module Azure
13
+ class BlobService
14
+ def initialize
15
+ @blobs = {}
16
+ end
17
+
18
+ def with_filter(&blk)
19
+ blk.call(nil, lambda{})
20
+ end
21
+
22
+ def get_blob(container, blobname)
23
+ raise Azure::Core::Http::HTTPError unless @blobs.has_key?(blobname)
24
+ return @blobs[blobname][:data]
25
+ end
26
+
27
+ def get_blob_metadata(container, blobname)
28
+ raise Azure::Core::Http::HTTPError unless @blobs.has_key?(blobname)
29
+ return @blobs[blobname]
30
+ end
31
+
32
+ def create_block_blob(container, blobname, io, options)
33
+ @blobs[blobname] = options.merge(data: io.read)
34
+ end
35
+ end
36
+
37
+ module Core
38
+ module Http
39
+ class HTTPError < RuntimeError
40
+ def type
41
+ ""
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ class TestUpload < Test::Unit::TestCase
49
+ def setup
50
+ @tmpdir = Dir.mktmpdir
51
+ Dir.mkdir(File.join(@tmpdir, "log"))
52
+ end
53
+
54
+ def teardown
55
+ ENV.delete "AZURE_STORAGE_ACCESS_KEY"
56
+ MswinBuild.instance_variable_set(:@upload_hooks, [])
57
+
58
+ FileUtils.rm_r @tmpdir if File.directory?(@tmpdir)
59
+ end
60
+
61
+ def test_add_upload_hook
62
+ assert_equal 0, MswinBuild.instance_variable_get(:@upload_hooks).size
63
+ MswinBuild.add_upload_hook do
64
+ end
65
+ assert_equal 1, MswinBuild.instance_variable_get(:@upload_hooks).size
66
+ end
67
+
68
+ def test_run_upload_hooks
69
+ foo = false
70
+ MswinBuild.add_upload_hook do
71
+ foo = true
72
+ end
73
+ refute foo
74
+ MswinBuild.run_upload_hooks
75
+ assert foo
76
+ end
77
+
78
+ def test_register_azure_upload
79
+ assert_raise(RuntimeError) do
80
+ MswinBuild.register_azure_upload(@tmpdir)
81
+ end
82
+
83
+ assert_equal 0, MswinBuild.instance_variable_get(:@upload_hooks).size
84
+
85
+ ENV["AZURE_STORAGE_ACCESS_KEY"] = "dummy"
86
+ assert_nothing_raised do
87
+ MswinBuild.register_azure_upload(@tmpdir)
88
+ end
89
+ assert_equal 1, MswinBuild.instance_variable_get(:@upload_hooks).size
90
+ end
91
+
92
+ def test_azure_upload
93
+ open(File.join(@tmpdir, "log", "test1.html.gz"), "w") do |f|
94
+ f.print "test1"
95
+ end
96
+ open(File.join(@tmpdir, "recent.html"), "w") do |f|
97
+ f.print "recent"
98
+ end
99
+ open(File.join(@tmpdir, "summary.html"), "w") do |f|
100
+ f.print "summary"
101
+ end
102
+ service = Azure::BlobService.new
103
+ assert_nothing_raised do
104
+ MswinBuild.azure_upload(service, @tmpdir)
105
+ end
106
+ branch = File.basename(@tmpdir)
107
+ refute File.exist?(File.join(@tmpdir, "log", "test1.html.gz"))
108
+ assert_equal "test1", service.get_blob(nil, File.join(branch, "log", "test1.html.gz"))
109
+ assert File.exist?(File.join(@tmpdir, "recent.html"))
110
+ assert_equal "recent", service.get_blob(nil, File.join(branch, "recent.html"))
111
+ assert File.exist?(File.join(@tmpdir, "summary.html"))
112
+ assert_equal "summary", service.get_blob(nil, File.join(branch, "summary.html"))
113
+ end
114
+
115
+ def test_azure_upload_file
116
+ service = Azure::BlobService.new
117
+
118
+ file = "test1.html.gz"
119
+ path = File.join(@tmpdir, file)
120
+ open(path, "wb") do |f|
121
+ f.puts "test1"
122
+ end
123
+ assert_nothing_raised do
124
+ assert MswinBuild.azure_upload_file(service, "foo", file, path)
125
+ end
126
+ assert_equal "test1\n", service.get_blob(service, file)
127
+ assert_equal "text/html", service.get_blob_metadata(service, file)[:content_type]
128
+ assert_equal "gzip", service.get_blob_metadata(service, file)[:content_encoding]
129
+
130
+ file = "test2.html"
131
+ path = File.join(@tmpdir, file)
132
+ open(path, "wb") do |f|
133
+ f.puts "test2"
134
+ end
135
+ assert_nothing_raised do
136
+ assert MswinBuild.azure_upload_file(service, "foo", file, path)
137
+ end
138
+ assert_equal "test2\n", service.get_blob(service, file)
139
+ assert_equal "text/html", service.get_blob_metadata(service, file)[:content_type]
140
+ assert_nil service.get_blob_metadata(service, file)[:content_encoding]
141
+ end
142
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mswin-build
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - U.Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-17 00:00:00.000000000 Z
11
+ date: 2017-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,12 +73,15 @@ files:
73
73
  - config/vc10-x86-1_9_3.yaml
74
74
  - config/vc10-x86-2_0_0.yaml
75
75
  - config/vc10-x86-trunk.yaml
76
+ - lib/mswin-build/azure-patch.rb
76
77
  - lib/mswin-build/builder.rb
77
78
  - lib/mswin-build/process_tree.rb
79
+ - lib/mswin-build/upload.rb
78
80
  - lib/mswin-build/version.rb
79
81
  - mswin-build.gemspec
80
82
  - test/unit/test_builder.rb
81
83
  - test/unit/test_process_tree.rb
84
+ - test/unit/test_upload.rb
82
85
  homepage: https://github.com/unak/mswin-build
83
86
  licenses:
84
87
  - BSD-2-Clause
@@ -99,10 +102,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
102
  version: '0'
100
103
  requirements: []
101
104
  rubyforge_project:
102
- rubygems_version: 2.2.2
105
+ rubygems_version: 2.6.11
103
106
  signing_key:
104
107
  specification_version: 4
105
108
  summary: A low quality clone of https://github.com/akr/chkbuild for mswin.
106
109
  test_files:
107
110
  - test/unit/test_builder.rb
108
111
  - test/unit/test_process_tree.rb
112
+ - test/unit/test_upload.rb