mswin-build 1.1.2 → 1.2.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: 04dd66454d1375114da0bdc7c13e8caade4177d5
4
- data.tar.gz: d042c5b0f15c2e0434d5542c7387eedb87b313ba
3
+ metadata.gz: 3e3caa55131f9d640fb35fadfc93c7b53562d1b6
4
+ data.tar.gz: fc4f25f04c6fc563025922ae88155294221d229e
5
5
  SHA512:
6
- metadata.gz: 3afae83b34dba29b69425e3452f2eda1da721ab91ebae7d635a76013436bac846bfb7846378c3980a930e47f1a0cb0b7cf89cc3c249a75c34ff59f43d8cf03ec
7
- data.tar.gz: 1333f4d3a83d48fe9c7a6c497852193455e867600c24b31eb694c0def0a6c65784b060a89dd9e3084b794b8280511a125955cc8f648d6e609cd83d632ff5fa08
6
+ metadata.gz: 19093b7cd32b3583125ffbd81c7feceaac6d1e7b5a79105a7e6089615da62e045d2c40102544db76c09471059599c4e6f1ebf16cc59141116630b1b4822ad2f4
7
+ data.tar.gz: 301321b2a7e5fa1cb32749610ac4d9805db209a0ebc47164d0e7013e17fb832a39b241807f2b7ede812dc4037ad7ebb977cc40af7c40ec5432ab7cae648c9862
@@ -32,6 +32,7 @@ rescue RuntimeError => ex
32
32
  puts opt.help
33
33
  exit 1
34
34
  end
35
+ STDOUT.sync = true if $debug
35
36
 
36
37
  loop do
37
38
  ARGV.each do |target|
@@ -83,6 +83,7 @@ module MswinBuild
83
83
  ENV[name] = value
84
84
  end
85
85
  files = []
86
+ @fails = []
86
87
  Dir.mktmpdir("mswin-build", @config["tmpdir"]) do |tmpdir|
87
88
  files << baseinfo(tmpdir)
88
89
  files << checkout(tmpdir)
@@ -109,14 +110,23 @@ module MswinBuild
109
110
  files << rubyspec(tmpdir)
110
111
  end
111
112
  files << end_(tmpdir)
112
- logfile = gather_log(files, tmpdir)
113
+ logfile, failfile = gather_log(files, tmpdir)
114
+ files.each do |io|
115
+ if io
116
+ io.close
117
+ File.unlink(io.path)
118
+ end
119
+ end
113
120
  difffile = diff(tmpdir, logfile)
114
121
  logfile = gzip(logfile)
115
122
  @data[:compressed_loghtml_relpath] = File.join("log", File.basename(logfile))
116
123
  difffile = gzip(difffile)
117
124
  @data[:compressed_diffhtml_relpath] = File.join("log", File.basename(difffile))
118
- add_recent(logfile)
119
- add_summary(logfile)
125
+ failfile = gzip(failfile)
126
+ @data[:compressed_failhtml_relpath] = File.join("log", File.basename(failfile))
127
+
128
+ add_recent(logfile, difffile, failfile)
129
+ add_summary(logfile, difffile, failfile)
120
130
 
121
131
  MswinBuild.run_upload_hooks
122
132
  end
@@ -254,6 +264,7 @@ module MswinBuild
254
264
  end
255
265
 
256
266
  if status.nil? || !status.success?
267
+ @fails << io
257
268
  io.puts "exit #{status.to_i}" unless status.nil?
258
269
  io.puts "failed(#{name})"
259
270
  @title << "failed(#{name})" if check_retval || status.nil?
@@ -266,6 +277,7 @@ module MswinBuild
266
277
  end
267
278
  end
268
279
  rescue Timeout::Error
280
+ @fails << io
269
281
  io.puts
270
282
  io.printf "|output interval exceeds %.1f seconds. (CommandTimeout)", @config["timeout"][name] || @config["timeout"]["default"]
271
283
  io.puts $!.backtrace.join("\n| ")
@@ -292,7 +304,7 @@ module MswinBuild
292
304
  end
293
305
  anchor = u name.to_s.tr('_', '-')
294
306
  text = h name.to_s.tr('_', '-')
295
- io.puts %'<a name="#{anchor}">== #{text}</a> \# #{h Time.now.iso8601}'
307
+ io.puts %'<a name="#{anchor}">== #{text} \# #{h Time.now.iso8601}</a>'
296
308
  @links[name] = [anchor, text]
297
309
  end
298
310
 
@@ -309,6 +321,10 @@ module MswinBuild
309
321
  end
310
322
  end
311
323
 
324
+ def define_failure_start_pattern(io, *patterns)
325
+ io.instance_variable_set(:@failure_start_patterns, patterns)
326
+ end
327
+
312
328
  define_buildmethod(:baseinfo) do |io, tmpdir|
313
329
  @start_time = Time.now
314
330
  @data[:start_time] = @start_time.dup.utc.strftime('%Y%m%dT%H%M%SZ')
@@ -397,8 +413,10 @@ module MswinBuild
397
413
  end
398
414
 
399
415
  define_buildmethod(:btest) do |io, tmpdir|
416
+ define_failure_start_pattern(io, /: $/, /:\d+:in `/)
400
417
  ret = do_command(io, "btest", 'nmake -l "OPTS=-v -q" btest', true, false)
401
418
  if !ret && !ret.nil?
419
+ @fails << io unless @fails.include?(io)
402
420
  io.rewind
403
421
  if %r'^FAIL (\d+)/\d+' =~ io.read
404
422
  @title << "#{$1}BFail"
@@ -414,6 +432,7 @@ module MswinBuild
414
432
  define_buildmethod(:testrb) do |io, tmpdir|
415
433
  ret = do_command(io, "test.rb", "./miniruby sample/test.rb", true, false)
416
434
  if !ret && !ret.nil?
435
+ @fails << io unless @fails.include?(io)
417
436
  io.rewind
418
437
  if %r'^not ok/test: \d+ failed (\d+)' =~ io.read
419
438
  @title << "#{$1}NotOK"
@@ -470,16 +489,19 @@ module MswinBuild
470
489
  end
471
490
 
472
491
  define_buildmethod(:test_all) do |io, tmpdir|
492
+ define_failure_start_pattern(io, /\A *\d+\) (Failure|Error)/, /\A\d+ tests, \d+ assertions, [1-9]\d* failures, \d+ errors/, /\A\d+ tests, \d+ assertions, \d+ failures, [1-9]\d* errors/, /:\d+:in `/)
473
493
  ret = do_command(io, "test-all", "nmake -l TESTS=-v RUBYOPT=-w test-all", true, false, nil)
474
494
  if !ret && !ret.nil?
475
495
  io.rewind
476
496
  if %r'^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors, (\d+) skips' =~ io.read
477
497
  @title << "#{$1}F#{$2}E"
478
498
  if $1.to_i + $2.to_i > 0
499
+ @fails << io unless @fails.include?(io)
479
500
  @data["failure_test-all"] = "#{$1}F#{$2}E"
480
501
  @data[:result] = "failure"
481
502
  end
482
503
  else
504
+ @fails << io unless @fails.include?(io)
483
505
  @title << "failed(test-all)"
484
506
  @data["failure_test-all"] = "failed"
485
507
  @data[:result] = "failure"
@@ -488,6 +510,7 @@ module MswinBuild
488
510
  end
489
511
 
490
512
  define_buildmethod(:rubyspec) do |io, tmpdir|
513
+ define_failure_start_pattern(io, /\A1\)\n\z/, /:\d+:in `/)
491
514
  if ruby_version >= "2.5.0"
492
515
  ret = do_command(io, "rubyspec", 'nmake -l MSPECOPT="-V -f s" test-rubyspec', true, false, nil)
493
516
  if !ret && !ret.nil?
@@ -495,10 +518,12 @@ module MswinBuild
495
518
  if /^\d+ files?, \d+ examples?, \d+ expectations?, (\d+) failures?, (\d+) errors?, \d+ tagged/ =~ io.read
496
519
  @title << "rubyspec:#{$1}F#{$2}E"
497
520
  if $1.to_i + $2.to_i > 0
521
+ @fails << io unless @fails.include?(io)
498
522
  @data["failure_rubyspec"] = "#{$1}F#{$2}E"
499
523
  @data[:result] = "failure"
500
524
  end
501
525
  else
526
+ @fails << io unless @fails.include?(io)
502
527
  @title << "failed(rubyspec)"
503
528
  @data["failure_rubyspec"] = "failed"
504
529
  @data[:result] = "failure"
@@ -569,30 +594,51 @@ module MswinBuild
569
594
  end
570
595
 
571
596
  def gather_log(files, tmpdir)
572
- logdir = File.join(@config["logdir"], "log")
573
- FileUtils.mkdir_p(logdir)
574
- logfile = File.join(logdir, @data[:start_time] + '.log.html')
575
597
  warns = 0
576
598
  revision = nil
577
- open(File.join(tmpdir, "gathered"), "w") do |out|
578
- files.each_with_index do |io, i|
599
+ open(File.join(tmpdir, "gathered"), "wb") do |out|
600
+ files.each do |io|
579
601
  next unless io
580
602
  io.reopen(io.path, "r", encoding: "ascii-8bit")
581
- begin
582
- io.each_line do |line|
583
- line = h(line) unless /^<a / =~ line
584
- out.write line
585
- warns += line.scan(/warn/i).length
586
- if File.basename(io.path) == "checkout" && /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ line
587
- revision = $1
588
- end
603
+ io.each_line do |line|
604
+ line = h(line) unless /^<a / =~ line
605
+ out.write line
606
+ warns += line.scan(/warn/i).length
607
+ if File.basename(io.path) == "checkout" && /^(?:SVN )?Last Changed Rev: (\d+)$/ =~ line
608
+ revision = $1
589
609
  end
590
- ensure
591
- io.close
592
- File.unlink(io.path) rescue nil
593
610
  end
594
611
  end
595
612
  end
613
+
614
+ open(File.join(tmpdir, "failed"), "wb") do |out|
615
+ if @fails.empty?
616
+ out.puts "No failures"
617
+ break
618
+ end
619
+
620
+ @fails.each do |io|
621
+ io.rewind
622
+ lines = io.read.lines
623
+ out.puts lines.shift
624
+ total = lines.size
625
+ patterns = io.instance_variable_defined?(:@failure_start_patterns) ? io.instance_variable_get(:@failure_start_patterns) : []
626
+ patterns << /\[BUG\]/
627
+ start = [0, total - 10].max
628
+ lines.each_with_index do |line, i|
629
+ if patterns.find{|pat| pat =~ line}
630
+ start = i
631
+ break
632
+ end
633
+ end
634
+ start = [0, start - 10].max # show 10 lines before the start point
635
+ out.puts "...(snip #{start} lines)..." if start > 0
636
+ lines.last(total - start).each do |line|
637
+ out.write h(line)
638
+ end
639
+ end
640
+ end
641
+
596
642
  title = @title[0, 2]
597
643
  @data[:warn] = "#{warns}W"
598
644
  if warns > 0
@@ -623,25 +669,46 @@ module MswinBuild
623
669
  title << v
624
670
  end
625
671
  end
672
+
626
673
  @data[:title] = title.join(' ')
627
- open(logfile, "w") do |out|
674
+
675
+ logdir = File.join(@config["logdir"], "log")
676
+ FileUtils.mkdir_p(logdir)
677
+ logfile = File.join(logdir, @data[:start_time] + '.log.html')
678
+ failfile = File.join(logdir, @data[:start_time] + '.fail.html')
679
+ open(logfile, "wb") do |out|
628
680
  header(out)
681
+ out.puts " <p><a href=\"#{File.basename(logfile) + '.gz'}\">#{@data[:start_time]}</a>(<a href=\"#{File.basename(failfile) + '.gz'}\">failure</a>)</p>"
629
682
  out.puts " <ul>"
630
683
  @links.each_value do |anchor, text, result = nil|
631
684
  out.puts %' <li><a href="\##{anchor}">#{text}</a>#{" #{result}" if result}</li>'
632
685
  end
633
686
  out.puts " </ul>"
634
687
  out.puts " <pre>"
635
- out.write IO.read(File.join(tmpdir, "gathered"))
688
+ out.write insert_href(IO.read(File.join(tmpdir, "gathered"), encoding: 'ascii-8bit'), File.basename(logfile) + ".gz")
636
689
  out.puts " </pre>"
637
690
  footer(out)
638
691
  end
639
- logfile
692
+
693
+ open(failfile, "wb") do |out|
694
+ header(out)
695
+ out.puts " <ul>"
696
+ @links.each_value do |anchor, text, result = nil|
697
+ out.puts %' <li><a href="\##{anchor}">#{text}</a> #{result}</li>' if result
698
+ end
699
+ out.puts " </ul>"
700
+ out.puts " <pre>"
701
+ out.write insert_href(IO.read(File.join(tmpdir, "failed"), encoding: 'ascii-8bit'), File.basename(failfile) + ".gz", File.basename(logfile) + ".gz")
702
+ out.puts " </pre>"
703
+ footer(out)
704
+ end
705
+
706
+ return logfile, failfile
640
707
  end
641
708
 
642
709
  def diff(tmpdir, logfile)
643
710
  filename = logfile.sub(/\.log/, ".diff")
644
- open(filename, "w") do |out|
711
+ open(filename, "wb") do |out|
645
712
  header(out)
646
713
  out.puts %'<p>Skipped. See the <a href="#{u File.basename(logfile)}.gz">full build log</a>.</p>'
647
714
  footer(out)
@@ -654,15 +721,19 @@ module MswinBuild
654
721
  file + ".gz"
655
722
  end
656
723
 
657
- def add_recent(logfile)
658
- add_recent_summary(logfile, :recent)
724
+ def insert_href(html, file, orig = nil)
725
+ html.gsub(/^<a name="(.+?)">(== .*)$/, "<a name=\"\\1\" href=\"#{file}\#\\1\">\\2#{%' (<a href=\"#{orig}\#\\1\">full</a>)' if orig}")
726
+ end
727
+
728
+ def add_recent(logfile, difffile, failfile)
729
+ add_recent_summary(logfile, difffile, failfile, :recent)
659
730
  end
660
731
 
661
- def add_summary(logfile)
662
- add_recent_summary(logfile, :summary)
732
+ def add_summary(logfile, difffile, failfile)
733
+ add_recent_summary(logfile, difffile, failfile, :summary)
663
734
  end
664
735
 
665
- def add_recent_summary(logfile, mode)
736
+ def add_recent_summary(logfile, difffile, failfile, mode)
666
737
  if mode == :recent
667
738
  filename = File.join(@config["logdir"], "recent.html")
668
739
  else
@@ -679,14 +750,14 @@ module MswinBuild
679
750
 
680
751
  title = @title.join(' ')
681
752
  time = @data[:start_time]
682
- 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>'
753
+ latest = %'<a href="log/#{File.basename(logfile)}" name="#{u time}">#{h time}</a>(<a href="log/#{File.basename(failfile)}">failure</a>) #{h title} (<a href="log/#{File.basename(difffile)}">#{@diff ? h(@diff) : "no diff"}</a>)<br>'
683
754
  if mode == :recent
684
755
  old = old[0..99]
685
756
  old.unshift(latest)
686
757
  else
687
758
  old.push(latest)
688
759
  end
689
- open(filename, "w") do |f|
760
+ open(filename, "wb") do |f|
690
761
  f.print <<-EOH
691
762
  <html>
692
763
  <head>
@@ -739,7 +810,7 @@ module MswinBuild
739
810
  }.join("\t")
740
811
  old.unshift(latest)
741
812
 
742
- open(filename, "w") do |f|
813
+ open(filename, "wb") do |f|
743
814
  old.take(100).each do |line|
744
815
  f.puts line
745
816
  end
@@ -1,3 +1,3 @@
1
1
  module MswinBuild
2
- VERSION = "1.1.2"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -2,6 +2,7 @@ require "fileutils"
2
2
  require "tmpdir"
3
3
  require "tempfile"
4
4
  require "test/unit"
5
+ require "zlib"
5
6
  require "mswin-build/builder.rb"
6
7
 
7
8
  module ProcessMock
@@ -71,7 +72,7 @@ env:
71
72
 
72
73
  def teardown
73
74
  @yaml.close!
74
- FileUtils.rm_r(@tmpdir)
75
+ FileUtils.rm_rf(@tmpdir)
75
76
  end
76
77
 
77
78
  def run_builder(**opt, &blk)
@@ -128,6 +129,7 @@ env:
128
129
  files = Dir.glob(File.join(@tmpdir, "log", "*"))
129
130
  assert files.reject! {|e| /\.log\.html\.gz\z/ =~ e}
130
131
  assert files.reject! {|e| /\.diff\.html\.gz\z/ =~ e}
132
+ assert files.reject! {|e| /\.fail\.html\.gz\z/ =~ e}
131
133
  assert_empty files
132
134
  end
133
135
 
@@ -166,7 +168,7 @@ env:
166
168
 
167
169
  recent = File.read(File.join(@tmpdir, "recent.html"))
168
170
  assert_match(/\bsuccess\b/, recent)
169
- assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent)
171
+ assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a>\(<a href="[^"]+">failure<\/a>\) r12345 /, recent) #"
170
172
  assert_not_match(/\bfailed\b/, recent)
171
173
  assert_not_match(/\bskipped\b/, recent)
172
174
 
@@ -196,7 +198,7 @@ env:
196
198
 
197
199
  recent = File.read(File.join(@tmpdir, "recent.html"))
198
200
  assert_match(/\bsuccess\b/, recent)
199
- assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a> r12345 /, recent)
201
+ assert_match(/^<a href="[^"]+" name="[^"]+">[^<]+<\/a>\(<a href="[^"]+">failure<\/a>\) r12345 /, recent) #"
200
202
  assert_not_match(/\bfailed\b/, recent)
201
203
 
202
204
  recent = File.read(File.join(@tmpdir, "recent.ltsv"))
@@ -204,6 +206,26 @@ env:
204
206
  assert_match(/\bruby_rev:r12345\b/, recent)
205
207
  assert_match(/"http\\x3A\/\/[^:]+":12345\b/, recent)
206
208
  assert_not_match(/\btitle:[^\t]*\b(failed|success|\dE\dF)\b/, recent)
209
+
210
+ logs = Dir.glob(File.join(@tmpdir, "log", "*.log.html.gz"))
211
+ assert logs.count > 0, "some logs must be written"
212
+ logs.each do |log|
213
+ fn = Regexp.escape(File.basename(log))
214
+ fn2 = fn.sub(/log/, "fail")
215
+ Zlib::GzipReader.open(log) do |gz|
216
+ html = gz.read
217
+ assert_match(/<p><a href="#{fn}">[^<]+<\/a>\(<a href="#{fn2}">failure<\/a>\)<\/p>/, html)
218
+ assert_match(/^<a name="(.+?)" href="#{fn}\#\1">== /, html)
219
+ end
220
+ end
221
+
222
+ fails = Dir.glob(File.join(@tmpdir, "log", "*.fail.html.gz"))
223
+ assert fails.count > 0, "some fail htmls must be written"
224
+ fails.each do |log|
225
+ Zlib::GzipReader.open(log) do |gz|
226
+ assert_match(/^No failures$/, gz.read)
227
+ end
228
+ end
207
229
  end
208
230
 
209
231
  def test_run_btest_failure
@@ -233,6 +255,16 @@ env:
233
255
  assert_match(/\bfailure_btest:3BFail\b/, recent)
234
256
  assert_match(/\btitle:[^\t]*\b3BFail\b/, recent)
235
257
  assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
258
+
259
+ fails = Dir.glob(File.join(@tmpdir, "log", "*.fail.html.gz"))
260
+ assert fails.count > 0, "some fail htmls must be written"
261
+ fails.each do |log|
262
+ fn = Regexp.escape(File.basename(log))
263
+ fn2 = fn.sub(/fail/, "log")
264
+ Zlib::GzipReader.open(log) do |gz|
265
+ assert_match(/^<a name="(btest)" href="#{fn}\#\1">== .*\(<a href="#{fn2}\#\1">full<\/a>\)$/, gz.read)
266
+ end
267
+ end
236
268
  end
237
269
 
238
270
  def test_run_testrb_failure
@@ -262,6 +294,16 @@ env:
262
294
  assert_match(/\bfailure_test.rb:4NotOK\b/, recent)
263
295
  assert_match(/\btitle:[^\t]*\b4NotOK\b/, recent)
264
296
  assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
297
+
298
+ fails = Dir.glob(File.join(@tmpdir, "log", "*.fail.html.gz"))
299
+ assert fails.count > 0, "some fail htmls must be written"
300
+ fails.each do |log|
301
+ fn = Regexp.escape(File.basename(log))
302
+ fn2 = fn.sub(/fail/, "log")
303
+ Zlib::GzipReader.open(log) do |gz|
304
+ assert_match(/^<a name="(test\.rb)" href="#{fn}\#\1">== .*\(<a href="#{fn2}\#\1">full<\/a>\)$/, gz.read)
305
+ end
306
+ end
265
307
  end
266
308
 
267
309
  def test_run_test_all_failure
@@ -291,6 +333,16 @@ env:
291
333
  assert_match(/\bfailure_test-all:2F1E\b/, recent)
292
334
  assert_match(/\btitle:[^\t]*\b2F1E\b/, recent)
293
335
  assert_not_match(/\btitle:[^\t]*\bfailed\b/, recent)
336
+
337
+ fails = Dir.glob(File.join(@tmpdir, "log", "*.fail.html.gz"))
338
+ assert fails.count > 0, "some fail htmls must be written"
339
+ fails.each do |log|
340
+ fn = Regexp.escape(File.basename(log))
341
+ fn2 = fn.sub(/fail/, "log")
342
+ Zlib::GzipReader.open(log) do |gz|
343
+ assert_match(/^<a name="(test-all)" href="#{fn}\#\1">== .*\(<a href="#{fn2}\#\1">full<\/a>\)$/, gz.read)
344
+ end
345
+ end
294
346
  end
295
347
 
296
348
  def test_run_timeout
@@ -316,6 +368,16 @@ env:
316
368
  assert_match(/\bresult:failure\b/, recent)
317
369
  assert_match(/\bfailure_test-all:failed\(test-all CommandTimeout\)/, recent)
318
370
  assert_match(/\btitle:[^\t]*\bfailed\(test-all CommandTimeout\)/, recent)
371
+
372
+ fails = Dir.glob(File.join(@tmpdir, "log", "*.fail.html.gz"))
373
+ assert fails.count > 0, "some fail htmls must be written"
374
+ fails.each do |log|
375
+ fn = Regexp.escape(File.basename(log))
376
+ fn2 = fn.sub(/fail/, "log")
377
+ Zlib::GzipReader.open(log) do |gz|
378
+ assert_match(/^<a name="(.+?)" href="#{fn}\#\1">== .*\(<a href="#{fn2}\#\1">full<\/a>\)$/, gz.read)
379
+ end
380
+ end
319
381
  end
320
382
 
321
383
  def test_get_current_revision
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.1.2
4
+ version: 1.2.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: 2017-05-20 00:00:00.000000000 Z
11
+ date: 2017-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler