| 1 | # |
|---|
| 2 | # This file is automatically generated. DO NOT MODIFY! |
|---|
| 3 | # |
|---|
| 4 | # install.rb |
|---|
| 5 | # |
|---|
| 6 | # Copyright (c) 2000-2002 Minero Aoki <aamine@loveruby.net> |
|---|
| 7 | # |
|---|
| 8 | # This program is free software. |
|---|
| 9 | # You can distribute/modify this program under the terms of |
|---|
| 10 | # the GNU Lesser General Public License version 2. |
|---|
| 11 | # |
|---|
| 12 | |
|---|
| 13 | ### begin compat.rb |
|---|
| 14 | |
|---|
| 15 | unless Enumerable.instance_methods.include? 'inject' |
|---|
| 16 | module Enumerable |
|---|
| 17 | def inject( result ) |
|---|
| 18 | each do |i| |
|---|
| 19 | result = yield(result, i) |
|---|
| 20 | end |
|---|
| 21 | result |
|---|
| 22 | end |
|---|
| 23 | end |
|---|
| 24 | end |
|---|
| 25 | |
|---|
| 26 | def File.read_all( fname ) |
|---|
| 27 | File.open(fname, 'rb') {|f| return f.read } |
|---|
| 28 | end |
|---|
| 29 | |
|---|
| 30 | def File.write( fname, str ) |
|---|
| 31 | File.open(fname, 'wb') {|f| f.write str } |
|---|
| 32 | end |
|---|
| 33 | |
|---|
| 34 | ### end compat.rb |
|---|
| 35 | ### begin config.rb |
|---|
| 36 | |
|---|
| 37 | if i = ARGV.index(/\A--rbconfig=/) |
|---|
| 38 | file = $' |
|---|
| 39 | ARGV.delete_at(i) |
|---|
| 40 | require file |
|---|
| 41 | else |
|---|
| 42 | require 'rbconfig' |
|---|
| 43 | end |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | class ConfigTable |
|---|
| 47 | |
|---|
| 48 | c = ::Config::CONFIG |
|---|
| 49 | |
|---|
| 50 | rubypath = c['bindir'] + '/' + c['ruby_install_name'] |
|---|
| 51 | |
|---|
| 52 | major = c['MAJOR'].to_i |
|---|
| 53 | minor = c['MINOR'].to_i |
|---|
| 54 | teeny = c['TEENY'].to_i |
|---|
| 55 | version = "#{major}.#{minor}" |
|---|
| 56 | |
|---|
| 57 | # ruby ver. >= 1.4.4? |
|---|
| 58 | newpath_p = ((major >= 2) or |
|---|
| 59 | ((major == 1) and |
|---|
| 60 | ((minor >= 5) or |
|---|
| 61 | ((minor == 4) and (teeny >= 4))))) |
|---|
| 62 | |
|---|
| 63 | re = Regexp.new('\A' + Regexp.quote(c['prefix'])) |
|---|
| 64 | subprefix = lambda {|path| |
|---|
| 65 | re === path and path.sub(re, '$prefix') |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | if c['rubylibdir'] |
|---|
| 69 | # V < 1.6.3 |
|---|
| 70 | stdruby = subprefix.call(c['rubylibdir']) |
|---|
| 71 | siteruby = subprefix.call(c['sitedir']) |
|---|
| 72 | versite = subprefix.call(c['sitelibdir']) |
|---|
| 73 | sodir = subprefix.call(c['sitearchdir']) |
|---|
| 74 | elsif newpath_p |
|---|
| 75 | # 1.4.4 <= V <= 1.6.3 |
|---|
| 76 | stdruby = "$prefix/lib/ruby/#{version}" |
|---|
| 77 | siteruby = subprefix.call(c['sitedir']) |
|---|
| 78 | versite = siteruby + '/' + version |
|---|
| 79 | sodir = "$site-ruby/#{c['arch']}" |
|---|
| 80 | else |
|---|
| 81 | # V < 1.4.4 |
|---|
| 82 | stdruby = "$prefix/lib/ruby/#{version}" |
|---|
| 83 | siteruby = "$prefix/lib/ruby/#{version}/site_ruby" |
|---|
| 84 | versite = siteruby |
|---|
| 85 | sodir = "$site-ruby/#{c['arch']}" |
|---|
| 86 | end |
|---|
| 87 | |
|---|
| 88 | DESCRIPTER = [ |
|---|
| 89 | [ 'prefix', [ c['prefix'], |
|---|
| 90 | 'path', |
|---|
| 91 | 'path prefix of target environment' ] ], |
|---|
| 92 | [ 'std-ruby', [ stdruby, |
|---|
| 93 | 'path', |
|---|
| 94 | 'the directory for standard ruby libraries' ] ], |
|---|
| 95 | [ 'site-ruby-common', [ siteruby, |
|---|
| 96 | 'path', |
|---|
| 97 | 'the directory for version-independent non-standard ruby libraries' ] ], |
|---|
| 98 | [ 'site-ruby', [ versite, |
|---|
| 99 | 'path', |
|---|
| 100 | 'the directory for non-standard ruby libraries' ] ], |
|---|
| 101 | [ 'bin-dir', [ '$prefix/bin', |
|---|
| 102 | 'path', |
|---|
| 103 | 'the directory for commands' ] ], |
|---|
| 104 | [ 'rb-dir', [ '$site-ruby', |
|---|
| 105 | 'path', |
|---|
| 106 | 'the directory for ruby scripts' ] ], |
|---|
| 107 | [ 'so-dir', [ sodir, |
|---|
| 108 | 'path', |
|---|
| 109 | 'the directory for ruby extentions' ] ], |
|---|
| 110 | [ 'data-dir', [ '$prefix/share', |
|---|
| 111 | 'path', |
|---|
| 112 | 'the directory for shared data' ] ], |
|---|
| 113 | [ 'ruby-path', [ rubypath, |
|---|
| 114 | 'path', |
|---|
| 115 | 'path to set to #! line' ] ], |
|---|
| 116 | [ 'ruby-prog', [ rubypath, |
|---|
| 117 | 'name', |
|---|
| 118 | 'the ruby program using for installation' ] ], |
|---|
| 119 | [ 'make-prog', [ 'make', |
|---|
| 120 | 'name', |
|---|
| 121 | 'the make program to compile ruby extentions' ] ], |
|---|
| 122 | [ 'without-ext', [ 'no', |
|---|
| 123 | 'yes/no', |
|---|
| 124 | 'does not compile/install ruby extentions' ] ] |
|---|
| 125 | ] |
|---|
| 126 | |
|---|
| 127 | SAVE_FILE = 'config.save' |
|---|
| 128 | |
|---|
| 129 | def ConfigTable.each_name( &block ) |
|---|
| 130 | keys().each(&block) |
|---|
| 131 | end |
|---|
| 132 | |
|---|
| 133 | def ConfigTable.keys |
|---|
| 134 | DESCRIPTER.collect {|k,*dummy| k } |
|---|
| 135 | end |
|---|
| 136 | |
|---|
| 137 | def ConfigTable.each_definition( &block ) |
|---|
| 138 | DESCRIPTER.each(&block) |
|---|
| 139 | end |
|---|
| 140 | |
|---|
| 141 | def ConfigTable.get_entry( name ) |
|---|
| 142 | name, ent = DESCRIPTER.assoc(name) |
|---|
| 143 | ent |
|---|
| 144 | end |
|---|
| 145 | |
|---|
| 146 | def ConfigTable.get_entry!( name ) |
|---|
| 147 | get_entry(name) or raise ArgumentError, "no such config: #{name}" |
|---|
| 148 | end |
|---|
| 149 | |
|---|
| 150 | def ConfigTable.add_entry( name, vals ) |
|---|
| 151 | ConfigTable::DESCRIPTER.push [name,vals] |
|---|
| 152 | end |
|---|
| 153 | |
|---|
| 154 | def ConfigTable.remove_entry( name ) |
|---|
| 155 | get_entry name or raise ArgumentError, "no such config: #{name}" |
|---|
| 156 | DESCRIPTER.delete_if {|n,arr| n == name } |
|---|
| 157 | end |
|---|
| 158 | |
|---|
| 159 | def ConfigTable.config_key?( name ) |
|---|
| 160 | get_entry(name) ? true : false |
|---|
| 161 | end |
|---|
| 162 | |
|---|
| 163 | def ConfigTable.bool_config?( name ) |
|---|
| 164 | ent = get_entry(name) or return false |
|---|
| 165 | ent[1] == 'yes/no' |
|---|
| 166 | end |
|---|
| 167 | |
|---|
| 168 | def ConfigTable.value_config?( name ) |
|---|
| 169 | ent = get_entry(name) or return false |
|---|
| 170 | ent[1] != 'yes/no' |
|---|
| 171 | end |
|---|
| 172 | |
|---|
| 173 | def ConfigTable.path_config?( name ) |
|---|
| 174 | ent = get_entry(name) or return false |
|---|
| 175 | ent[1] == 'path' |
|---|
| 176 | end |
|---|
| 177 | |
|---|
| 178 | |
|---|
| 179 | class << self |
|---|
| 180 | |
|---|
| 181 | alias newobj new |
|---|
| 182 | |
|---|
| 183 | def new |
|---|
| 184 | c = newobj() |
|---|
| 185 | c.__send__ :init |
|---|
| 186 | c |
|---|
| 187 | end |
|---|
| 188 | |
|---|
| 189 | def load |
|---|
| 190 | c = newobj() |
|---|
| 191 | raise InstallError, "#{File.basename $0} config first"\ |
|---|
| 192 | unless File.file? SAVE_FILE |
|---|
| 193 | File.foreach(SAVE_FILE) do |line| |
|---|
| 194 | k, v = line.split(/=/, 2) |
|---|
| 195 | c.instance_eval { |
|---|
| 196 | @table[k] = v.strip |
|---|
| 197 | } |
|---|
| 198 | end |
|---|
| 199 | c |
|---|
| 200 | end |
|---|
| 201 | |
|---|
| 202 | end |
|---|
| 203 | |
|---|
| 204 | def initialize |
|---|
| 205 | @table = {} |
|---|
| 206 | end |
|---|
| 207 | |
|---|
| 208 | def init |
|---|
| 209 | DESCRIPTER.each do |k, (default, vname, desc, default2)| |
|---|
| 210 | @table[k] = default |
|---|
| 211 | end |
|---|
| 212 | end |
|---|
| 213 | private :init |
|---|
| 214 | |
|---|
| 215 | def save |
|---|
| 216 | File.open(SAVE_FILE, 'w') {|f| |
|---|
| 217 | @table.each do |k, v| |
|---|
| 218 | f.printf "%s=%s\n", k, v if v |
|---|
| 219 | end |
|---|
| 220 | } |
|---|
| 221 | end |
|---|
| 222 | |
|---|
| 223 | def []=( k, v ) |
|---|
| 224 | ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}" |
|---|
| 225 | if ConfigTable.path_config? k |
|---|
| 226 | @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v |
|---|
| 227 | else |
|---|
| 228 | @table[k] = v |
|---|
| 229 | end |
|---|
| 230 | end |
|---|
| 231 | |
|---|
| 232 | def []( key ) |
|---|
| 233 | @table[key] or return nil |
|---|
| 234 | @table[key].gsub(%r<\$([^/]+)>) { self[$1] } |
|---|
| 235 | end |
|---|
| 236 | |
|---|
| 237 | def set_raw( key, val ) |
|---|
| 238 | @table[key] = val |
|---|
| 239 | end |
|---|
| 240 | |
|---|
| 241 | def get_raw( key ) |
|---|
| 242 | @table[key] |
|---|
| 243 | end |
|---|
| 244 | |
|---|
| 245 | end |
|---|
| 246 | |
|---|
| 247 | |
|---|
| 248 | class MetaConfigEnvironment |
|---|
| 249 | |
|---|
| 250 | def self.eval_file( file ) |
|---|
| 251 | return unless File.file? file |
|---|
| 252 | new.instance_eval File.read_all(file), file, 1 |
|---|
| 253 | end |
|---|
| 254 | |
|---|
| 255 | private |
|---|
| 256 | |
|---|
| 257 | def config_names |
|---|
| 258 | ConfigTable.keys |
|---|
| 259 | end |
|---|
| 260 | |
|---|
| 261 | def config?( name ) |
|---|
| 262 | ConfigTable.config_key? name |
|---|
| 263 | end |
|---|
| 264 | |
|---|
| 265 | def bool_config?( name ) |
|---|
| 266 | ConfigTable.bool_config? name |
|---|
| 267 | end |
|---|
| 268 | |
|---|
| 269 | def value_config?( name ) |
|---|
| 270 | ConfigTable.value_config? name |
|---|
| 271 | end |
|---|
| 272 | |
|---|
| 273 | def path_config?( name ) |
|---|
| 274 | ConfigTable.path_config? name |
|---|
| 275 | end |
|---|
| 276 | |
|---|
| 277 | def add_config( name, argname, default, desc ) |
|---|
| 278 | ConfigTable.add_entry name,[default,argname,desc] |
|---|
| 279 | end |
|---|
| 280 | |
|---|
| 281 | def add_path_config( name, default, desc ) |
|---|
| 282 | add_config name, 'path', default, desc |
|---|
| 283 | end |
|---|
| 284 | |
|---|
| 285 | def add_bool_config( name, default, desc ) |
|---|
| 286 | add_config name, 'yes/no', default ? 'yes' : 'no', desc |
|---|
| 287 | end |
|---|
| 288 | |
|---|
| 289 | def set_config_default( name, default ) |
|---|
| 290 | if bool_config? name |
|---|
| 291 | ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no' |
|---|
| 292 | else |
|---|
| 293 | ConfigTable.get_entry!(name)[0] = default |
|---|
| 294 | end |
|---|
| 295 | end |
|---|
| 296 | |
|---|
| 297 | def remove_config( name ) |
|---|
| 298 | ent = ConfigTable.get_entry(name) |
|---|
| 299 | ConfigTable.remove_entry name |
|---|
| 300 | ent |
|---|
| 301 | end |
|---|
| 302 | |
|---|
| 303 | end |
|---|
| 304 | |
|---|
| 305 | ### end config.rb |
|---|
| 306 | ### begin fileop.rb |
|---|
| 307 | |
|---|
| 308 | module FileOperations |
|---|
| 309 | |
|---|
| 310 | def mkdir_p( dname, prefix = nil ) |
|---|
| 311 | dname = prefix + dname if prefix |
|---|
| 312 | $stderr.puts "mkdir -p #{dname}" if verbose? |
|---|
| 313 | return if no_harm? |
|---|
| 314 | |
|---|
| 315 | # does not check '/'... it's too abnormal case |
|---|
| 316 | dirs = dname.split(%r<(?=/)>) |
|---|
| 317 | if /\A[a-z]:\z/i === dirs[0] |
|---|
| 318 | disk = dirs.shift |
|---|
| 319 | dirs[0] = disk + dirs[0] |
|---|
| 320 | end |
|---|
| 321 | dirs.each_index do |idx| |
|---|
| 322 | path = dirs[0..idx].join('') |
|---|
| 323 | Dir.mkdir path unless dir? path |
|---|
| 324 | end |
|---|
| 325 | end |
|---|
| 326 | |
|---|
| 327 | def rm_f( fname ) |
|---|
| 328 | $stderr.puts "rm -f #{fname}" if verbose? |
|---|
| 329 | return if no_harm? |
|---|
| 330 | |
|---|
| 331 | if File.exist? fname or File.symlink? fname |
|---|
| 332 | File.chmod 0777, fname |
|---|
| 333 | File.unlink fname |
|---|
| 334 | end |
|---|
| 335 | end |
|---|
| 336 | |
|---|
| 337 | def rm_rf( dn ) |
|---|
| 338 | $stderr.puts "rm -rf #{dn}" if verbose? |
|---|
| 339 | return if no_harm? |
|---|
| 340 | |
|---|
| 341 | Dir.chdir dn |
|---|
| 342 | Dir.foreach('.') do |fn| |
|---|
| 343 | next if fn == '.' |
|---|
| 344 | next if fn == '..' |
|---|
| 345 | if dir? fn |
|---|
| 346 | verbose_off { |
|---|
| 347 | rm_rf fn |
|---|
| 348 | } |
|---|
| 349 | else |
|---|
| 350 | verbose_off { |
|---|
| 351 | rm_f fn |
|---|
| 352 | } |
|---|
| 353 | end |
|---|
| 354 | end |
|---|
| 355 | Dir.chdir '..' |
|---|
| 356 | Dir.rmdir dn |
|---|
| 357 | end |
|---|
| 358 | |
|---|
| 359 | def mv( src, dest ) |
|---|
| 360 | rm_f dest |
|---|
| 361 | begin |
|---|
| 362 | File.link src, dest |
|---|
| 363 | rescue |
|---|
| 364 | File.write dest, File.read_all(src) |
|---|
| 365 | File.chmod File.stat(src).mode, dest |
|---|
| 366 | end |
|---|
| 367 | rm_f src |
|---|
| 368 | end |
|---|
| 369 | |
|---|
| 370 | def install( from, dest, mode, prefix = nil ) |
|---|
| 371 | $stderr.puts "install #{from} #{dest}" if verbose? |
|---|
| 372 | return if no_harm? |
|---|
| 373 | |
|---|
| 374 | realdest = prefix + dest if prefix |
|---|
| 375 | if dir? realdest |
|---|
| 376 | realdest += '/' + File.basename(from) |
|---|
| 377 | end |
|---|
| 378 | str = File.read_all(from) |
|---|
| 379 | if diff? str, realdest |
|---|
| 380 | verbose_off { |
|---|
| 381 | rm_f realdest if File.exist? realdest |
|---|
| 382 | } |
|---|
| 383 | File.write realdest, str |
|---|
| 384 | File.chmod mode, realdest |
|---|
| 385 | |
|---|
| 386 | File.open(objdir + '/InstalledFiles', 'a') {|f| f.puts realdest } |
|---|
| 387 | end |
|---|
| 388 | end |
|---|
| 389 | |
|---|
| 390 | def diff?( orig, targ ) |
|---|
| 391 | return true unless File.exist? targ |
|---|
| 392 | orig != File.read_all(targ) |
|---|
| 393 | end |
|---|
| 394 | |
|---|
| 395 | def command( str ) |
|---|
| 396 | $stderr.puts str if verbose? |
|---|
| 397 | system str or raise RuntimeError, "'system #{str}' failed" |
|---|
| 398 | end |
|---|
| 399 | |
|---|
| 400 | def ruby( str ) |
|---|
| 401 | command config('ruby-prog') + ' ' + str |
|---|
| 402 | end |
|---|
| 403 | |
|---|
| 404 | def dir?( dname ) |
|---|
| 405 | # for corrupted windows stat() |
|---|
| 406 | File.directory?((dname[-1,1] == '/') ? dname : dname + '/') |
|---|
| 407 | end |
|---|
| 408 | |
|---|
| 409 | def all_files( dname ) |
|---|
| 410 | Dir.open(dname) {|d| |
|---|
| 411 | return d.find_all {|n| File.file? "#{dname}/#{n}" } |
|---|
| 412 | } |
|---|
| 413 | end |
|---|
| 414 | |
|---|
| 415 | def all_dirs( dname ) |
|---|
| 416 | Dir.open(dname) {|d| |
|---|
| 417 | return d.find_all {|n| dir? "#{dname}/#{n}" } - %w(. ..) |
|---|
| 418 | } |
|---|
| 419 | end |
|---|
| 420 | |
|---|
| 421 | end |
|---|
| 422 | |
|---|
| 423 | ### end fileop.rb |
|---|
| 424 | ### begin base.rb |
|---|
| 425 | |
|---|
| 426 | class InstallError < StandardError; end |
|---|
| 427 | |
|---|
| 428 | |
|---|
| 429 | class Installer |
|---|
| 430 | |
|---|
| 431 | Version = '3.1.3' |
|---|
| 432 | Copyright = 'Copyright (c) 2000-2002 Minero Aoki' |
|---|
| 433 | |
|---|
| 434 | |
|---|
| 435 | @toplevel = nil |
|---|
| 436 | |
|---|
| 437 | def self.declear_toplevel_installer( inst ) |
|---|
| 438 | @toplevel and |
|---|
| 439 | raise ArgumentError, 'more than one toplevel installer decleared' |
|---|
| 440 | @toplevel = inst |
|---|
| 441 | end |
|---|
| 442 | |
|---|
| 443 | def self.toplevel_installer |
|---|
| 444 | @toplevel |
|---|
| 445 | end |
|---|
| 446 | |
|---|
| 447 | |
|---|
| 448 | FILETYPES = %w( bin lib ext data ) |
|---|
| 449 | |
|---|
| 450 | include FileOperations |
|---|
| 451 | |
|---|
| 452 | def initialize( config, opt, srcroot, objroot ) |
|---|
| 453 | @config = config |
|---|
| 454 | @options = opt |
|---|
| 455 | @srcdir = File.expand_path(srcroot) |
|---|
| 456 | @objdir = File.expand_path(objroot) |
|---|
| 457 | @currdir = '.' |
|---|
| 458 | end |
|---|
| 459 | |
|---|
| 460 | def inspect |
|---|
| 461 | "#<#{self.class} #{__id__}>" |
|---|
| 462 | end |
|---|
| 463 | |
|---|
| 464 | # |
|---|
| 465 | # configs/options |
|---|
| 466 | # |
|---|
| 467 | |
|---|
| 468 | def get_config( key ) |
|---|
| 469 | @config[key] |
|---|
| 470 | end |
|---|
| 471 | |
|---|
| 472 | alias config get_config |
|---|
| 473 | |
|---|
| 474 | def set_config( key, val ) |
|---|
| 475 | @config[key] = val |
|---|
| 476 | end |
|---|
| 477 | |
|---|
| 478 | def no_harm? |
|---|
| 479 | @options['no-harm'] |
|---|
| 480 | end |
|---|
| 481 | |
|---|
| 482 | def verbose? |
|---|
| 483 | @options['verbose'] |
|---|
| 484 | end |
|---|
| 485 | |
|---|
| 486 | def verbose_off |
|---|
| 487 | save, @options['verbose'] = @options['verbose'], false |
|---|
| 488 | yield |
|---|
| 489 | @options['verbose'] = save |
|---|
| 490 | end |
|---|
| 491 | |
|---|
| 492 | # |
|---|
| 493 | # srcdir/objdir |
|---|
| 494 | # |
|---|
| 495 | |
|---|
| 496 | attr_reader :srcdir |
|---|
| 497 | alias srcdir_root srcdir |
|---|
| 498 | alias package_root srcdir |
|---|
| 499 | |
|---|
| 500 | def curr_srcdir |
|---|
| 501 | "#{@srcdir}/#{@currdir}" |
|---|
| 502 | end |
|---|
| 503 | |
|---|
| 504 | attr_reader :objdir |
|---|
| 505 | alias objdir_root objdir |
|---|
| 506 | |
|---|
| 507 | def curr_objdir |
|---|
| 508 | "#{@objdir}/#{@currdir}" |
|---|
| 509 | end |
|---|
| 510 | |
|---|
| 511 | def srcfile( path ) |
|---|
| 512 | curr_srcdir + '/' + path |
|---|
| 513 | end |
|---|
| 514 | |
|---|
| 515 | def srcexist?( path ) |
|---|
| 516 | File.exist? srcfile(path) |
|---|
| 517 | end |
|---|
| 518 | |
|---|
| 519 | def srcdirectory?( path ) |
|---|
| 520 | dir? srcfile(path) |
|---|
| 521 | end |
|---|
| 522 | |
|---|
| 523 | def srcfile?( path ) |
|---|
| 524 | File.file? srcfile(path) |
|---|
| 525 | end |
|---|
| 526 | |
|---|
| 527 | def srcentries( path = '.' ) |
|---|
| 528 | Dir.open(curr_srcdir + '/' + path) {|d| |
|---|
| 529 | return d.to_a - %w(. ..) - hookfilenames |
|---|
| 530 | } |
|---|
| 531 | end |
|---|
| 532 | |
|---|
| 533 | def srcfiles( path = '.' ) |
|---|
| 534 | srcentries(path).find_all {|fname| |
|---|
| 535 | File.file? File.join(curr_srcdir, path, fname) |
|---|
| 536 | } |
|---|
| 537 | end |
|---|
| 538 | |
|---|
| 539 | def srcdirectories( path = '.' ) |
|---|
| 540 | srcentries(path).find_all {|fname| |
|---|
| 541 | dir? File.join(curr_srcdir, path, fname) |
|---|
| 542 | } |
|---|
| 543 | end |
|---|
| 544 | |
|---|
| 545 | def dive_into( rel ) |
|---|
| 546 | return unless dir? "#{@srcdir}/#{rel}" |
|---|
| 547 | |
|---|
| 548 | dir = File.basename(rel) |
|---|
| 549 | Dir.mkdir dir unless dir? dir |
|---|
| 550 | save = Dir.pwd |
|---|
| 551 | Dir.chdir dir |
|---|
| 552 | $stderr.puts '---> ' + rel if verbose? |
|---|
| 553 | @currdir = rel |
|---|
| 554 | yield |
|---|
| 555 | Dir.chdir save |
|---|
| 556 | $stderr.puts '<--- ' + rel if verbose? |
|---|
| 557 | @currdir = File.dirname(rel) |
|---|
| 558 | end |
|---|
| 559 | |
|---|
| 560 | # |
|---|
| 561 | # config |
|---|
| 562 | # |
|---|
| 563 | |
|---|
| 564 | def exec_config |
|---|
| 565 | exec_task_traverse 'config' |
|---|
| 566 | end |
|---|
| 567 | |
|---|
| 568 | def config_dir_bin( rel ) |
|---|
| 569 | end |
|---|
| 570 | |
|---|
| 571 | def config_dir_lib( rel ) |
|---|
| 572 | end |
|---|
| 573 | |
|---|
| 574 | def config_dir_ext( rel ) |
|---|
| 575 | extconf if extdir? curr_srcdir |
|---|
| 576 | end |
|---|
| 577 | |
|---|
| 578 | def extconf |
|---|
| 579 | opt = @options['config-opt'].join(' ') |
|---|
| 580 | command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}" |
|---|
| 581 | end |
|---|
| 582 | |
|---|
| 583 | def config_dir_data( rel ) |
|---|
| 584 | end |
|---|
| 585 | |
|---|
| 586 | # |
|---|
| 587 | # setup |
|---|
| 588 | # |
|---|
| 589 | |
|---|
| 590 | def exec_setup |
|---|
| 591 | exec_task_traverse 'setup' |
|---|
| 592 | end |
|---|
| 593 | |
|---|
| 594 | def setup_dir_bin( relpath ) |
|---|
| 595 | all_files(curr_srcdir).each do |fname| |
|---|
| 596 | add_rubypath "#{curr_srcdir}/#{fname}" |
|---|
| 597 | end |
|---|
| 598 | end |
|---|
| 599 | |
|---|
| 600 | SHEBANG_RE = /\A\#!\s*\S*ruby\S*/ |
|---|
| 601 | |
|---|
| 602 | def add_rubypath( path ) |
|---|
| 603 | $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose? |
|---|
| 604 | return if no_harm? |
|---|
| 605 | |
|---|
| 606 | tmpfile = File.basename(path) + '.tmp' |
|---|
| 607 | begin |
|---|
| 608 | File.open(path) {|r| |
|---|
| 609 | File.open(tmpfile, 'w') {|w| |
|---|
| 610 | first = r.gets |
|---|
| 611 | return unless SHEBANG_RE === first # reject '/usr/bin/env ruby' |
|---|
| 612 | |
|---|
| 613 | w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path')) |
|---|
| 614 | w.write r.read |
|---|
| 615 | } } |
|---|
| 616 | mv tmpfile, File.basename(path) |
|---|
| 617 | ensure |
|---|
| 618 | rm_f tmpfile if File.exist? tmpfile |
|---|
| 619 | end |
|---|
| 620 | end |
|---|
| 621 | |
|---|
| 622 | def setup_dir_lib( relpath ) |
|---|
| 623 | end |
|---|
| 624 | |
|---|
| 625 | def setup_dir_ext( relpath ) |
|---|
| 626 | make if extdir?(curr_srcdir) |
|---|
| 627 | end |
|---|
| 628 | |
|---|
| 629 | def make |
|---|
| 630 | command config('make-prog') |
|---|
| 631 | end |
|---|
| 632 | |
|---|
| 633 | def setup_dir_data( relpath ) |
|---|
| 634 | end |
|---|
| 635 | |
|---|
| 636 | # |
|---|
| 637 | # install |
|---|
| 638 | # |
|---|
| 639 | |
|---|
| 640 | def exec_install |
|---|
| 641 | exec_task_traverse 'install' |
|---|
| 642 | end |
|---|
| 643 | |
|---|
| 644 | def install_dir_bin( rel ) |
|---|
| 645 | install_files targfiles, config('bin-dir') + '/' + rel, 0755 |
|---|
| 646 | end |
|---|
| 647 | |
|---|
| 648 | def install_dir_lib( rel ) |
|---|
| 649 | install_files targfiles, config('rb-dir') + '/' + rel, 0644 |
|---|
| 650 | end |
|---|
| 651 | |
|---|
| 652 | def install_dir_ext( rel ) |
|---|
| 653 | install_dir_ext_main File.dirname(rel) if extdir?(curr_srcdir) |
|---|
| 654 | end |
|---|
| 655 | |
|---|
| 656 | def install_dir_ext_main( rel ) |
|---|
| 657 | install_files allext('.'), config('so-dir') + '/' + rel, 0555 |
|---|
| 658 | end |
|---|
| 659 | |
|---|
| 660 | def install_dir_data( rel ) |
|---|
| 661 | install_files targfiles, config('data-dir') + '/' + rel, 0644 |
|---|
| 662 | end |
|---|
| 663 | |
|---|
| 664 | def install_files( list, dest, mode ) |
|---|
| 665 | mkdir_p dest, @options['install-prefix'] |
|---|
| 666 | list.each do |fname| |
|---|
| 667 | install fname, dest, mode, @options['install-prefix'] |
|---|
| 668 | end |
|---|
| 669 | end |
|---|
| 670 | |
|---|
| 671 | def targfiles |
|---|
| 672 | (targfilenames() - hookfilenames()).collect {|fname| |
|---|
| 673 | File.exist?(fname) ? fname : File.join(curr_srcdir(), fname) |
|---|
| 674 | } |
|---|
| 675 | end |
|---|
| 676 | |
|---|
| 677 | def targfilenames |
|---|
| 678 | [ curr_srcdir(), '.' ].inject([]) {|ret, dir| |
|---|
| 679 | ret | all_files(dir) |
|---|
| 680 | } |
|---|
| 681 | end |
|---|
| 682 | |
|---|
| 683 | def hookfilenames |
|---|
| 684 | %w( pre-%s post-%s pre-%s.rb post-%s.rb ).collect {|fmt| |
|---|
| 685 | %w( config setup install clean ).collect {|t| sprintf fmt, t } |
|---|
| 686 | }.flatten |
|---|
| 687 | end |
|---|
| 688 | |
|---|
| 689 | def allext( dir ) |
|---|
| 690 | _allext(dir) or raise InstallError, |
|---|
| 691 | "no extention exists: Have you done 'ruby #{$0} setup' ?" |
|---|
| 692 | end |
|---|
| 693 | |
|---|
| 694 | DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/ |
|---|
| 695 | |
|---|
| 696 | def _allext( dir ) |
|---|
| 697 | Dir.open(dir) {|d| |
|---|
| 698 | return d.find_all {|fname| DLEXT === fname } |
|---|
| 699 | } |
|---|
| 700 | end |
|---|
| 701 | |
|---|
| 702 | # |
|---|
| 703 | # clean |
|---|
| 704 | # |
|---|
| 705 | |
|---|
| 706 | def exec_clean |
|---|
| 707 | exec_task_traverse 'clean' |
|---|
| 708 | rm_f 'config.save' |
|---|
| 709 | rm_f 'InstalledFiles' |
|---|
| 710 | end |
|---|
| 711 | |
|---|
| 712 | def clean_dir_bin( rel ) |
|---|
| 713 | end |
|---|
| 714 | |
|---|
| 715 | def clean_dir_lib( rel ) |
|---|
| 716 | end |
|---|
| 717 | |
|---|
| 718 | def clean_dir_ext( rel ) |
|---|
| 719 | clean |
|---|
| 720 | end |
|---|
| 721 | |
|---|
| 722 | def clean |
|---|
| 723 | command config('make-prog') + ' clean' if File.file? 'Makefile' |
|---|
| 724 | end |
|---|
| 725 | |
|---|
| 726 | def clean_dir_data( rel ) |
|---|
| 727 | end |
|---|
| 728 | |
|---|
| 729 | # |
|---|
| 730 | # lib |
|---|
| 731 | # |
|---|
| 732 | |
|---|
| 733 | def exec_task_traverse( task ) |
|---|
| 734 | run_hook 'pre-' + task |
|---|
| 735 | FILETYPES.each do |type| |
|---|
| 736 | if config('without-ext') == 'yes' and type == 'ext' |
|---|
| 737 | $stderr.puts 'skipping ext/* by user option' if verbose? |
|---|
| 738 | next |
|---|
| 739 | end |
|---|
| 740 | traverse task, type, task + '_dir_' + type |
|---|
| 741 | end |
|---|
| 742 | run_hook 'post-' + task |
|---|
| 743 | end |
|---|
| 744 | |
|---|
| 745 | def traverse( task, rel, mid ) |
|---|
| 746 | dive_into(rel) { |
|---|
| 747 | run_hook 'pre-' + task |
|---|
| 748 | __send__ mid, rel.sub(%r_\A.*?(?:/|\z)_, '') |
|---|
| 749 | all_dirs(curr_srcdir).each do |d| |
|---|
| 750 | traverse task, rel + '/' + d, mid |
|---|
| 751 | end |
|---|
| 752 | run_hook 'post-' + task |
|---|
| 753 | } |
|---|
| 754 | end |
|---|
| 755 | |
|---|
| 756 | def run_hook( name ) |
|---|
| 757 | try_run_hook curr_srcdir + '/' + name or |
|---|
| 758 | try_run_hook curr_srcdir + '/' + name + '.rb' |
|---|
| 759 | end |
|---|
| 760 | |
|---|
| 761 | def try_run_hook( fname ) |
|---|
| 762 | return false unless File.file? fname |
|---|
| 763 | |
|---|
| 764 | env = self.dup |
|---|
| 765 | begin |
|---|
| 766 | env.instance_eval File.read_all(fname), fname, 1 |
|---|
| 767 | rescue |
|---|
| 768 | raise InstallError, "hook #{fname} failed:\n" + $!.message |
|---|
| 769 | end |
|---|
| 770 | true |
|---|
| 771 | end |
|---|
| 772 | |
|---|
| 773 | def extdir?( dir ) |
|---|
| 774 | File.exist? dir + '/MANIFEST' |
|---|
| 775 | end |
|---|
| 776 | |
|---|
| 777 | end |
|---|
| 778 | |
|---|
| 779 | ### end base.rb |
|---|
| 780 | ### begin toplevel.rb |
|---|
| 781 | |
|---|
| 782 | class ToplevelInstaller < Installer |
|---|
| 783 | |
|---|
| 784 | TASKS = [ |
|---|
| 785 | [ 'config', 'saves your configurations' ], |
|---|
| 786 | [ 'show', 'shows current configuration' ], |
|---|
| 787 | [ 'setup', 'compiles extention or else' ], |
|---|
| 788 | [ 'install', 'installs files' ], |
|---|
| 789 | [ 'clean', "does `make clean' for each extention" ] |
|---|
| 790 | ] |
|---|
| 791 | |
|---|
| 792 | |
|---|
| 793 | def initialize( root ) |
|---|
| 794 | super nil, {'verbose' => true}, root, '.' |
|---|
| 795 | Installer.declear_toplevel_installer self |
|---|
| 796 | end |
|---|
| 797 | |
|---|
| 798 | |
|---|
| 799 | def execute |
|---|
| 800 | run_metaconfigs |
|---|
| 801 | |
|---|
| 802 | case task = parsearg_global() |
|---|
| 803 | when 'config' |
|---|
| 804 | @config = ConfigTable.new |
|---|
| 805 | else |
|---|
| 806 | @config = ConfigTable.load |
|---|
| 807 | end |
|---|
| 808 | parsearg_TASK task |
|---|
| 809 | |
|---|
| 810 | exectask task |
|---|
| 811 | end |
|---|
| 812 | |
|---|
| 813 | |
|---|
| 814 | def run_metaconfigs |
|---|
| 815 | MetaConfigEnvironment.eval_file "#{srcdir_root()}/#{metaconfig()}" |
|---|
| 816 | end |
|---|
| 817 | |
|---|
| 818 | def metaconfig |
|---|
| 819 | 'metaconfig' |
|---|
| 820 | end |
|---|
| 821 | |
|---|
| 822 | |
|---|
| 823 | def exectask( task ) |
|---|
| 824 | if task == 'show' |
|---|
| 825 | exec_show |
|---|
| 826 | else |
|---|
| 827 | try task |
|---|
| 828 | end |
|---|
| 829 | end |
|---|
| 830 | |
|---|
| 831 | def try( task ) |
|---|
| 832 | $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose? |
|---|
| 833 | begin |
|---|
| 834 | __send__ 'exec_' + task |
|---|
| 835 | rescue |
|---|
| 836 | $stderr.printf "%s failed\n", task |
|---|
| 837 | raise |
|---|
| 838 | end |
|---|
| 839 | $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose? |
|---|
| 840 | end |
|---|
| 841 | |
|---|
| 842 | # |
|---|
| 843 | # processing arguments |
|---|
| 844 | # |
|---|
| 845 | |
|---|
| 846 | def parsearg_global |
|---|
| 847 | task_re = /\A(?:#{TASKS.collect {|i| i[0] }.join '|'})\z/ |
|---|
| 848 | |
|---|
| 849 | while arg = ARGV.shift |
|---|
| 850 | case arg |
|---|
| 851 | when /\A\w+\z/ |
|---|
| 852 | task_re === arg or raise InstallError, "wrong task: #{arg}" |
|---|
| 853 | return arg |
|---|
| 854 | |
|---|
| 855 | when '-q', '--quiet' |
|---|
| 856 | @options['verbose'] = false |
|---|
| 857 | |
|---|
| 858 | when '--verbose' |
|---|
| 859 | @options['verbose'] = true |
|---|
| 860 | |
|---|
| 861 | when '-h', '--help' |
|---|
| 862 | print_usage $stdout |
|---|
| 863 | exit 0 |
|---|
| 864 | |
|---|
| 865 | when '-v', '--version' |
|---|
| 866 | puts "#{File.basename $0} version #{Version}" |
|---|
| 867 | exit 0 |
|---|
| 868 | |
|---|
| 869 | when '--copyright' |
|---|
| 870 | puts Copyright |
|---|
| 871 | exit 0 |
|---|
| 872 | |
|---|
| 873 | else |
|---|
| 874 | raise InstallError, "unknown global option '#{arg}'" |
|---|
| 875 | end |
|---|
| 876 | end |
|---|
| 877 | |
|---|
| 878 | raise InstallError, "No task or global option given. |
|---|
| 879 | Typical installation procedure is: |
|---|
| 880 | $ ruby #{File.basename $0} config |
|---|
| 881 | $ ruby #{File.basename $0} setup |
|---|
| 882 | # ruby #{File.basename $0} install (may require root privilege) |
|---|
| 883 | " |
|---|
| 884 | end |
|---|
| 885 | |
|---|
| 886 | |
|---|
| 887 | def parsearg_TASK( task ) |
|---|
| 888 | mid = "parsearg_#{task}" |
|---|
| 889 | if respond_to? mid, true |
|---|
| 890 | __send__ mid |
|---|
| 891 | else |
|---|
| 892 | ARGV.empty? or |
|---|
| 893 | raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}" |
|---|
| 894 | end |
|---|
| 895 | end |
|---|
| 896 | |
|---|
| 897 | def parsearg_config |
|---|
| 898 | re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/ |
|---|
| 899 | @options['config-opt'] = [] |
|---|
| 900 | |
|---|
| 901 | while i = ARGV.shift |
|---|
| 902 | if /\A--?\z/ === i |
|---|
| 903 | @options['config-opt'] = ARGV.dup |
|---|
| 904 | break |
|---|
| 905 | end |
|---|
| 906 | m = re.match(i) or raise InstallError, "config: unknown option #{i}" |
|---|
| 907 | name, value = m.to_a[1,2] |
|---|
| 908 | if value |
|---|
| 909 | if ConfigTable.bool_config?(name) |
|---|
| 910 | /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument" |
|---|
| 911 | value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no' |
|---|
| 912 | end |
|---|
| 913 | else |
|---|
| 914 | ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument" |
|---|
| 915 | value = 'yes' |
|---|
| 916 | end |
|---|
| 917 | @config[name] = value |
|---|
| 918 | end |
|---|
| 919 | end |
|---|
| 920 | |
|---|
| 921 | def parsearg_install |
|---|
| 922 | @options['no-harm'] = false |
|---|
| 923 | @options['install-prefix'] = '' |
|---|
| 924 | while a = ARGV.shift |
|---|
| 925 | case a |
|---|
| 926 | when /\A--no-harm\z/ |
|---|
| 927 | @options['no-harm'] = true |
|---|
| 928 | when /\A--prefix=(.*)\z/ |
|---|
| 929 | path = $1 |
|---|
| 930 | path = File.expand_path(path) unless path[0,1] == '/' |
|---|
| 931 | @options['install-prefix'] = path |
|---|
| 932 | else |
|---|
| 933 | raise InstallError, "install: unknown option #{a}" |
|---|
| 934 | end |
|---|
| 935 | end |
|---|
| 936 | end |
|---|
| 937 | |
|---|
| 938 | |
|---|
| 939 | def print_usage( out ) |
|---|
| 940 | out.puts 'Typical Installation Procedure:' |
|---|
| 941 | out.puts " $ ruby #{File.basename $0} config" |
|---|
| 942 | out.puts " $ ruby #{File.basename $0} setup" |
|---|
| 943 | out.puts " # ruby #{File.basename $0} install (may require root privilege)" |
|---|
| 944 | out.puts |
|---|
| 945 | out.puts 'Detailed Usage:' |
|---|
| 946 | out.puts " ruby #{File.basename $0} <global option>" |
|---|
| 947 | out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]" |
|---|
| 948 | |
|---|
| 949 | fmt = " %-20s %s\n" |
|---|
| 950 | out.puts |
|---|
| 951 | out.puts 'Global options:' |
|---|
| 952 | out.printf fmt, '-q,--quiet', 'suppress message outputs' |
|---|
| 953 | out.printf fmt, ' --verbose', 'output messages verbosely' |
|---|
| 954 | out.printf fmt, '-h,--help', 'print this message' |
|---|
| 955 | out.printf fmt, '-v,--version', 'print version and quit' |
|---|
| 956 | out.printf fmt, ' --copyright', 'print copyright and quit' |
|---|
| 957 | |
|---|
| 958 | out.puts |
|---|
| 959 | out.puts 'Tasks:' |
|---|
| 960 | TASKS.each do |name, desc| |
|---|
| 961 | out.printf " %-10s %s\n", name, desc |
|---|
| 962 | end |
|---|
| 963 | |
|---|
| 964 | out.puts |
|---|
| 965 | out.puts 'Options for config:' |
|---|
| 966 | ConfigTable.each_definition do |name, (default, arg, desc, default2)| |
|---|
| 967 | out.printf " %-20s %s [%s]\n", |
|---|
| 968 | '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg), |
|---|
| 969 | desc, |
|---|
| 970 | default2 || default |
|---|
| 971 | end |
|---|
| 972 | out.printf " %-20s %s [%s]\n", |
|---|
| 973 | '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's" |
|---|
| 974 | |
|---|
| 975 | out.puts |
|---|
| 976 | out.puts 'Options for install:' |
|---|
| 977 | out.printf " %-20s %s [%s]\n", |
|---|
| 978 | '--no-harm', 'only display what to do if given', 'off' |
|---|
| 979 | out.printf " %-20s %s [%s]\n", |
|---|
| 980 | '--prefix', 'install path prefix', '$prefix' |
|---|
| 981 | |
|---|
| 982 | out.puts |
|---|
| 983 | end |
|---|
| 984 | |
|---|
| 985 | # |
|---|
| 986 | # config |
|---|
| 987 | # |
|---|
| 988 | |
|---|
| 989 | def exec_config |
|---|
| 990 | super |
|---|
| 991 | @config.save |
|---|
| 992 | end |
|---|
| 993 | |
|---|
| 994 | # |
|---|
| 995 | # show |
|---|
| 996 | # |
|---|
| 997 | |
|---|
| 998 | def exec_show |
|---|
| 999 | ConfigTable.each_name do |k| |
|---|
| 1000 | v = @config.get_raw(k) |
|---|
| 1001 | if not v or v.empty? |
|---|
| 1002 | v = '(not specified)' |
|---|
| 1003 | end |
|---|
| 1004 | printf "%-10s %s\n", k, v |
|---|
| 1005 | end |
|---|
| 1006 | end |
|---|
| 1007 | |
|---|
| 1008 | end |
|---|
| 1009 | |
|---|
| 1010 | ### end toplevel.rb |
|---|
| 1011 | |
|---|
| 1012 | if $0 == __FILE__ |
|---|
| 1013 | begin |
|---|
| 1014 | installer = ToplevelInstaller.new(File.dirname($0)) |
|---|
| 1015 | installer.execute |
|---|
| 1016 | rescue |
|---|
| 1017 | raise if $DEBUG |
|---|
| 1018 | $stderr.puts $!.message |
|---|
| 1019 | $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." |
|---|
| 1020 | exit 1 |
|---|
| 1021 | end |
|---|
| 1022 | end |
|---|