yugui-chkbuild 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.ja.rd +191 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/bin/last-build +28 -0
- data/bin/start-build +37 -0
- data/chkbuild.gemspec +107 -0
- data/core_ext/io.rb +17 -0
- data/core_ext/string.rb +10 -0
- data/lib/chkbuild.rb +45 -0
- data/lib/chkbuild/build.rb +718 -0
- data/lib/chkbuild/lock.rb +57 -0
- data/lib/chkbuild/logfile.rb +230 -0
- data/lib/chkbuild/main.rb +138 -0
- data/lib/chkbuild/options.rb +62 -0
- data/lib/chkbuild/scm/cvs.rb +132 -0
- data/lib/chkbuild/scm/git.rb +223 -0
- data/lib/chkbuild/scm/svn.rb +215 -0
- data/lib/chkbuild/scm/xforge.rb +33 -0
- data/lib/chkbuild/target.rb +180 -0
- data/lib/chkbuild/targets/gcc.rb +94 -0
- data/lib/chkbuild/targets/ruby.rb +456 -0
- data/lib/chkbuild/title.rb +107 -0
- data/lib/chkbuild/upload.rb +66 -0
- data/lib/misc/escape.rb +535 -0
- data/lib/misc/gdb.rb +74 -0
- data/lib/misc/timeoutcom.rb +174 -0
- data/lib/misc/udiff.rb +244 -0
- data/lib/misc/util.rb +232 -0
- data/sample/build-autoconf-ruby +69 -0
- data/sample/build-gcc-ruby +43 -0
- data/sample/build-ruby +37 -0
- data/sample/build-ruby2 +36 -0
- data/sample/build-svn +55 -0
- data/sample/build-yarv +35 -0
- data/sample/test-apr +12 -0
- data/sample/test-catcherr +23 -0
- data/sample/test-combfail +21 -0
- data/sample/test-core +14 -0
- data/sample/test-core2 +19 -0
- data/sample/test-date +9 -0
- data/sample/test-dep +17 -0
- data/sample/test-depver +14 -0
- data/sample/test-echo +9 -0
- data/sample/test-env +9 -0
- data/sample/test-error +9 -0
- data/sample/test-fail +18 -0
- data/sample/test-fmesg +16 -0
- data/sample/test-gcc-v +15 -0
- data/sample/test-git +11 -0
- data/sample/test-leave-proc +9 -0
- data/sample/test-limit +9 -0
- data/sample/test-make +9 -0
- data/sample/test-neterr +16 -0
- data/sample/test-savannah +14 -0
- data/sample/test-sleep +9 -0
- data/sample/test-timeout +9 -0
- data/sample/test-timeout2 +10 -0
- data/sample/test-timeout3 +9 -0
- data/sample/test-upload +13 -0
- data/sample/test-warn +13 -0
- data/setup/upload-rsync-ssh +572 -0
- data/test/misc/test-escape.rb +17 -0
- data/test/misc/test-logfile.rb +108 -0
- data/test/misc/test-timeoutcom.rb +23 -0
- data/test/test_helper.rb +9 -0
- metadata +123 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright (C) 2006,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
|
+
module ChkBuild
|
26
|
+
LOCK_PATH = ChkBuild.build_top + '.lock'
|
27
|
+
|
28
|
+
def self.lock_start
|
29
|
+
if !defined?(@lock_io)
|
30
|
+
@lock_io = LOCK_PATH.open(File::WRONLY|File::CREAT)
|
31
|
+
end
|
32
|
+
if @lock_io.flock(File::LOCK_EX|File::LOCK_NB) == false
|
33
|
+
raise "another chkbuild is running."
|
34
|
+
end
|
35
|
+
@lock_io.truncate(0)
|
36
|
+
@lock_io.sync = true
|
37
|
+
@lock_io.close_on_exec = true
|
38
|
+
@lock_io.puts "locked pid:#{$$}"
|
39
|
+
lock_pid = $$
|
40
|
+
at_exit {
|
41
|
+
@lock_io.puts "exit pid:#{$$}" if $$ == lock_pid
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.lock_puts(mesg)
|
46
|
+
if block_given?
|
47
|
+
t1 = Time.now
|
48
|
+
@lock_io.print "#{t1.iso8601} #{mesg}"
|
49
|
+
ret = yield
|
50
|
+
t2 = Time.now
|
51
|
+
@lock_io.puts "\t#{t2-t1}"
|
52
|
+
ret
|
53
|
+
else
|
54
|
+
@lock_io.puts "#{Time.now.iso8601} #{mesg}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# Copyright (C) 2006,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 'time'
|
26
|
+
|
27
|
+
module ChkBuild
|
28
|
+
end
|
29
|
+
|
30
|
+
class ChkBuild::LogFile
|
31
|
+
InitialMark = '=='
|
32
|
+
|
33
|
+
def self.write_open(filename, build)
|
34
|
+
logfile = self.new(filename, true)
|
35
|
+
logfile.start_section build.depsuffixed_name
|
36
|
+
logfile.with_default_output {
|
37
|
+
system("uname -a")
|
38
|
+
section_started = false
|
39
|
+
build.traverse_depbuild {|depbuild|
|
40
|
+
if !section_started
|
41
|
+
logfile.start_section 'dependencies'
|
42
|
+
section_started = true
|
43
|
+
end
|
44
|
+
if depbuild.suffixed_name == depbuild.version
|
45
|
+
puts "#{depbuild.suffixed_name} #{depbuild.start_time}"
|
46
|
+
else
|
47
|
+
puts "#{depbuild.suffixed_name} #{depbuild.start_time} (#{depbuild.version})"
|
48
|
+
end
|
49
|
+
}
|
50
|
+
}
|
51
|
+
logfile
|
52
|
+
end
|
53
|
+
|
54
|
+
def dependencies
|
55
|
+
return [] unless log = self.get_section('dependencies')
|
56
|
+
r = []
|
57
|
+
log.each_line {|line|
|
58
|
+
if /^(\S+) (\d+T\d+) \((.*)\)$/ =~ line
|
59
|
+
r << [$1, $2, $3]
|
60
|
+
elsif /^(\S+) (\d+T\d+)$/ =~ line
|
61
|
+
r << [$1, $2, $1]
|
62
|
+
end
|
63
|
+
}
|
64
|
+
r
|
65
|
+
end
|
66
|
+
|
67
|
+
def depsuffixed_name
|
68
|
+
return @depsuffixed_name if defined? @depsuffixed_name
|
69
|
+
if /\A\S+\s+(\S+)/ =~ self.get_all_log
|
70
|
+
return @depsuffixed_name = $1
|
71
|
+
end
|
72
|
+
raise "unexpected log format"
|
73
|
+
end
|
74
|
+
|
75
|
+
def suffixed_name() depsuffixed_name.sub(/_.*/, '') end
|
76
|
+
def target_name() suffixed_name.sub(/-.*/, '') end
|
77
|
+
def suffixes() suffixed_name.split(/-/)[1..-1] end
|
78
|
+
|
79
|
+
def self.read_open(filename)
|
80
|
+
self.new(filename, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize(filename, writemode)
|
84
|
+
@writemode = writemode
|
85
|
+
mode = writemode ? File::RDWR|File::CREAT|File::APPEND : File::RDONLY
|
86
|
+
@filename = filename
|
87
|
+
@io = File.open(filename, mode)
|
88
|
+
@io.set_encoding("ascii-8bit") if @io.respond_to? :set_encoding
|
89
|
+
@io.sync = true
|
90
|
+
@mark = read_separator
|
91
|
+
@sections = detect_sections
|
92
|
+
end
|
93
|
+
|
94
|
+
def read_separator
|
95
|
+
mark = nil
|
96
|
+
if @io.stat.size != 0
|
97
|
+
@io.rewind
|
98
|
+
mark = @io.gets[/\A\S+/]
|
99
|
+
end
|
100
|
+
mark || InitialMark
|
101
|
+
end
|
102
|
+
private :read_separator
|
103
|
+
|
104
|
+
def detect_sections
|
105
|
+
ret = {}
|
106
|
+
@io.rewind
|
107
|
+
pat = /\A#{Regexp.quote @mark} /
|
108
|
+
@io.each {|line|
|
109
|
+
if pat =~ line
|
110
|
+
epos = @io.pos
|
111
|
+
spos = epos - line.length
|
112
|
+
secname = $'.chomp.sub(/#.*/, '').strip
|
113
|
+
ret[secname] = spos
|
114
|
+
end
|
115
|
+
}
|
116
|
+
ret
|
117
|
+
end
|
118
|
+
private :detect_sections
|
119
|
+
|
120
|
+
# logfile.with_default_output { ... }
|
121
|
+
def with_default_output
|
122
|
+
raise "not opened for writing" if !@writemode
|
123
|
+
File.open(@filename, File::WRONLY|File::APPEND) {|f|
|
124
|
+
STDERR.tmp_reopen(f) {
|
125
|
+
STDERR.sync = true
|
126
|
+
STDOUT.tmp_reopen(f) {
|
127
|
+
STDOUT.sync = true
|
128
|
+
yield
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def change_default_output
|
135
|
+
raise "not opened for writing" if !@writemode
|
136
|
+
STDOUT.reopen(@save_io = File.for_fd(@io.fileno, File::WRONLY|File::APPEND))
|
137
|
+
STDERR.reopen(STDOUT)
|
138
|
+
STDOUT.sync = true
|
139
|
+
STDERR.sync = true
|
140
|
+
end
|
141
|
+
|
142
|
+
# start_section returns the (unique) section name.
|
143
|
+
def start_section(secname)
|
144
|
+
@io.flush
|
145
|
+
if 0 < @io.stat.size
|
146
|
+
@io.seek(-1, IO::SEEK_END)
|
147
|
+
if @io.read != "\n"
|
148
|
+
@io.write "\n"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
spos = @io.pos
|
152
|
+
secname = secname.strip
|
153
|
+
if @sections[secname]
|
154
|
+
i = 2
|
155
|
+
while @sections["#{secname}(#{i})"]
|
156
|
+
i += 1
|
157
|
+
end
|
158
|
+
secname = "#{secname}(#{i})"
|
159
|
+
end
|
160
|
+
@sections[secname] = spos
|
161
|
+
@io.write "#{@mark} #{secname} \# #{Time.now.iso8601}\n"
|
162
|
+
secname
|
163
|
+
end
|
164
|
+
|
165
|
+
def secnames
|
166
|
+
@sections.keys.sort_by {|secname| @sections[secname] }
|
167
|
+
end
|
168
|
+
|
169
|
+
def each_secname(&block)
|
170
|
+
@sections.keys.sort_by {|secname| @sections[secname] }.each(&block)
|
171
|
+
end
|
172
|
+
|
173
|
+
def section_size(secname)
|
174
|
+
spos = @sections[secname]
|
175
|
+
raise ArgumentError, "no section : #{secname.inspect}" if !spos
|
176
|
+
epos = @sections.values.reject {|pos| pos <= spos }.min
|
177
|
+
epos = @io.stat.size if !epos
|
178
|
+
epos - spos
|
179
|
+
end
|
180
|
+
|
181
|
+
def get_section(secname)
|
182
|
+
spos = @sections[secname]
|
183
|
+
return nil if !spos
|
184
|
+
@io.seek spos
|
185
|
+
@io.gets("\n#{@mark} ").chomp("#{@mark} ").sub(/\A.*\n/, '')
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_all_log
|
189
|
+
@io.rewind
|
190
|
+
@io.read
|
191
|
+
end
|
192
|
+
|
193
|
+
def modify_section(secname, data)
|
194
|
+
raise "not opened for writing" if !@writemode
|
195
|
+
spos = @sections[secname]
|
196
|
+
raise ArgumentError, "no section: #{secname.inspect}" if !spos
|
197
|
+
data += "\n" if /\n\z/ !~ data
|
198
|
+
old = nil
|
199
|
+
File.open(@filename, File::RDWR) {|f|
|
200
|
+
f.seek spos
|
201
|
+
rest = f.read
|
202
|
+
if /\n#{Regexp.quote @mark} / =~ rest
|
203
|
+
epos = $~.begin(0) + 1
|
204
|
+
curr = rest[0...epos]
|
205
|
+
rest = rest[epos..-1]
|
206
|
+
else
|
207
|
+
curr = rest
|
208
|
+
rest = ''
|
209
|
+
end
|
210
|
+
if /\n/ =~ curr
|
211
|
+
secline = $` + $&
|
212
|
+
old = $'
|
213
|
+
else
|
214
|
+
secline = curr + "\n"
|
215
|
+
old = ''
|
216
|
+
end
|
217
|
+
f.seek spos
|
218
|
+
f.print secline, data, rest
|
219
|
+
f.flush
|
220
|
+
f.truncate(f.pos)
|
221
|
+
}
|
222
|
+
off = data.length - old.length
|
223
|
+
@sections.each_pair {|n, pos|
|
224
|
+
if spos < pos
|
225
|
+
@sections[n] = pos + off
|
226
|
+
end
|
227
|
+
}
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,138 @@
|
|
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 'pathname'
|
26
|
+
require 'optparse'
|
27
|
+
|
28
|
+
module ChkBuild
|
29
|
+
TOP_DIRECTORY = Pathname.getwd
|
30
|
+
def ChkBuild.build_top() TOP_DIRECTORY+"tmp/build" end
|
31
|
+
def ChkBuild.public_top() TOP_DIRECTORY+"tmp/public_html" end
|
32
|
+
|
33
|
+
def ChkBuild.main_help(status=true)
|
34
|
+
if File.executable? $0
|
35
|
+
command = $0
|
36
|
+
else
|
37
|
+
require 'rbconfig'
|
38
|
+
ruby = "#{Config::CONFIG["bindir"]}/#{Config::CONFIG["ruby_install_name"]}"
|
39
|
+
command = "#{ruby} #{$0}"
|
40
|
+
end
|
41
|
+
print <<"End"
|
42
|
+
usage:
|
43
|
+
#{command} [build [--procmemsize]]
|
44
|
+
#{command} list
|
45
|
+
#{command} title [depsuffixed_name...]
|
46
|
+
#{command} logdiff [depsuffixed_name [date1 [date2]]]
|
47
|
+
End
|
48
|
+
exit status
|
49
|
+
end
|
50
|
+
|
51
|
+
@target_list = []
|
52
|
+
def ChkBuild.main_build
|
53
|
+
o = OptionParser.new
|
54
|
+
o.def_option('--procmemsize') {
|
55
|
+
@target_list.each {|t|
|
56
|
+
t.update_option(:procmemsize => true)
|
57
|
+
}
|
58
|
+
}
|
59
|
+
o.parse!
|
60
|
+
begin
|
61
|
+
Process.setpriority(Process::PRIO_PROCESS, 0, 10)
|
62
|
+
rescue Errno::EACCES # already niced to 11 or more
|
63
|
+
end
|
64
|
+
File.umask(002)
|
65
|
+
STDIN.reopen("/dev/null", "r")
|
66
|
+
STDOUT.sync = true
|
67
|
+
ChkBuild.build_top.mkpath
|
68
|
+
ChkBuild.lock_start
|
69
|
+
@target_list.each {|t|
|
70
|
+
t.make_result
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def ChkBuild.def_target(target_name, *args, &block)
|
75
|
+
t = ChkBuild::Target.new(target_name, *args, &block)
|
76
|
+
@target_list << t
|
77
|
+
t
|
78
|
+
end
|
79
|
+
|
80
|
+
def ChkBuild.main_list
|
81
|
+
@target_list.each {|t|
|
82
|
+
t.each_build_obj {|build|
|
83
|
+
puts build.depsuffixed_name
|
84
|
+
}
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def ChkBuild.main_title
|
89
|
+
@target_list.each {|t|
|
90
|
+
t.each_build_obj {|build|
|
91
|
+
next if !ARGV.empty? && !ARGV.include?(build.depsuffixed_name)
|
92
|
+
last_txt = ChkBuild.public_top + build.depsuffixed_name + 'last.txt'
|
93
|
+
if last_txt.exist?
|
94
|
+
logfile = ChkBuild::LogFile.read_open(last_txt)
|
95
|
+
title = ChkBuild::Title.new(t, logfile)
|
96
|
+
title.run_hooks
|
97
|
+
puts "#{build.depsuffixed_name}:\t#{title.make_title}"
|
98
|
+
end
|
99
|
+
}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def ChkBuild.main_logdiff
|
104
|
+
depsuffixed_name, arg_t1, arg_t2 = ARGV
|
105
|
+
@target_list.each {|t|
|
106
|
+
t.each_build_obj {|build|
|
107
|
+
next if depsuffixed_name && build.depsuffixed_name != depsuffixed_name
|
108
|
+
ts = build.log_time_sequence
|
109
|
+
raise "no log: #{build.depsuffixed_name}/#{arg_t1}" if arg_t1 and !ts.include?(arg_t1)
|
110
|
+
raise "no log: #{build.depsuffixed_name}/#{arg_t2}" if arg_t2 and !ts.include?(arg_t2)
|
111
|
+
if ts.length < 2
|
112
|
+
puts "#{build.depsuffixed_name}: less than 2 logs"
|
113
|
+
next
|
114
|
+
end
|
115
|
+
t1 = arg_t1 || ts[-2]
|
116
|
+
t2 = arg_t2 || ts[-1]
|
117
|
+
puts "#{build.depsuffixed_name}: #{t1}->#{t2}"
|
118
|
+
build.output_diff(t1, t2, STDOUT)
|
119
|
+
puts
|
120
|
+
}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def ChkBuild.main
|
125
|
+
ARGV.unshift 'build' if ARGV.empty?
|
126
|
+
subcommand = ARGV.shift
|
127
|
+
case subcommand
|
128
|
+
when 'help', '-h' then ChkBuild.main_help
|
129
|
+
when 'build' then ChkBuild.main_build
|
130
|
+
when 'list' then ChkBuild.main_list
|
131
|
+
when 'title' then ChkBuild.main_title
|
132
|
+
when 'logdiff' then ChkBuild.main_logdiff
|
133
|
+
else
|
134
|
+
puts "unexpected subcommand: #{subcommand}"
|
135
|
+
exit 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,62 @@
|
|
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
|
+
module ChkBuild
|
26
|
+
@default_options = {
|
27
|
+
:num_oldbuilds => 3,
|
28
|
+
:limit_cpu => 3600 * 4,
|
29
|
+
:limit_stack => 1024 * 1024 * 40,
|
30
|
+
:limit_data => 1024 * 1024 * 100,
|
31
|
+
:limit_as => 1024 * 1024 * 100
|
32
|
+
}
|
33
|
+
|
34
|
+
def self.get_options
|
35
|
+
@default_options.dup
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.num_oldbuilds
|
39
|
+
@default_options[:num_oldbuilds]
|
40
|
+
end
|
41
|
+
def self.num_oldbuilds=(val)
|
42
|
+
@default_options[:num_oldbuilds] = val
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.limit(hash)
|
46
|
+
hash.each {|k, v|
|
47
|
+
s = "limit_#{k}".intern
|
48
|
+
raise "unexpected resource name: #{k}" if !@default_options[s]
|
49
|
+
@default_options[s] = v
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.get_limit
|
54
|
+
ret = {}
|
55
|
+
@default_options.each {|k, v|
|
56
|
+
next if /\Alimit_/ !~ k.to_s
|
57
|
+
s = $'.intern
|
58
|
+
ret[s] = v
|
59
|
+
}
|
60
|
+
ret
|
61
|
+
end
|
62
|
+
end
|