2012-11-28 21:58:34 -05:00
|
|
|
# -*- coding: us-ascii -*-
|
2008-04-23 11:22:13 -04:00
|
|
|
require "open3"
|
|
|
|
require "timeout"
|
|
|
|
|
2003-10-04 22:56:42 -04:00
|
|
|
module EnvUtil
|
|
|
|
def rubybin
|
2006-02-03 04:15:42 -05:00
|
|
|
unless ENV["RUBYOPT"]
|
2009-03-05 22:56:38 -05:00
|
|
|
|
2006-02-03 04:15:42 -05:00
|
|
|
end
|
2004-05-19 10:45:49 -04:00
|
|
|
if ruby = ENV["RUBY"]
|
|
|
|
return ruby
|
|
|
|
end
|
2005-12-29 03:05:26 -05:00
|
|
|
ruby = "ruby"
|
2006-02-03 04:15:42 -05:00
|
|
|
rubyexe = ruby+".exe"
|
2003-10-13 09:05:24 -04:00
|
|
|
3.times do
|
2006-02-03 04:15:42 -05:00
|
|
|
if File.exist? ruby and File.executable? ruby and !File.directory? ruby
|
|
|
|
return File.expand_path(ruby)
|
|
|
|
end
|
|
|
|
if File.exist? rubyexe and File.executable? rubyexe
|
2008-05-12 08:35:37 -04:00
|
|
|
return File.expand_path(rubyexe)
|
2003-10-13 09:05:24 -04:00
|
|
|
end
|
2005-12-29 03:05:26 -05:00
|
|
|
ruby = File.join("..", ruby)
|
2003-10-13 10:59:25 -04:00
|
|
|
end
|
2010-01-12 02:41:40 -05:00
|
|
|
if defined?(RbConfig.ruby)
|
2009-12-31 10:00:04 -05:00
|
|
|
RbConfig.ruby
|
2010-01-12 02:41:40 -05:00
|
|
|
else
|
2003-10-13 10:59:25 -04:00
|
|
|
"ruby"
|
2003-10-04 22:56:42 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
module_function :rubybin
|
2008-04-23 11:22:13 -04:00
|
|
|
|
|
|
|
LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
|
2009-11-19 17:47:53 -05:00
|
|
|
|
2010-07-01 08:37:58 -04:00
|
|
|
def invoke_ruby(args, stdin_data="", capture_stdout=false, capture_stderr=false, opt={})
|
|
|
|
in_c, in_p = IO.pipe
|
|
|
|
out_p, out_c = IO.pipe if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
err_p, err_c = IO.pipe if capture_stderr && capture_stderr != :merge_to_stdout
|
2010-07-01 08:37:58 -04:00
|
|
|
opt = opt.dup
|
|
|
|
opt[:in] = in_c
|
|
|
|
opt[:out] = out_c if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
opt[:err] = capture_stderr == :merge_to_stdout ? out_c : err_c if capture_stderr
|
2010-07-01 08:37:58 -04:00
|
|
|
if enc = opt.delete(:encoding)
|
|
|
|
out_p.set_encoding(enc) if out_p
|
|
|
|
err_p.set_encoding(enc) if err_p
|
|
|
|
end
|
2011-12-17 19:38:35 -05:00
|
|
|
timeout = opt.delete(:timeout) || 10
|
2012-12-09 09:34:33 -05:00
|
|
|
reprieve = opt.delete(:reprieve) || 1
|
2008-04-23 11:22:13 -04:00
|
|
|
c = "C"
|
2010-07-01 08:37:58 -04:00
|
|
|
child_env = {}
|
|
|
|
LANG_ENVS.each {|lc| child_env[lc] = c}
|
|
|
|
if Array === args and Hash === args.first
|
|
|
|
child_env.update(args.shift)
|
2008-04-23 11:22:13 -04:00
|
|
|
end
|
2010-06-05 09:47:09 -04:00
|
|
|
args = [args] if args.kind_of?(String)
|
2010-07-01 08:37:58 -04:00
|
|
|
pid = spawn(child_env, EnvUtil.rubybin, *args, opt)
|
|
|
|
in_c.close
|
|
|
|
out_c.close if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
err_c.close if capture_stderr && capture_stderr != :merge_to_stdout
|
2010-07-01 08:37:58 -04:00
|
|
|
if block_given?
|
2012-01-31 00:27:27 -05:00
|
|
|
return yield in_p, out_p, err_p, pid
|
2010-07-01 08:37:58 -04:00
|
|
|
else
|
2009-11-19 17:47:53 -05:00
|
|
|
th_stdout = Thread.new { out_p.read } if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
th_stderr = Thread.new { err_p.read } if capture_stderr && capture_stderr != :merge_to_stdout
|
2010-06-24 20:57:03 -04:00
|
|
|
in_p.write stdin_data.to_str
|
|
|
|
in_p.close
|
2010-08-07 06:53:13 -04:00
|
|
|
if (!th_stdout || th_stdout.join(timeout)) && (!th_stderr || th_stderr.join(timeout))
|
2009-11-19 17:47:53 -05:00
|
|
|
stdout = th_stdout.value if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
stderr = th_stderr.value if capture_stderr && capture_stderr != :merge_to_stdout
|
2009-11-19 17:47:53 -05:00
|
|
|
else
|
2012-09-29 07:19:11 -04:00
|
|
|
signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :KILL : :TERM
|
|
|
|
begin
|
|
|
|
Process.kill signal, pid
|
|
|
|
rescue Errno::ESRCH
|
2012-12-09 09:34:33 -05:00
|
|
|
break
|
|
|
|
else
|
|
|
|
end until signal == :KILL or (sleep reprieve; signal = :KILL; false)
|
2009-11-24 08:59:10 -05:00
|
|
|
raise Timeout::Error
|
2009-11-19 17:47:53 -05:00
|
|
|
end
|
|
|
|
out_p.close if capture_stdout
|
2010-08-07 06:53:13 -04:00
|
|
|
err_p.close if capture_stderr && capture_stderr != :merge_to_stdout
|
2009-11-19 17:47:53 -05:00
|
|
|
Process.wait pid
|
|
|
|
status = $?
|
2010-07-01 08:37:58 -04:00
|
|
|
return stdout, stderr, status
|
|
|
|
end
|
|
|
|
ensure
|
2012-09-04 08:45:31 -04:00
|
|
|
[th_stdout, th_stderr].each do |th|
|
|
|
|
th.kill if th
|
|
|
|
end
|
2010-07-01 08:37:58 -04:00
|
|
|
[in_c, in_p, out_c, out_p, err_c, err_p].each do |io|
|
|
|
|
io.close if io && !io.closed?
|
|
|
|
end
|
|
|
|
[th_stdout, th_stderr].each do |th|
|
2012-09-04 08:45:31 -04:00
|
|
|
th.join if th
|
2009-11-19 17:47:53 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
module_function :invoke_ruby
|
2009-09-29 02:26:46 -04:00
|
|
|
|
2010-07-01 08:37:58 -04:00
|
|
|
alias rubyexec invoke_ruby
|
|
|
|
class << self
|
|
|
|
alias rubyexec invoke_ruby
|
|
|
|
end
|
|
|
|
|
2009-09-29 02:26:46 -04:00
|
|
|
def verbose_warning
|
|
|
|
class << (stderr = "")
|
|
|
|
alias write <<
|
|
|
|
end
|
|
|
|
stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
|
|
|
|
yield stderr
|
2012-03-16 04:38:24 -04:00
|
|
|
return $stderr
|
2009-09-29 02:26:46 -04:00
|
|
|
ensure
|
|
|
|
stderr, $stderr, $VERBOSE = $stderr, stderr, verbose
|
|
|
|
end
|
|
|
|
module_function :verbose_warning
|
2010-06-05 21:44:38 -04:00
|
|
|
|
2010-07-24 16:26:34 -04:00
|
|
|
def suppress_warning
|
|
|
|
verbose, $VERBOSE = $VERBOSE, nil
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
$VERBOSE = verbose
|
|
|
|
end
|
|
|
|
module_function :suppress_warning
|
|
|
|
|
2010-06-05 21:44:38 -04:00
|
|
|
def under_gc_stress
|
|
|
|
stress, GC.stress = GC.stress, true
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
GC.stress = stress
|
|
|
|
end
|
|
|
|
module_function :under_gc_stress
|
2003-10-04 22:56:42 -04:00
|
|
|
end
|
2008-05-03 07:57:55 -04:00
|
|
|
|
|
|
|
module Test
|
|
|
|
module Unit
|
|
|
|
module Assertions
|
|
|
|
public
|
2013-01-07 01:29:44 -05:00
|
|
|
def assert_valid_syntax(code, fname = caller_locations(1, 1)[0], mesg = fname.to_s)
|
2012-12-19 21:05:37 -05:00
|
|
|
code = code.dup.force_encoding("ascii-8bit")
|
|
|
|
code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
|
|
|
|
"#$&#{"\n" if $1 && !$2}BEGIN{throw tag, :ok}\n"
|
|
|
|
}
|
|
|
|
code.force_encoding("us-ascii")
|
|
|
|
verbose, $VERBOSE = $VERBOSE, nil
|
|
|
|
yield if defined?(yield)
|
2013-01-07 01:29:44 -05:00
|
|
|
case
|
|
|
|
when Array === fname
|
|
|
|
fname, line = *fname
|
|
|
|
when defined?(fname.path) && defined?(fname.lineno)
|
|
|
|
fname, line = fname.path, fname.lineno
|
|
|
|
else
|
|
|
|
line = 0
|
|
|
|
end
|
2012-12-19 21:05:37 -05:00
|
|
|
assert_nothing_raised(SyntaxError, mesg) do
|
2013-01-07 01:29:44 -05:00
|
|
|
assert_equal(:ok, catch {|tag| eval(code, binding, fname, line)}, mesg)
|
2012-12-19 21:05:37 -05:00
|
|
|
end
|
|
|
|
ensure
|
|
|
|
$VERBOSE = verbose
|
|
|
|
end
|
|
|
|
|
2013-01-07 01:29:48 -05:00
|
|
|
def assert_syntax_error(code, error, fname = caller_locations(1, 1)[0], mesg = fname.to_s)
|
|
|
|
code = code.dup.force_encoding("ascii-8bit")
|
|
|
|
code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
|
|
|
|
"#$&#{"\n" if $1 && !$2}BEGIN{throw tag, :ng}\n"
|
|
|
|
}
|
|
|
|
code.force_encoding("us-ascii")
|
|
|
|
verbose, $VERBOSE = $VERBOSE, nil
|
|
|
|
yield if defined?(yield)
|
|
|
|
case
|
|
|
|
when Array === fname
|
|
|
|
fname, line = *fname
|
|
|
|
when defined?(fname.path) && defined?(fname.lineno)
|
|
|
|
fname, line = fname.path, fname.lineno
|
|
|
|
else
|
|
|
|
line = 0
|
|
|
|
end
|
|
|
|
e = assert_raise(SyntaxError, mesg) do
|
|
|
|
catch {|tag| eval(code, binding, fname, line)}
|
|
|
|
end
|
|
|
|
assert_match(error, e.message, mesg)
|
|
|
|
ensure
|
|
|
|
$VERBOSE = verbose
|
|
|
|
end
|
|
|
|
|
2010-07-01 08:37:58 -04:00
|
|
|
def assert_normal_exit(testsrc, message = '', opt = {})
|
2013-01-07 01:29:44 -05:00
|
|
|
assert_valid_syntax(testsrc, caller_locations(1, 1)[0])
|
2011-09-30 21:00:40 -04:00
|
|
|
if opt.include?(:child_env)
|
|
|
|
opt = opt.dup
|
|
|
|
child_env = [opt.delete(:child_env)] || []
|
|
|
|
else
|
|
|
|
child_env = []
|
|
|
|
end
|
|
|
|
out, _, status = EnvUtil.invoke_ruby(child_env + %W'-W0', testsrc, true, :merge_to_stdout, opt)
|
2013-01-28 03:51:41 -05:00
|
|
|
assert !status.signaled?, FailDesc[status, message, out]
|
|
|
|
end
|
|
|
|
|
|
|
|
FailDesc = proc do |status, message = "", out = ""|
|
2010-07-01 08:37:58 -04:00
|
|
|
pid = status.pid
|
|
|
|
faildesc = proc do
|
2008-05-03 07:57:55 -04:00
|
|
|
signo = status.termsig
|
|
|
|
signame = Signal.list.invert[signo]
|
|
|
|
sigdesc = "signal #{signo}"
|
|
|
|
if signame
|
|
|
|
sigdesc = "SIG#{signame} (#{sigdesc})"
|
|
|
|
end
|
2008-05-31 21:32:54 -04:00
|
|
|
if status.coredump?
|
|
|
|
sigdesc << " (core dumped)"
|
|
|
|
end
|
2009-09-10 08:21:48 -04:00
|
|
|
full_message = ''
|
2013-01-28 03:51:41 -05:00
|
|
|
if message and !message.empty?
|
2009-09-10 08:21:48 -04:00
|
|
|
full_message << message << "\n"
|
|
|
|
end
|
2010-08-07 06:53:13 -04:00
|
|
|
full_message << "pid #{pid} killed by #{sigdesc}"
|
2013-01-28 03:51:41 -05:00
|
|
|
if out and !out.empty?
|
2010-08-07 06:53:13 -04:00
|
|
|
full_message << "\n#{out.gsub(/^/, '| ')}"
|
2013-01-28 03:51:41 -05:00
|
|
|
full_message << "\n" if /\n\z/ !~ full_message
|
2008-05-21 22:40:50 -04:00
|
|
|
end
|
2010-07-01 08:37:58 -04:00
|
|
|
full_message
|
2008-05-03 07:57:55 -04:00
|
|
|
end
|
2013-01-28 03:51:41 -05:00
|
|
|
faildesc
|
2008-05-03 07:57:55 -04:00
|
|
|
end
|
2008-07-15 11:26:04 -04:00
|
|
|
|
2009-11-16 08:45:59 -05:00
|
|
|
def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil, opt={})
|
2009-11-19 17:47:53 -05:00
|
|
|
stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, opt)
|
2009-11-16 08:45:59 -05:00
|
|
|
if block_given?
|
2012-11-30 12:14:27 -05:00
|
|
|
raise "test_stdout ignored, use block only or without block" if test_stdout != []
|
|
|
|
raise "test_stderr ignored, use block only or without block" if test_stderr != []
|
2013-01-04 22:25:44 -05:00
|
|
|
yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp }, status)
|
2009-11-16 08:45:59 -05:00
|
|
|
else
|
2013-01-04 22:25:44 -05:00
|
|
|
errs = []
|
|
|
|
[[test_stdout, stdout], [test_stderr, stderr]].each do |exp, act|
|
|
|
|
begin
|
|
|
|
if exp.is_a?(Regexp)
|
|
|
|
assert_match(exp, act, message)
|
|
|
|
else
|
|
|
|
assert_equal(exp, act.lines.map {|l| l.chomp }, message)
|
|
|
|
end
|
|
|
|
rescue MiniTest::Assertion => e
|
|
|
|
errs << e.message
|
|
|
|
message = nil
|
|
|
|
end
|
2009-11-16 08:45:59 -05:00
|
|
|
end
|
2013-01-04 22:25:44 -05:00
|
|
|
raise MiniTest::Assertion, errs.join("\n---\n") unless errs.empty?
|
2010-06-24 21:07:29 -04:00
|
|
|
status
|
2009-11-16 08:45:59 -05:00
|
|
|
end
|
2009-11-15 12:11:54 -05:00
|
|
|
end
|
|
|
|
|
2009-11-17 08:24:44 -05:00
|
|
|
def assert_ruby_status(args, test_stdin="", message=nil, opt={})
|
2010-07-24 16:26:34 -04:00
|
|
|
_, _, status = EnvUtil.invoke_ruby(args, test_stdin, false, false, opt)
|
2009-12-16 06:29:54 -05:00
|
|
|
m = message ? "#{message} (#{status.inspect})" : "ruby exit status is not success: #{status.inspect}"
|
2009-11-16 08:45:59 -05:00
|
|
|
assert(status.success?, m)
|
2009-11-15 11:24:45 -05:00
|
|
|
end
|
2009-11-15 12:11:54 -05:00
|
|
|
|
2013-02-08 02:08:32 -05:00
|
|
|
ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV")
|
|
|
|
|
2012-12-14 00:59:17 -05:00
|
|
|
def assert_separately(args, file = nil, line = nil, src, **opt)
|
|
|
|
unless file and line
|
|
|
|
loc, = caller_locations(1,1)
|
|
|
|
file ||= loc.path
|
|
|
|
line ||= loc.lineno
|
|
|
|
end
|
2012-12-13 20:38:07 -05:00
|
|
|
src = <<eom
|
|
|
|
require 'test/unit';include Test::Unit::Assertions;begin;#{src}
|
|
|
|
ensure
|
2012-12-14 00:58:41 -05:00
|
|
|
puts [Marshal.dump($!)].pack('m'), "assertions=\#{self._assertions}"
|
2012-12-13 20:38:07 -05:00
|
|
|
end
|
|
|
|
eom
|
2013-02-08 02:08:32 -05:00
|
|
|
stdout, stderr, status = EnvUtil.invoke_ruby(args, src, true, true, opt)
|
|
|
|
abort = status.coredump? || (status.signaled? && ABORT_SIGNALS.include?(status.termsig))
|
|
|
|
assert(!abort, FailDesc[status, stderr])
|
2012-12-14 00:58:41 -05:00
|
|
|
self._assertions += stdout[/^assertions=(\d+)/, 1].to_i
|
2012-12-13 20:38:07 -05:00
|
|
|
res = Marshal.load(stdout.unpack("m")[0])
|
|
|
|
return unless res
|
|
|
|
res.backtrace.each do |l|
|
|
|
|
l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"}
|
|
|
|
end
|
|
|
|
raise res
|
|
|
|
end
|
|
|
|
|
2012-11-24 12:14:06 -05:00
|
|
|
def assert_warning(pat, message = nil)
|
2010-11-17 02:08:07 -05:00
|
|
|
stderr = EnvUtil.verbose_warning { yield }
|
2012-03-13 00:03:03 -04:00
|
|
|
message = ' "' + message + '"' if message
|
|
|
|
msg = proc {"warning message #{stderr.inspect} is expected to match #{pat.inspect}#{message}"}
|
|
|
|
assert(pat === stderr, msg)
|
2012-03-12 23:34:11 -04:00
|
|
|
end
|
|
|
|
|
2012-11-24 12:14:06 -05:00
|
|
|
def assert_warn(*args)
|
|
|
|
assert_warning(*args) {$VERBOSE = false; yield}
|
2010-11-17 02:08:07 -05:00
|
|
|
end
|
|
|
|
|
2012-02-09 10:47:11 -05:00
|
|
|
def assert_no_memory_leak(args, prepare, code, message=nil, limit: 1.5)
|
|
|
|
token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m"
|
|
|
|
token_dump = token.dump
|
|
|
|
token_re = Regexp.quote(token)
|
|
|
|
args = [
|
|
|
|
"--disable=gems",
|
|
|
|
"-r", File.expand_path("../memory_status", __FILE__),
|
|
|
|
*args,
|
|
|
|
"-v", "-",
|
|
|
|
]
|
|
|
|
cmd = [
|
2012-10-25 10:06:31 -04:00
|
|
|
'END {STDERR.puts '"#{token_dump}"'"FINAL=#{Memory::Status.new.size}"}',
|
2012-02-09 10:47:11 -05:00
|
|
|
prepare,
|
2012-10-25 10:06:31 -04:00
|
|
|
'STDERR.puts('"#{token_dump}"'"START=#{$initial_size = Memory::Status.new.size}")',
|
2012-02-09 10:47:11 -05:00
|
|
|
code,
|
|
|
|
].join("\n")
|
2012-03-16 04:38:22 -04:00
|
|
|
_, err, status = EnvUtil.invoke_ruby(args, cmd, true, true)
|
2012-02-09 10:47:11 -05:00
|
|
|
before = err.sub!(/^#{token_re}START=(\d+)\n/, '') && $1.to_i
|
|
|
|
after = err.sub!(/^#{token_re}FINAL=(\d+)\n/, '') && $1.to_i
|
|
|
|
assert_equal([true, ""], [status.success?, err], message)
|
|
|
|
assert_operator(after.fdiv(before), :<, limit, message)
|
|
|
|
end
|
2012-03-14 02:10:01 -04:00
|
|
|
|
|
|
|
def assert_is_minus_zero(f)
|
|
|
|
assert(1.0/f == -Float::INFINITY, "#{f} is not -0.0")
|
|
|
|
end
|
2012-10-09 10:18:05 -04:00
|
|
|
|
2012-10-16 00:02:04 -04:00
|
|
|
def assert_file
|
|
|
|
AssertFile
|
2012-10-09 10:18:05 -04:00
|
|
|
end
|
|
|
|
|
2013-02-25 09:59:21 -05:00
|
|
|
class << (AssertFile = Struct.new(:failure_message).new)
|
2012-10-15 09:14:48 -04:00
|
|
|
include Assertions
|
|
|
|
def assert_file_predicate(predicate, *args)
|
|
|
|
if /\Anot_/ =~ predicate
|
|
|
|
predicate = $'
|
|
|
|
neg = " not"
|
|
|
|
end
|
|
|
|
result = File.__send__(predicate, *args)
|
|
|
|
result = !result if neg
|
|
|
|
mesg = "Expected file " << args.shift.inspect
|
|
|
|
mesg << mu_pp(args) unless args.empty?
|
|
|
|
mesg << "#{neg} to be #{predicate}"
|
2013-02-25 09:59:21 -05:00
|
|
|
mesg << " #{failure_message}" if failure_message
|
2012-10-15 09:14:48 -04:00
|
|
|
assert(result, mesg)
|
|
|
|
end
|
|
|
|
alias method_missing assert_file_predicate
|
2012-11-03 21:19:11 -04:00
|
|
|
|
|
|
|
def for(message)
|
2013-02-25 09:59:21 -05:00
|
|
|
clone.tap {|a| a.failure_message = message}
|
2012-11-03 21:19:11 -04:00
|
|
|
end
|
2012-10-09 10:18:05 -04:00
|
|
|
end
|
2008-05-03 07:57:55 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-01-12 02:41:40 -05:00
|
|
|
begin
|
|
|
|
require 'rbconfig'
|
|
|
|
rescue LoadError
|
|
|
|
else
|
|
|
|
module RbConfig
|
|
|
|
@ruby = EnvUtil.rubybin
|
|
|
|
class << self
|
2010-01-25 08:33:02 -05:00
|
|
|
undef ruby if method_defined?(:ruby)
|
2010-01-12 02:41:40 -05:00
|
|
|
attr_reader :ruby
|
|
|
|
end
|
|
|
|
dir = File.dirname(ruby)
|
|
|
|
name = File.basename(ruby, CONFIG['EXEEXT'])
|
|
|
|
CONFIG['bindir'] = dir
|
|
|
|
CONFIG['ruby_install_name'] = name
|
|
|
|
CONFIG['RUBY_INSTALL_NAME'] = name
|
2011-02-10 22:03:26 -05:00
|
|
|
Gem::ConfigMap[:bindir] = dir if defined?(Gem::ConfigMap)
|
2010-01-12 02:41:40 -05:00
|
|
|
end
|
|
|
|
end
|