1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#!/usr/bin/env ruby
# usage: ruby install.rb [-n]
# options:
# -n : don't install
#
# Author: Tanaka Akira <akr@m17n.org>
require 'optparse'
require 'fileutils'
def target_directory
$:.each {|loc|
if %r{/site_ruby/[\d.]+\z} =~ loc
return loc
end
}
raise "could not find target install directory"
end
CVS_FILES = {}
def cvs_files(dir)
return CVS_FILES[dir] if CVS_FILES.include? dir
if File.directory? "#{dir}/CVS"
result = {}
File.foreach("#{dir}/CVS/Entries") {|line|
case line
when %r{\A/([^/]+)/} then result[$1] = true
when %r{\AD/([^/]+)/} then result[$1] = true
end
}
else
result = nil
end
CVS_FILES[dir] = result
result
end
def each_target(&block)
target_set = {}
cvs = cvs_files('.')
Dir.glob("*.rb") {|filename|
next if /\Atest-/ =~ filename
next if /\Ainstall/ =~ filename
next if cvs && !cvs.include?(filename)
target_set[filename] = true
yield filename
each_require(filename, target_set, &block)
}
end
def each_require(file, target_set, &block)
File.foreach(file) {|line|
next if /\A\s*require\s+['"]([^'"]+)['"]/ !~ line
feature = $1
filename = "#{feature}.rb"
next if target_set.include? filename
next if !File.exist?(filename)
target_set[filename] = true
yield filename
each_require(filename, target_set, &block)
}
end
def collect_target
result = []
each_target {|filename| result << filename }
result.sort!
result
end
def install_file(src, dst)
ignore_exc(Errno::ENOENT) { return if FileUtils.compare_file src, dst }
# check shadow
ignore_exc(Errno::ENOENT) { File.unlink dst }
FileUtils.mkdir_p(File.dirname(dst), :mode=>0755)
FileUtils.cp(src, dst, :verbose => true)
File.chmod(0644, dst)
end
def ignore_exc(exc)
begin
yield
rescue exc
end
end
$opt_n = false
ARGV.options {|q|
q.banner = 'ruby install.rb [opts]'
q.def_option('--help', 'show this message') {puts q; exit(0)}
q.def_option('-n', "don't install") { $opt_n = true }
q.parse!
}
if $opt_n
dir = target_directory
collect_target.each {|filename|
puts "-> #{dir}/#{filename}"
}
exit
else
File.umask 022
dir = target_directory
collect_target.each {|filename|
install_file filename, "#{dir}/#{filename}"
}
end
|