yugui-chkbuild 0.1.2

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.
Files changed (66) hide show
  1. data/README.ja.rd +191 -0
  2. data/Rakefile +56 -0
  3. data/VERSION +1 -0
  4. data/bin/last-build +28 -0
  5. data/bin/start-build +37 -0
  6. data/chkbuild.gemspec +107 -0
  7. data/core_ext/io.rb +17 -0
  8. data/core_ext/string.rb +10 -0
  9. data/lib/chkbuild.rb +45 -0
  10. data/lib/chkbuild/build.rb +718 -0
  11. data/lib/chkbuild/lock.rb +57 -0
  12. data/lib/chkbuild/logfile.rb +230 -0
  13. data/lib/chkbuild/main.rb +138 -0
  14. data/lib/chkbuild/options.rb +62 -0
  15. data/lib/chkbuild/scm/cvs.rb +132 -0
  16. data/lib/chkbuild/scm/git.rb +223 -0
  17. data/lib/chkbuild/scm/svn.rb +215 -0
  18. data/lib/chkbuild/scm/xforge.rb +33 -0
  19. data/lib/chkbuild/target.rb +180 -0
  20. data/lib/chkbuild/targets/gcc.rb +94 -0
  21. data/lib/chkbuild/targets/ruby.rb +456 -0
  22. data/lib/chkbuild/title.rb +107 -0
  23. data/lib/chkbuild/upload.rb +66 -0
  24. data/lib/misc/escape.rb +535 -0
  25. data/lib/misc/gdb.rb +74 -0
  26. data/lib/misc/timeoutcom.rb +174 -0
  27. data/lib/misc/udiff.rb +244 -0
  28. data/lib/misc/util.rb +232 -0
  29. data/sample/build-autoconf-ruby +69 -0
  30. data/sample/build-gcc-ruby +43 -0
  31. data/sample/build-ruby +37 -0
  32. data/sample/build-ruby2 +36 -0
  33. data/sample/build-svn +55 -0
  34. data/sample/build-yarv +35 -0
  35. data/sample/test-apr +12 -0
  36. data/sample/test-catcherr +23 -0
  37. data/sample/test-combfail +21 -0
  38. data/sample/test-core +14 -0
  39. data/sample/test-core2 +19 -0
  40. data/sample/test-date +9 -0
  41. data/sample/test-dep +17 -0
  42. data/sample/test-depver +14 -0
  43. data/sample/test-echo +9 -0
  44. data/sample/test-env +9 -0
  45. data/sample/test-error +9 -0
  46. data/sample/test-fail +18 -0
  47. data/sample/test-fmesg +16 -0
  48. data/sample/test-gcc-v +15 -0
  49. data/sample/test-git +11 -0
  50. data/sample/test-leave-proc +9 -0
  51. data/sample/test-limit +9 -0
  52. data/sample/test-make +9 -0
  53. data/sample/test-neterr +16 -0
  54. data/sample/test-savannah +14 -0
  55. data/sample/test-sleep +9 -0
  56. data/sample/test-timeout +9 -0
  57. data/sample/test-timeout2 +10 -0
  58. data/sample/test-timeout3 +9 -0
  59. data/sample/test-upload +13 -0
  60. data/sample/test-warn +13 -0
  61. data/setup/upload-rsync-ssh +572 -0
  62. data/test/misc/test-escape.rb +17 -0
  63. data/test/misc/test-logfile.rb +108 -0
  64. data/test/misc/test-timeoutcom.rb +23 -0
  65. data/test/test_helper.rb +9 -0
  66. metadata +123 -0
@@ -0,0 +1,33 @@
1
+ # Copyright (C) 2006 Tanaka Akira <akr@fsij.org>
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions are met:
5
+ #
6
+ # 1. Redistributions of source code must retain the above copyright notice, this
7
+ # list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
9
+ # this list of conditions and the following disclaimer in the documentation
10
+ # and/or other materials provided with the distribution.
11
+ # 3. The name of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
19
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
23
+ # OF SUCH DAMAGE.
24
+
25
+ require 'chkbuild/scm/cvs'
26
+
27
+ class ChkBuild::Build
28
+ def gnu_savannah_cvs(proj, mod, branch, opts={})
29
+ opts = opts.dup
30
+ opts[:viewcvs] ||= "http://savannah.gnu.org/cgi-bin/viewcvs/#{proj}?diff_format=u"
31
+ self.cvs(":pserver:anonymous@cvs.savannah.gnu.org:/sources/#{proj}", mod, branch, opts)
32
+ end
33
+ end
@@ -0,0 +1,180 @@
1
+ # Copyright (C) 2006,2007,2008,2009 Tanaka Akira <akr@fsij.org>
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions are met:
5
+ #
6
+ # 1. Redistributions of source code must retain the above copyright notice, this
7
+ # list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
9
+ # this list of conditions and the following disclaimer in the documentation
10
+ # and/or other materials provided with the distribution.
11
+ # 3. The name of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
19
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
23
+ # OF SUCH DAMAGE.
24
+
25
+ class ChkBuild::Target
26
+ def initialize(target_name, *args, &block)
27
+ @target_name = target_name
28
+ @build_proc = block
29
+ @opts = ChkBuild.get_options
30
+ @opts.update args.pop if Hash === args.last
31
+ init_target(*args)
32
+ @title_hook = []
33
+ init_default_title_hooks
34
+ @failure_hook = []
35
+ @diff_preprocess_hook = []
36
+ init_default_diff_preprocess_hooks
37
+ @diff_preprocess_sort_patterns = []
38
+ end
39
+ attr_reader :target_name, :opts, :build_proc
40
+
41
+ def init_target(*args)
42
+ @dep_targets = []
43
+ suffixes_ary = []
44
+ args.each {|arg|
45
+ if ChkBuild::Target === arg
46
+ @dep_targets << arg
47
+ else
48
+ suffixes_ary << arg
49
+ end
50
+ }
51
+ @branches = []
52
+ Util.rproduct(*suffixes_ary) {|suffixes|
53
+ if @opts[:limit_combination]
54
+ next if !@opts[:limit_combination].call(*suffixes)
55
+ end
56
+ suffixes.compact!
57
+ @branches << suffixes
58
+ }
59
+ end
60
+
61
+ def init_default_title_hooks
62
+ add_title_hook('success') {|title, log|
63
+ title.update_title(:status) {|val| 'success' if !val }
64
+ }
65
+ add_title_hook('failure') {|title, log|
66
+ title.update_title(:status) {|val|
67
+ if !val
68
+ line = /\n/ =~ log ? $` : log
69
+ line = line.strip
70
+ line if !line.empty?
71
+ end
72
+ }
73
+ }
74
+ add_title_hook(nil) {|title, log|
75
+ num_warns = log.scan(/warn/i).length
76
+ title.update_title(:warn) {|val| "#{num_warns}W" } if 0 < num_warns
77
+ }
78
+ add_title_hook('dependencies') {|title, log|
79
+ dep_versions = []
80
+ title.logfile.dependencies.each {|suffixed_name, time, ver|
81
+ dep_versions << "(#{ver})"
82
+ }
83
+ title.update_title(:dep_versions, dep_versions)
84
+ }
85
+ end
86
+
87
+ def add_title_hook(secname, &block) @title_hook << [secname, block] end
88
+ def each_title_hook(&block) @title_hook.each(&block) end
89
+
90
+ def add_failure_hook(secname, &block) @failure_hook << [secname, block] end
91
+ def each_failure_hook(&block) @failure_hook.each(&block) end
92
+
93
+ CHANGE_LINE_PAT = /^(ADD|DEL|CHG) .*\t.*->.*\n|^COMMIT .*\n|^last commit:\n/
94
+
95
+ def init_default_diff_preprocess_hooks
96
+ add_diff_preprocess_gsub(/ # \d{4,}-\d\d-\d\dT\d\d:\d\d:\d\d[-+]\d\d:\d\d$/) {|match|
97
+ ' # <time>'
98
+ }
99
+ add_diff_preprocess_gsub(CHANGE_LINE_PAT) {|match| '' }
100
+ add_diff_preprocess_gsub(/timeout: the process group \d+ is alive/) {|match|
101
+ "timeout: the process group <pgid> is alive"
102
+ }
103
+ add_diff_preprocess_gsub(/some descendant process in process group \d+ remain/) {|match|
104
+ "some descendant process in process group <pgid> remain"
105
+ }
106
+ end
107
+
108
+ def add_diff_preprocess_gsub(pat, &block)
109
+ @diff_preprocess_hook << lambda {|line| line.gsub(pat) { yield $~ } }
110
+ end
111
+ def add_diff_preprocess_hook(&block) @diff_preprocess_hook << block end
112
+ def each_diff_preprocess_hook(&block) @diff_preprocess_hook.each(&block) end
113
+
114
+ def add_diff_preprocess_sort(pat) @diff_preprocess_sort_patterns << pat end
115
+ def diff_preprocess_sort_pattern()
116
+ if @diff_preprocess_sort_patterns.empty?
117
+ nil
118
+ else
119
+ /\A#{Regexp.union(*@diff_preprocess_sort_patterns)}/
120
+ end
121
+ end
122
+
123
+ def each_suffixes
124
+ @branches.each {|suffixes|
125
+ yield suffixes
126
+ }
127
+ end
128
+
129
+ def update_option(hash)
130
+ @opts.update(hash)
131
+ end
132
+
133
+ def make_build_objs
134
+ return @builds if defined? @builds
135
+ builds = []
136
+ each_suffixes {|suffixes|
137
+ dep_builds = @dep_targets.map {|dep_target| dep_target.make_build_objs }
138
+ Util.rproduct(*dep_builds) {|dependencies|
139
+ builds << ChkBuild::Build.new(self, suffixes, dependencies)
140
+ }
141
+ }
142
+ @builds = builds
143
+ end
144
+ def each_build_obj(&block)
145
+ make_build_objs.each(&block)
146
+ end
147
+
148
+ def make_result
149
+ return @result if defined? @result
150
+ succeed = Result.new
151
+ each_build_obj {|build|
152
+ if build.depbuilds.all? {|depbuild| depbuild.success? }
153
+ succeed.add(build) if build.build
154
+ end
155
+ }
156
+ @result = succeed
157
+ succeed
158
+ end
159
+
160
+ def result
161
+ return @result if defined? @result
162
+ raise "#{@target_name}: no result yet"
163
+ end
164
+
165
+ class Result
166
+ include Enumerable
167
+
168
+ def initialize
169
+ @list = []
170
+ end
171
+
172
+ def add(elt)
173
+ @list << elt
174
+ end
175
+
176
+ def each
177
+ @list.each {|elt| yield elt }
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,94 @@
1
+ # Copyright (C) 2006 Tanaka Akira <akr@fsij.org>
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions are met:
5
+ #
6
+ # 1. Redistributions of source code must retain the above copyright notice, this
7
+ # list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
9
+ # this list of conditions and the following disclaimer in the documentation
10
+ # and/or other materials provided with the distribution.
11
+ # 3. The name of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
19
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
23
+ # OF SUCH DAMAGE.
24
+
25
+ require 'chkbuild'
26
+
27
+ module ChkBuild
28
+ module GCC
29
+ module_function
30
+ def def_target(*args)
31
+ gcc = ChkBuild.def_target("gcc",
32
+ *args) {|b, *suffixes|
33
+ gcc_dir = b.build_dir
34
+
35
+ gcc_branch = nil
36
+ odcctools_dir = nil
37
+ suffixes.each {|s|
38
+ case s
39
+ when "trunk" then gcc_branch = "trunk"
40
+ when "4.2" then gcc_branch = "branches/gcc-4_2-branch"
41
+ when "4.1" then gcc_branch = "branches/gcc-4_1-branch"
42
+ when "4.0" then gcc_branch = "branches/gcc-4_0-branch"
43
+ when /\Aodcctools_dir=/
44
+ odcctools_dir = $'
45
+ else
46
+ raise "unexpected suffix: #{s.inspect}"
47
+ end
48
+ }
49
+
50
+ Dir.chdir("..") {
51
+ if odcctools_dir
52
+ File.unlink("gcc/gcc/config/darwin.h") rescue nil
53
+ end
54
+ b.svn("svn://gcc.gnu.org/svn/gcc", gcc_branch, 'gcc',
55
+ :viewvc=>"http://gcc.gnu.org/viewcvs")
56
+ if odcctools_dir
57
+ b.run("perl", "-pi", "-e", "s,/usr/bin/libtool,/Users/akr/bin/libtool,;", "gcc/gcc/config/darwin.h")
58
+ end
59
+ }
60
+ b.mkcd("objdir")
61
+ configure_flags = %w[--enable-languages=c]
62
+ if odcctools_dir
63
+ configure_flags.concat %W[--disable-checking --with-as=#{odcctools_dir}/bin/as --with-ld=#{odcctools_dir}/bin/ld]
64
+ else
65
+ configure_flags.concat %W[--disable-shared --disable-multilib]
66
+ end
67
+ b.run("../../gcc/configure", "--prefix=#{gcc_dir}", *configure_flags)
68
+ b.make("bootstrap", "install", :timeout=>'5h')
69
+ b.run("#{gcc_dir}/bin/gcc", '-v', :section=>'version')
70
+ }
71
+
72
+ gcc.add_title_hook('version') {|title, log|
73
+ if /^gcc version (.*)$/ =~ log
74
+ title.update_title(:version, "gcc #{$1}")
75
+ end
76
+ }
77
+
78
+ gcc.add_diff_preprocess_gsub(
79
+ /^(\ \ transformation:\ [0-9.]+,\ building\ DFA:\ [0-9.]+
80
+ |\ \ transformation:\ [0-9.]+,\ building\ NDFA:\ [0-9.]+,\ NDFA\ ->\ DFA:\ [0-9.]+
81
+ |\ \ DFA\ minimization:\ [0-9.]+,\ making\ insn\ equivalence:\ [0-9.]+
82
+ |\ all\ automaton\ generation:\ [0-9.]+,\ output:\ [0-9.]+
83
+ )$/x) {|match|
84
+ match[0].gsub(/[0-9.]+/, '<t>')
85
+ }
86
+
87
+ gcc.add_diff_preprocess_gsub(%r{^/tmp/cc[A-Za-z0-9]+\.s:}) {
88
+ '/tmp/cc<tmpnam>.s:'
89
+ }
90
+
91
+ gcc
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,456 @@
1
+ # Copyright (C) 2006,2007,2008,2009 Tanaka Akira <akr@fsij.org>
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions are met:
5
+ #
6
+ # 1. Redistributions of source code must retain the above copyright notice, this
7
+ # list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
9
+ # this list of conditions and the following disclaimer in the documentation
10
+ # and/or other materials provided with the distribution.
11
+ # 3. The name of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17
+ # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
19
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
23
+ # OF SUCH DAMAGE.
24
+
25
+ require 'chkbuild'
26
+
27
+ module ChkBuild
28
+ module Ruby
29
+ METHOD_LIST_SCRIPT = <<'End'
30
+ use_symbol = Object.instance_methods[0].is_a?(Symbol)
31
+ nummodule = nummethod = 0
32
+ mods = []
33
+ ObjectSpace.each_object(Module) {|m| mods << m if m.name }
34
+ mods = mods.sort_by {|m| m.name }
35
+ mods.each {|mod|
36
+ nummodule += 1
37
+ puts "#{mod.name} #{(mod.ancestors - [mod]).inspect}"
38
+ mod.singleton_methods(false).sort.each {|methname|
39
+ nummethod += 1
40
+ meth = mod.method(methname)
41
+ line = "#{mod.name}.#{methname} #{meth.arity}"
42
+ line << " not-implemented" if !mod.respond_to?(methname)
43
+ puts line
44
+ }
45
+ ms = mod.instance_methods(false)
46
+ if use_symbol
47
+ ms << :initialize if mod.private_instance_methods(false).include? :initialize
48
+ else
49
+ ms << "initialize" if mod.private_instance_methods(false).include? "initialize"
50
+ end
51
+ ms.sort.each {|methname|
52
+ nummethod += 1
53
+ meth = mod.instance_method(methname)
54
+ line = "#{mod.name}\##{methname} #{meth.arity}"
55
+ line << " not-implemented" if /\(not-implemented\)/ =~ meth.inspect
56
+ puts line
57
+ }
58
+ }
59
+ puts "#{nummodule} modules, #{nummethod} methods"
60
+ End
61
+
62
+ # not strictly RFC 1034.
63
+ DOMAINLABEL = /[A-Za-z0-9-]+/
64
+ DOMAINPAT = /#{DOMAINLABEL}(\.#{DOMAINLABEL})*/
65
+
66
+ module_function
67
+
68
+ def limit_combination(*suffixes)
69
+ if suffixes.include?("pth")
70
+ return false if suffixes.grep(/\A1\.8/).empty? && !suffixes.include?("matzruby")
71
+ end
72
+ true
73
+ end
74
+
75
+ MaintainedBranches = %w[trunk 1.9.1 1.8 1.8.7 1.8.6]
76
+
77
+ def def_target(*args)
78
+ opts = Hash === args.last ? args.pop : {}
79
+ default_opts = {:separated_srcdir=>false, :shared_gitdir=>ChkBuild.build_top}
80
+ opts = default_opts.merge(opts)
81
+ opts[:limit_combination] = method(:limit_combination)
82
+ args.push opts
83
+ opts = Hash === args.last ? args.last : {}
84
+ separated_srcdir = opts[:separated_srcdir]
85
+ t = ChkBuild.def_target("ruby", *args) {|b, *suffixes|
86
+ ruby_build_dir = b.build_dir
87
+
88
+ ruby_branch = nil
89
+ configure_flags = %w[--with-valgrind]
90
+ cflags = %w[]
91
+ cppflags = %w[-DRUBY_DEBUG_ENV]
92
+ optflags = %w[-O2]
93
+ debugflags = %w[-g]
94
+ warnflags = %w[-W -Wall -Wformat=2 -Wundef -Wno-parentheses -Wno-unused-parameter]
95
+ dldflags = %w[]
96
+ gcc_dir = nil
97
+ autoconf_command = 'autoconf'
98
+ make_options = {}
99
+ suffixes.each {|s|
100
+ case s
101
+ when "trunk" then ruby_branch = 'trunk'
102
+ when "mvm" then ruby_branch = 'branches/mvm'
103
+ cppflags.delete '-DRUBY_DEBUG_ENV'
104
+ when "half-baked-1.9" then ruby_branch = 'branches/half-baked-1.9'
105
+ when "matzruby" then ruby_branch = 'branches/matzruby'
106
+ when "1.9.1" then ruby_branch = 'branches/ruby_1_9_1'
107
+ when "1.8" then ruby_branch = 'branches/ruby_1_8'
108
+ when "1.8.5" then ruby_branch = 'branches/ruby_1_8_5'
109
+ when "1.8.6" then ruby_branch = 'branches/ruby_1_8_6'
110
+ when "1.8.7" then ruby_branch = 'branches/ruby_1_8_7'
111
+ when "o0"
112
+ optflags.delete_if {|arg| /\A-O\d\z/ =~ arg }
113
+ optflags << '-O0'
114
+ when "o1"
115
+ optflags.delete_if {|arg| /\A-O\d\z/ =~ arg }
116
+ optflags << '-O1'
117
+ when "o3"
118
+ optflags.delete_if {|arg| /\A-O\d\z/ =~ arg }
119
+ optflags << '-O3'
120
+ when "pth" then configure_flags << '--enable-pthread'
121
+ when "m32"
122
+ cflags.delete_if {|arg| /\A-m(32|64)\z/ =~ arg }
123
+ cflags << '-m32'
124
+ dldflags.delete_if {|arg| /\A-m(32|64)\z/ =~ arg }
125
+ dldflags << '-m32'
126
+ when "m64"
127
+ cflags.delete_if {|arg| /\A-m(32|64)\z/ =~ arg }
128
+ cflags << '-m64'
129
+ dldflags.delete_if {|arg| /\A-m(32|64)\z/ =~ arg }
130
+ dldflags << '-m64'
131
+ when /\Agcc=/
132
+ configure_flags << "CC=#{$'}/bin/gcc"
133
+ make_options["ENV:LD_RUN_PATH"] = "#{$'}/lib"
134
+ when /\Aautoconf=/
135
+ autoconf_command = "#{$'}/bin/autoconf"
136
+ else
137
+ raise "unexpected suffix: #{s.inspect}"
138
+ end
139
+ }
140
+
141
+ if opts["--with-opt-dir"]
142
+ configure_flags << "--with-opt-dir=#{opts['--with-opt-dir']}"
143
+ end
144
+
145
+ if %r{branches/ruby_1_8_} =~ ruby_branch && $' < "8"
146
+ cflags.concat cppflags
147
+ cflags.concat optflags
148
+ cflags.concat debugflags
149
+ cflags.concat warnflags
150
+ cppflags = nil
151
+ optflags = nil
152
+ debugflags = nil
153
+ warnflags = nil
154
+ end
155
+
156
+ use_rubyspec = false
157
+ if ENV['PATH'].split(/:/).any? {|d| File.executable?("#{d}/git") }
158
+ use_rubyspec = true
159
+ end
160
+
161
+ objdir = ruby_build_dir+'ruby'
162
+ if separated_srcdir
163
+ checkout_dir = ruby_build_dir.dirname
164
+ else
165
+ checkout_dir = ruby_build_dir
166
+ end
167
+ srcdir = (checkout_dir+'ruby').relative_path_from(objdir)
168
+
169
+ Dir.chdir(checkout_dir)
170
+ b.svn("http://svn.ruby-lang.org/repos/ruby", ruby_branch, 'ruby',
171
+ :viewvc=>'http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?diff_format=u')
172
+ Dir.chdir("ruby")
173
+ b.run(autoconf_command)
174
+
175
+ Dir.chdir(ruby_build_dir)
176
+
177
+ use_rubyspec &&= b.catch_error {
178
+ opts2 = opts.dup
179
+ opts2[:section] = "git-mspec"
180
+ b.github("rubyspec", "mspec", "mspec", opts2)
181
+ }
182
+ use_rubyspec &&= b.catch_error {
183
+ opts2 = opts.dup
184
+ opts2[:section] = "git-rubyspec"
185
+ b.github("rubyspec", "rubyspec", "rubyspec", opts2)
186
+ }
187
+
188
+ b.mkcd("ruby")
189
+ args = []
190
+ args << "--prefix=#{ruby_build_dir}"
191
+ args << "CFLAGS=#{cflags.join(' ')}" if cflags && !cflags.empty?
192
+ args << "CPPFLAGS=#{cppflags.join(' ')}" if cppflags && !cppflags.empty?
193
+ args << "optflags=#{optflags.join(' ')}" if optflags
194
+ args << "debugflags=#{debugflags.join(' ')}" if debugflags
195
+ args << "warnflags=#{warnflags.join(' ')}" if warnflags
196
+ args << "DLDFLAGS=#{dldflags.join(' ')}" unless dldflags.empty?
197
+ args.concat configure_flags
198
+ b.run("#{srcdir}/configure", *args)
199
+ b.make("miniruby", make_options)
200
+ b.catch_error { b.run("./miniruby", "-v", :section=>"miniversion") }
201
+ if File.directory? "#{srcdir}/bootstraptest"
202
+ b.catch_error { b.make("btest", "OPTS=-v -q", :section=>"btest") }
203
+ end
204
+ b.catch_error {
205
+ b.run("./miniruby", "#{srcdir+'sample/test.rb'}", :section=>"test.rb")
206
+ if /^end of test/ !~ b.logfile.get_section('test.rb')
207
+ raise ChkBuild::Build::CommandError.new(0, "test.rb")
208
+ end
209
+ }
210
+ b.catch_error { b.run("./miniruby", '-e', METHOD_LIST_SCRIPT, :section=>"method-list") }
211
+ b.make(make_options)
212
+ b.catch_error { b.run("./ruby", "-v", :section=>"version") }
213
+ b.make("install-nodoc")
214
+ b.catch_error { b.make("install-doc") }
215
+ if File.file? "#{srcdir}/KNOWNBUGS.rb"
216
+ b.catch_error { b.make("test-knownbug", "OPTS=-v -q") }
217
+ end
218
+ #b.catch_error { b.run("./ruby", "#{srcdir+'test/runner.rb'}", "-v", :section=>"test-all") }
219
+ b.catch_error { b.make("test-all", "TESTS=-v", :section=>"test-all") }
220
+
221
+ Dir.chdir(ruby_build_dir)
222
+ use_rubyspec &&= b.catch_error {
223
+ if %r{branches/ruby_1_8} =~ ruby_branch
224
+ config = Dir.pwd + "/rubyspec/ruby.1.8.mspec"
225
+ command = %W[bin/ruby mspec/bin/mspec -V -f s -B #{config} -t bin/ruby -G critical rubyspec]
226
+ else
227
+ config = Dir.pwd + "/rubyspec/ruby.1.9.mspec"
228
+ command = %W[bin/ruby mspec/bin/mspec ci -V -f s -B #{config} -t bin/ruby rubyspec]
229
+ end
230
+ command << { :section=>"rubyspec" }
231
+ b.run(*command)
232
+ }
233
+ }
234
+
235
+ t.add_title_hook("configure") {|title, log|
236
+ if /^checking target system type\.\.\. (\S+)$/ =~ log
237
+ title.update_title(:version, "#{title.suffixed_name} [#{$1}]")
238
+ end
239
+ }
240
+
241
+ t.add_title_hook("miniversion") {|title, log|
242
+ if /^ruby [0-9].*$/ =~ log
243
+ ver = $&
244
+ ss = title.suffixed_name.split(/-/)[1..-1].reject {|s| /\A(trunk|1\.8)\z/ =~ s }
245
+ ver << " [#{ss.join(',')}]" if !ss.empty?
246
+ title.update_title(:version, ver)
247
+ end
248
+ }
249
+
250
+ t.add_title_hook("version") {|title, log|
251
+ if /^ruby [0-9].*$/ =~ log
252
+ ver = $&
253
+ ss = title.suffixed_name.split(/-/)[1..-1].reject {|s| /\A(trunk|1\.8)\z/ =~ s }
254
+ ver << " [#{ss.join(',')}]" if !ss.empty?
255
+ title.update_title(:version, ver)
256
+ end
257
+ }
258
+
259
+ t.add_failure_hook("btest") {|log|
260
+ if /^FAIL (\d+)\/\d+ tests failed/ =~ log
261
+ "#{$1}BFail"
262
+ end
263
+ }
264
+
265
+ t.add_failure_hook("test-knownbug") {|log|
266
+ if /^FAIL (\d+)\/\d+ tests failed/ =~ log
267
+ "#{$1}KB"
268
+ elsif /^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors$/ =~ log
269
+ failures = $1.to_i
270
+ errors = $2.to_i
271
+ if failures != 0 || errors != 0
272
+ "KB#{failures}F#{errors}E"
273
+ end
274
+ end
275
+ }
276
+
277
+ t.add_failure_hook("test.rb") {|log|
278
+ if /^end of test/ !~ log
279
+ if /^test: \d+ failed (\d+)/ =~ log || %r{^not ok/test: \d+ failed (\d+)} =~ log
280
+ "#{$1}NotOK"
281
+ end
282
+ end
283
+ }
284
+
285
+ t.add_failure_hook("test-all") {|log|
286
+ if /^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors$/ =~ log
287
+ failures = $1.to_i
288
+ errors = $2.to_i
289
+ if failures != 0 || errors != 0
290
+ "#{failures}F#{errors}E"
291
+ end
292
+ elsif /^\d+ tests, \d+ assertions, (\d+) failures, (\d+) errors, (\d+) skips$/ =~ log
293
+ failures = $1.to_i
294
+ errors = $2.to_i
295
+ skips = $3.to_i
296
+ if failures != 0 || errors != 0 || skips != 0
297
+ if skips == 0
298
+ "#{failures}F#{errors}E"
299
+ else
300
+ "#{failures}F#{errors}E#{skips}S"
301
+ end
302
+ end
303
+ end
304
+ }
305
+
306
+ t.add_failure_hook("rubyspec") {|log|
307
+ if /^\d+ files?, \d+ examples?, \d+ expectations?, (\d+) failures?, (\d+) errors?$/ =~ log
308
+ failures = $1.to_i
309
+ errors = $2.to_i
310
+ if failures != 0 || errors != 0
311
+ "rubyspec:#{failures}F#{errors}E"
312
+ end
313
+ end
314
+ }
315
+
316
+ t.add_title_hook(nil) {|title, log|
317
+ mark = ''
318
+ numbugs = count_prefix(/\[BUG\]/i, log) and mark << " #{numbugs}[BUG]"
319
+ numsegv = count_prefix(
320
+ /segmentation fault|signal segv/i,
321
+ log.sub(/combination may cause frequent hang or segmentation fault|hangs or segmentation faults/, '')) and # skip tk message.
322
+ mark << " #{numsegv}[SEGV]"
323
+ numsigbus = count_prefix(/signal SIGBUS/i, log) and mark << " #{numsigbus}[SIGBUS]"
324
+ numsigill = count_prefix(/signal SIGILL/i, log) and mark << " #{numsigill}[SIGILL]"
325
+ numsigabrt = count_prefix(/signal SIGABRT/i, log) and mark << " #{numsigabrt}[SIGABRT]"
326
+ numfatal = count_prefix(/\[FATAL\]/i, log) and mark << " #{numfatal}[FATAL]"
327
+ mark.sub!(/\A /, '')
328
+ title.update_title(:mark, mark)
329
+ }
330
+
331
+ # delete trailing spaces.
332
+ t.add_diff_preprocess_gsub(/[ \t]*$/) {|match|
333
+ ""
334
+ }
335
+
336
+ # test_exception.rb #1 test_exception.rb:1
337
+ t.add_diff_preprocess_gsub(/\#\d+ test_/) {|match|
338
+ "#<n> test_"
339
+ }
340
+
341
+ # test/unit:
342
+ # 28) Error:
343
+ # 33) Failure:
344
+ # rubyspec:
345
+ # 61)
346
+ t.add_diff_preprocess_gsub(/^ *\d+\)( Error:| Failure:|$)/) {|match|
347
+ " <n>) #{match[1]}"
348
+ }
349
+
350
+ # rubyspec
351
+ # -- reports aborting on a killed thread (FAILED - 9)
352
+ # -- flattens self (ERROR - 21)
353
+ t.add_diff_preprocess_gsub(/\((FAILED|ERROR) - \d+\)$/) {|match|
354
+ "(#{match[1]} - <n>)"
355
+ }
356
+
357
+ t.add_diff_preprocess_gsub(%r{\((druby|drbssl)://(#{DOMAINPAT}):\d+\)}o) {|match|
358
+ "(#{match[1]}://#{match[2]}:<port>)"
359
+ }
360
+
361
+ # [2006-09-24T12:48:49.245737 #6902] ERROR -- : undefined method `each' for #<String:0x447fc5e4> (NoMethodError)
362
+ t.add_diff_preprocess_gsub(%r{\[\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+) \#(\d+)\]}o) {|match|
363
+ "[YYYY-MM-DDThh:mm:ss" + match[1].gsub(/\d/, 's') + " #<pid>]"
364
+ }
365
+
366
+ # #<String:0x4455ae94
367
+ t.add_diff_preprocess_gsub(%r{\#<[A-Z][A-Za-z0-9_]*(?:::[A-Z][A-Za-z0-9_]*)*:0x[0-9a-f]+}o) {|match|
368
+ match[0].sub(/[0-9a-f]+\z/) { 'X' * $&.length }
369
+ }
370
+
371
+ # #<#<Class:0xXXXXXXX>:0x0e87dd00
372
+ # order sensitive. this should be applied after the above.
373
+ t.add_diff_preprocess_gsub(%r{(\#<\#<Class:0xX+>:0x)([0-9a-f]+)}o) {|match|
374
+ match[1] + 'X' * match[2].length
375
+ }
376
+
377
+ # #<BigDecimal:403070d8,
378
+ t.add_diff_preprocess_gsub(%r{\#<BigDecimal:[0-9a-f]+}) {|match|
379
+ match[0].sub(/[0-9a-f]+\z/) { 'X' * $&.length }
380
+ }
381
+
382
+ # but got ThreadError (uncaught throw `blah' in thread 0x23f0660)
383
+ t.add_diff_preprocess_gsub(%r{thread 0x[0-9a-f]+}o) {|match|
384
+ match[0].sub(/[0-9a-f]+\z/) { 'X' * $&.length }
385
+ }
386
+
387
+ # XSD::ValueSpaceError: {http://www.w3.org/2001/XMLSchema}dateTime: cannot accept '2007-02-01T23:44:2682967.846399999994901+09:00'.
388
+ t.add_diff_preprocess_gsub(%r{\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\d+\.\d+}o) {|match|
389
+ s = match[0]
390
+ chars = %w[Y M D h m s s]
391
+ s.gsub!(/\d+/) { "<#{chars.shift}>" }
392
+ s
393
+ }
394
+
395
+ # mkdir -p /home/akr/chkbuild/tmp/build/ruby-trunk/<buildtime>/tmp/fileutils.rb.23661/tmpdir/dir/
396
+ t.add_diff_preprocess_gsub(%r{/tmp/fileutils.rb.\d+/tmpdir/}o) {|match|
397
+ '/tmp/fileutils.rb.<n>/tmpdir/'
398
+ }
399
+
400
+ # connect to #<Addrinfo: [::1]:54046 TCP>.
401
+ t.add_diff_preprocess_gsub(%r{\#<Addrinfo: \[::1\]:\d+}o) {|match|
402
+ '#<Addrinfo: [::1]:<port>'
403
+ }
404
+
405
+ t.add_diff_preprocess_gsub(/^Elapsed: [0-9.]+s/) {|match|
406
+ "Elapsed: <t>s"
407
+ }
408
+
409
+ # test/unit:
410
+ # Finished in 139.785699 seconds.
411
+ # rubyspec:
412
+ # Finished in 31.648244 seconds
413
+ t.add_diff_preprocess_gsub(/^Finished in [0-9.]+ seconds/) {|match|
414
+ "Finished in <t> seconds"
415
+ }
416
+
417
+ # /tmp/test_rubygems_18634
418
+ t.add_diff_preprocess_gsub(%r{/tmp/test_rubygems_\d+}o) {|match|
419
+ '/tmp/test_rubygems_<pid>'
420
+ }
421
+
422
+ # <buildtime>/mspec/lib/mspec/mocks/mock.rb:128:in `__ms_70044980_respond_to?__'
423
+ t.add_diff_preprocess_gsub(%r{__ms_-?\d+_}) {|match|
424
+ '__ms_<object_id>_'
425
+ }
426
+
427
+ # miniunit:
428
+ # Complex_Test#test_parse: 0.01 s: .
429
+ t.add_diff_preprocess_gsub(%r{\d+\.\d\d s: }) {|match|
430
+ '<elapsed> s: '
431
+ }
432
+
433
+ # MinitestSpec#test_needs_to_verify_nil: <elapsed> s: .
434
+ # RUNIT::TestAssert#test_assert_send: .
435
+ t.add_diff_preprocess_sort(/\A[A-Z][A-Za-z0-9_]+(::[A-Z][A-Za-z0-9_]+)*\#/)
436
+
437
+ # - returns self as a symbol literal for :$*
438
+ t.add_diff_preprocess_sort(/\A- returns self as a symbol literal for :/)
439
+
440
+ t
441
+ end
442
+
443
+ def count_prefix(pat, str)
444
+ n = 0
445
+ str.scan(pat) { n += 1 }
446
+ case n
447
+ when 0
448
+ nil
449
+ when 1
450
+ ""
451
+ else
452
+ n.to_s
453
+ end
454
+ end
455
+ end
456
+ end