mswin-build 1.0.0 → 1.1.0

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