4
# Copyright (c) 2000-2006 Minero Aoki
6
# This program is free software.
7
# You can distribute/modify this program under the terms of
8
# the GNU LGPL, Lesser General Public License version 2.1.
11
unless Enumerable.method_defined?(:map) # Ruby 1.4.6
17
unless File.respond_to?(:read) # Ruby 1.6
25
unless Errno.const_defined?(:ENOTEMPTY) # Windows?
28
# We do not raise this exception, implementation is not needed.
33
def File.binread(fname)
34
open(fname, 'rb') {|f|
39
# for corrupted Windows' stat(2)
41
File.directory?((path[-1,1] == '/') ? path : path + '/')
49
def initialize(rbconfig)
60
attr_accessor :install_prefix
61
attr_accessor :config_opt
76
lookup(key).resolve(self)
84
@items.map {|i| i.name }
96
@table[name] or setup_rb_error "no such config item: #{name}"
101
@table[item.name] = item
106
@items.delete_if {|i| i.name == name }
107
@table.delete_if {|name, i| i.name == name }
111
def load_script(path, inst = nil)
113
MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
123
File.foreach(savefile()) do |line|
124
k, v = *line.split(/=/, 2)
128
setup_rb_error $!.message + "\n#{File.basename($0)} config first"
133
@items.each {|i| i.value }
134
File.open(savefile(), 'w') {|f|
136
f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
141
def load_standard_entries
142
standard_entries(@rbconfig).each do |ent|
147
def standard_entries(rbconfig)
150
rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
152
major = c['MAJOR'].to_i
153
minor = c['MINOR'].to_i
154
teeny = c['TEENY'].to_i
155
version = "#{major}.#{minor}"
157
# ruby ver. >= 1.4.4?
158
newpath_p = ((major >= 2) or
161
((minor == 4) and (teeny >= 4)))))
165
libruby = "#{c['prefix']}/lib/ruby"
166
librubyver = c['rubylibdir']
167
librubyverarch = c['archdir']
168
siteruby = c['sitedir']
169
siterubyver = c['sitelibdir']
170
siterubyverarch = c['sitearchdir']
172
# 1.4.4 <= V <= 1.6.3
173
libruby = "#{c['prefix']}/lib/ruby"
174
librubyver = "#{c['prefix']}/lib/ruby/#{version}"
175
librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
176
siteruby = c['sitedir']
177
siterubyver = "$siteruby/#{version}"
178
siterubyverarch = "$siterubyver/#{c['arch']}"
181
libruby = "#{c['prefix']}/lib/ruby"
182
librubyver = "#{c['prefix']}/lib/ruby/#{version}"
183
librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
184
siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
185
siterubyver = siteruby
186
siterubyverarch = "$siterubyver/#{c['arch']}"
188
parameterize = lambda {|path|
189
path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
192
if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
193
makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
199
ExecItem.new('installdirs', 'std/site/home',
200
'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
204
table['rbdir'] = '$librubyver'
205
table['sodir'] = '$librubyverarch'
207
table['rbdir'] = '$siterubyver'
208
table['sodir'] = '$siterubyverarch'
210
setup_rb_error '$HOME was not set' unless ENV['HOME']
211
table['prefix'] = ENV['HOME']
212
table['rbdir'] = '$libdir/ruby'
213
table['sodir'] = '$libdir/ruby'
216
PathItem.new('prefix', 'path', c['prefix'],
217
'path prefix of target environment'),
218
PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
219
'the directory for commands'),
220
PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
221
'the directory for libraries'),
222
PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
223
'the directory for shared data'),
224
PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
225
'the directory for man pages'),
226
PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
227
'the directory for system configuration files'),
228
PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
229
'the directory for local state data'),
230
PathItem.new('libruby', 'path', libruby,
231
'the directory for ruby libraries'),
232
PathItem.new('librubyver', 'path', librubyver,
233
'the directory for standard ruby libraries'),
234
PathItem.new('librubyverarch', 'path', librubyverarch,
235
'the directory for standard ruby extensions'),
236
PathItem.new('siteruby', 'path', siteruby,
237
'the directory for version-independent aux ruby libraries'),
238
PathItem.new('siterubyver', 'path', siterubyver,
239
'the directory for aux ruby libraries'),
240
PathItem.new('siterubyverarch', 'path', siterubyverarch,
241
'the directory for aux ruby binaries'),
242
PathItem.new('rbdir', 'path', '$siterubyver',
243
'the directory for ruby scripts'),
244
PathItem.new('sodir', 'path', '$siterubyverarch',
245
'the directory for ruby extentions'),
246
PathItem.new('rubypath', 'path', rubypath,
247
'the path to set to #! line'),
248
ProgramItem.new('rubyprog', 'name', rubypath,
249
'the ruby program using for installation'),
250
ProgramItem.new('makeprog', 'name', makeprog,
251
'the make program to compile ruby extentions'),
252
SelectItem.new('shebang', 'all/ruby/never', 'ruby',
253
'shebang line (#!) editing mode'),
254
BoolItem.new('without-ext', 'yes/no', 'no',
255
'does not compile/install ruby extentions')
258
private :standard_entries
260
def load_multipackage_entries
261
multipackage_entries().each do |ent|
266
def multipackage_entries
268
PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
269
'package names that you want to install'),
270
PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
271
'package names that you do not want to install')
274
private :multipackage_entries
277
'std-ruby' => 'librubyver',
278
'stdruby' => 'librubyver',
279
'rubylibdir' => 'librubyver',
280
'archdir' => 'librubyverarch',
281
'site-ruby-common' => 'siteruby', # For backward compatibility
282
'site-ruby' => 'siterubyver', # For backward compatibility
283
'bin-dir' => 'bindir',
284
'bin-dir' => 'bindir',
287
'data-dir' => 'datadir',
288
'ruby-path' => 'rubypath',
289
'ruby-prog' => 'rubyprog',
290
'ruby' => 'rubyprog',
291
'make-prog' => 'makeprog',
296
ALIASES.each do |ali, name|
297
@table[ali] = @table[name]
302
/\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
306
m = options_re().match(opt) or setup_rb_error "config: unknown option #{opt}"
314
def value_config?(name)
319
def initialize(name, template, default, desc)
328
attr_reader :description
330
attr_accessor :default
331
alias help_default default
334
"--#{@name}=#{@template}"
346
@value.gsub(%r<\$([^/]+)>) { table[$1] }
356
setup_rb_error "config: --#{name} requires argument" unless val
361
class BoolItem < Item
373
return 'yes' unless val
375
when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
376
when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
378
setup_rb_error "config: --#{@name} accepts only yes/no for argument"
383
class PathItem < Item
391
setup_rb_error "config: --#{@name} requires argument" unless path
392
path[0,1] == '$' ? path : File.expand_path(path)
396
class ProgramItem < Item
402
class SelectItem < Item
403
def initialize(name, selection, default, desc)
405
@ok = selection.split('/')
415
unless @ok.include?(val.strip)
416
setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
422
class ExecItem < Item
423
def initialize(name, selection, desc, &block)
424
super name, selection, nil, desc
425
@ok = selection.split('/')
438
setup_rb_error "$#{name()} wrongly used as option value"
443
def evaluate(val, table)
444
v = val.strip.downcase
445
unless @ok.include?(v)
446
setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
448
@action.call v, table
452
class PackageSelectionItem < Item
453
def initialize(name, template, default, help_default, desc)
454
super name, template, default, desc
455
@help_default = help_default
458
attr_reader :help_default
467
unless File.dir?("packages/#{val}")
468
setup_rb_error "config: no such package: #{val}"
474
class MetaConfigEnvironment
475
def initialize(config, installer)
477
@installer = installer
488
def bool_config?(name)
489
@config.lookup(name).config_type == 'bool'
492
def path_config?(name)
493
@config.lookup(name).config_type == 'path'
496
def value_config?(name)
497
@config.lookup(name).config_type != 'exec'
504
def add_bool_config(name, default, desc)
505
@config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
508
def add_path_config(name, default, desc)
509
@config.add PathItem.new(name, 'path', default, desc)
512
def set_config_default(name, default)
513
@config.lookup(name).default = default
516
def remove_config(name)
520
# For only multipackage
522
raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
526
# For only multipackage
527
def declare_packages(list)
528
raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
529
@installer.packages = list
533
end # class ConfigTable
536
# This module requires: #verbose?, #no_harm?
537
module FileOperations
539
def mkdir_p(dirname, prefix = nil)
540
dirname = prefix + File.expand_path(dirname) if prefix
541
$stderr.puts "mkdir -p #{dirname}" if verbose?
544
# Does not check '/', it's too abnormal.
545
dirs = File.expand_path(dirname).split(%r<(?=/)>)
546
if /\A[a-z]:\z/i =~ dirs[0]
548
dirs[0] = disk + dirs[0]
550
dirs.each_index do |idx|
551
path = dirs[0..idx].join('')
552
Dir.mkdir path unless File.dir?(path)
557
$stderr.puts "rm -f #{path}" if verbose?
559
force_remove_file path
563
$stderr.puts "rm -rf #{path}" if verbose?
568
def remove_tree(path)
569
if File.symlink?(path)
571
elsif File.dir?(path)
574
force_remove_file path
578
def remove_tree0(path)
579
Dir.foreach(path) do |ent|
582
entpath = "#{path}/#{ent}"
583
if File.symlink?(entpath)
585
elsif File.dir?(entpath)
588
force_remove_file entpath
593
rescue Errno::ENOTEMPTY
594
# directory may not be empty
598
def move_file(src, dest)
599
force_remove_file dest
601
File.rename src, dest
603
File.open(dest, 'wb') {|f|
604
f.write File.binread(src)
606
File.chmod File.stat(src).mode, dest
611
def force_remove_file(path)
618
def remove_file(path)
619
File.chmod 0777, path
623
def install(from, dest, mode, prefix = nil)
624
$stderr.puts "install #{from} #{dest}" if verbose?
627
realdest = prefix ? prefix + File.expand_path(dest) : dest
628
realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
629
str = File.binread(from)
630
if diff?(str, realdest)
632
rm_f realdest if File.exist?(realdest)
634
File.open(realdest, 'wb') {|f|
637
File.chmod mode, realdest
639
File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
641
f.puts realdest.sub(prefix, '')
649
def diff?(new_content, path)
650
return true unless File.exist?(path)
651
new_content != File.binread(path)
655
$stderr.puts args.join(' ') if verbose?
656
system(*args) or raise RuntimeError,
657
"system(#{args.map{|a| a.inspect }.join(' ')}) failed"
661
command config('rubyprog'), *args
665
command(*[config('makeprog'), task].compact)
669
File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
674
return d.select {|ent| File.file?("#{dir}/#{ent}") }
678
DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
680
def directories_of(dir)
682
return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
689
# This module requires: #srcdir_root, #objdir_root, #relpath
696
alias config get_config
698
# obsolete: use metaconfig to change configuration
699
def set_config(key, val)
704
# srcdir/objdir (works only in the package directory)
708
"#{srcdir_root()}/#{relpath()}"
712
"#{objdir_root()}/#{relpath()}"
716
"#{curr_srcdir()}/#{path}"
720
File.exist?(srcfile(path))
723
def srcdirectory?(path)
724
File.dir?(srcfile(path))
728
File.file?(srcfile(path))
731
def srcentries(path = '.')
732
Dir.open("#{curr_srcdir()}/#{path}") {|d|
733
return d.to_a - %w(. ..)
737
def srcfiles(path = '.')
738
srcentries(path).select {|fname|
739
File.file?(File.join(curr_srcdir(), path, fname))
743
def srcdirectories(path = '.')
744
srcentries(path).select {|fname|
745
File.dir?(File.join(curr_srcdir(), path, fname))
752
class ToplevelInstaller
755
Copyright = 'Copyright (c) 2000-2006 Minero Aoki'
758
[ 'all', 'do config, setup, then install' ],
759
[ 'config', 'saves your configurations' ],
760
[ 'show', 'shows current configuration' ],
761
[ 'setup', 'compiles ruby extentions and others' ],
762
[ 'install', 'installs files' ],
763
[ 'test', 'run all tests in test/' ],
764
[ 'clean', "does `make clean' for each extention" ],
765
[ 'distclean',"does `make distclean' for each extention" ]
768
def ToplevelInstaller.invoke
769
config = ConfigTable.new(load_rbconfig())
770
config.load_standard_entries
771
config.load_multipackage_entries if multipackage?
773
klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
774
klass.new(File.dirname($0), config).invoke
777
def ToplevelInstaller.multipackage?
778
File.dir?(File.dirname($0) + '/packages')
781
def ToplevelInstaller.load_rbconfig
782
if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
784
load File.expand_path(arg.split(/=/, 2)[1])
785
$".push 'rbconfig.rb'
787
require 'rbconfig' unless defined? RbConfig
792
def initialize(ardir_root, config)
793
@ardir = File.expand_path(ardir_root)
804
"#<#{self.class} #{__id__()}>"
809
case task = parsearg_global()
818
when 'config', 'test'
820
when 'clean', 'distclean'
821
@config.load_savefile if File.exist?(@config.savefile)
823
@config.load_savefile
825
__send__ "parsearg_#{task}"
827
__send__ "exec_#{task}"
832
@config.load_script "#{@ardir}/metaconfig"
836
@installer = Installer.new(@config, @ardir, File.expand_path('.'))
840
# Hook Script API bases
860
while arg = ARGV.shift
863
setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
866
@config.verbose = false
868
@config.verbose = true
873
puts "#{File.basename($0)} version #{Version}"
879
setup_rb_error "unknown global option '#{arg}'"
890
@valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
893
def parsearg_no_options
895
task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
896
setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
900
alias parsearg_show parsearg_no_options
901
alias parsearg_setup parsearg_no_options
902
alias parsearg_test parsearg_no_options
903
alias parsearg_clean parsearg_no_options
904
alias parsearg_distclean parsearg_no_options
909
@config.config_opt = []
912
@config.config_opt = ARGV.dup
915
name, value = *@config.parse_opt(i)
916
if @config.value_config?(name)
917
@config[name] = value
919
evalopt.push [name, value]
923
evalopt.each do |name, value|
924
@config.lookup(name).evaluate value, @config
926
# Check if configuration is valid
928
@config[n] if @config.value_config?(n)
933
@config.no_harm = false
934
@config.install_prefix = ''
938
@config.no_harm = true
940
path = a.split(/=/, 2)[1]
941
path = File.expand_path(path) unless path[0,1] == '/'
942
@config.install_prefix = path
944
setup_rb_error "install: unknown option #{a}"
950
out.puts 'Typical Installation Procedure:'
951
out.puts " $ ruby #{File.basename $0} config"
952
out.puts " $ ruby #{File.basename $0} setup"
953
out.puts " # ruby #{File.basename $0} install (may require root privilege)"
955
out.puts 'Detailed Usage:'
956
out.puts " ruby #{File.basename $0} <global option>"
957
out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
961
out.puts 'Global options:'
962
out.printf fmt, '-q,--quiet', 'suppress message outputs'
963
out.printf fmt, ' --verbose', 'output messages verbosely'
964
out.printf fmt, ' --help', 'print this message'
965
out.printf fmt, ' --version', 'print version and quit'
966
out.printf fmt, ' --copyright', 'print copyright and quit'
969
TASKS.each do |name, desc|
970
out.printf fmt, name, desc
973
fmt = " %-24s %s [%s]\n"
975
out.puts 'Options for CONFIG or ALL:'
976
@config.each do |item|
977
out.printf fmt, item.help_opt, item.description, item.help_default
979
out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
981
out.puts 'Options for INSTALL:'
982
out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
983
out.printf fmt, '--prefix=path', 'install path prefix', ''
992
@installer.exec_config
993
@config.save # must be final
997
@installer.exec_setup
1001
@installer.exec_install
1005
@installer.exec_test
1010
printf "%-20s %s\n", i.name, i.value if i.value?
1015
@installer.exec_clean
1019
@installer.exec_distclean
1022
end # class ToplevelInstaller
1025
class ToplevelInstallerMulti < ToplevelInstaller
1027
include FileOperations
1029
def initialize(ardir_root, config)
1031
@packages = directories_of("#{@ardir}/packages")
1032
raise 'no package exists' if @packages.empty?
1033
@root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
1037
@config.load_script "#{@ardir}/metaconfig", self
1038
@packages.each do |name|
1039
@config.load_script "#{@ardir}/packages/#{name}/metaconfig"
1043
attr_reader :packages
1046
raise 'package list is empty' if list.empty?
1048
raise "directory packages/#{name} does not exist"\
1049
unless File.dir?("#{@ardir}/packages/#{name}")
1056
@packages.each do |pack|
1057
@installers[pack] = Installer.new(@config,
1058
"#{@ardir}/packages/#{pack}",
1061
with = extract_selection(config('with'))
1062
without = extract_selection(config('without'))
1063
@selected = @installers.keys.select {|name|
1064
(with.empty? or with.include?(name)) \
1065
and not without.include?(name)
1069
def extract_selection(list)
1072
setup_rb_error "no such package: #{name}" unless @installers.key?(name)
1079
f.puts 'Inluded packages:'
1080
f.puts ' ' + @packages.sort.join(' ')
1089
run_hook 'pre-config'
1090
each_selected_installers {|inst| inst.exec_config }
1091
run_hook 'post-config'
1092
@config.save # must be final
1096
run_hook 'pre-setup'
1097
each_selected_installers {|inst| inst.exec_setup }
1098
run_hook 'post-setup'
1102
run_hook 'pre-install'
1103
each_selected_installers {|inst| inst.exec_install }
1104
run_hook 'post-install'
1109
each_selected_installers {|inst| inst.exec_test }
1110
run_hook 'post-test'
1114
rm_f @config.savefile
1115
run_hook 'pre-clean'
1116
each_selected_installers {|inst| inst.exec_clean }
1117
run_hook 'post-clean'
1121
rm_f @config.savefile
1122
run_hook 'pre-distclean'
1123
each_selected_installers {|inst| inst.exec_distclean }
1124
run_hook 'post-distclean'
1131
def each_selected_installers
1132
Dir.mkdir 'packages' unless File.dir?('packages')
1133
@selected.each do |pack|
1134
$stderr.puts "Processing the package `#{pack}' ..." if verbose?
1135
Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1136
Dir.chdir "packages/#{pack}"
1137
yield @installers[pack]
1143
@root_installer.run_hook id
1146
# module FileOperations requires this
1151
# module FileOperations requires this
1156
end # class ToplevelInstallerMulti
1161
FILETYPES = %w( bin lib ext data conf man )
1163
include FileOperations
1164
include HookScriptAPI
1166
def initialize(config, srcroot, objroot)
1168
@srcdir = File.expand_path(srcroot)
1169
@objdir = File.expand_path(objroot)
1174
"#<#{self.class} #{File.basename(@srcdir)}>"
1181
# Hook Script API base methods
1200
# module FileOperations requires this
1205
# module FileOperations requires this
1212
save, @config.verbose = @config.verbose?, false
1215
@config.verbose = save
1224
exec_task_traverse 'config'
1227
alias config_dir_bin noop
1228
alias config_dir_lib noop
1230
def config_dir_ext(rel)
1231
extconf if extdir?(curr_srcdir())
1234
alias config_dir_data noop
1235
alias config_dir_conf noop
1236
alias config_dir_man noop
1239
ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1247
exec_task_traverse 'setup'
1250
def setup_dir_bin(rel)
1251
files_of(curr_srcdir()).each do |fname|
1252
update_shebang_line "#{curr_srcdir()}/#{fname}"
1256
alias setup_dir_lib noop
1258
def setup_dir_ext(rel)
1259
make if extdir?(curr_srcdir())
1262
alias setup_dir_data noop
1263
alias setup_dir_conf noop
1264
alias setup_dir_man noop
1266
def update_shebang_line(path)
1268
return if config('shebang') == 'never'
1269
old = Shebang.load(path)
1271
$stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
1272
new = new_shebang(old)
1273
return if new.to_s == old.to_s
1275
return unless config('shebang') == 'all'
1276
new = Shebang.new(config('rubypath'))
1278
$stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
1279
open_atomic_writer(path) {|output|
1280
File.open(path, 'rb') {|f|
1281
f.gets if old # discard
1282
output.puts new.to_s
1288
def new_shebang(old)
1289
if /\Aruby/ =~ File.basename(old.cmd)
1290
Shebang.new(config('rubypath'), old.args)
1291
elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1292
Shebang.new(config('rubypath'), old.args[1..-1])
1294
return old unless config('shebang') == 'all'
1295
Shebang.new(config('rubypath'))
1299
def open_atomic_writer(path, &block)
1300
tmpfile = File.basename(path) + '.tmp'
1302
File.open(tmpfile, 'wb', &block)
1303
File.rename tmpfile, File.basename(path)
1305
File.unlink tmpfile if File.exist?(tmpfile)
1310
def Shebang.load(path)
1312
File.open(path) {|f|
1315
return nil unless /\A#!/ =~ line
1319
def Shebang.parse(line)
1320
cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1324
def initialize(cmd, args = [])
1333
"#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1342
rm_f 'InstalledFiles'
1343
exec_task_traverse 'install'
1346
def install_dir_bin(rel)
1347
install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755, strip_ext?
1351
/mswin|mingw/ !~ RUBY_PLATFORM
1354
def install_dir_lib(rel)
1355
install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
1358
def install_dir_ext(rel)
1359
return unless extdir?(curr_srcdir())
1360
install_files rubyextentions('.'),
1361
"#{config('sodir')}/#{File.dirname(rel)}",
1365
def install_dir_data(rel)
1366
install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
1369
def install_dir_conf(rel)
1370
# FIXME: should not remove current config files
1371
# (rename previous file to .old/.org)
1372
install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
1375
def install_dir_man(rel)
1376
install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
1379
def install_files(list, dest, mode, stripext = false)
1380
mkdir_p dest, @config.install_prefix
1381
list.each do |fname|
1383
install fname, "#{dest}/#{File.basename(fname, '.*')}",
1384
mode, @config.install_prefix
1386
install fname, dest, mode, @config.install_prefix
1392
glob_reject(%w(*.y *.output), targetfiles())
1395
def rubyextentions(dir)
1396
ents = glob_select("*.#{@config.dllext}", targetfiles())
1398
setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1404
mapdir(existfiles() - hookfiles())
1411
else "#{curr_srcdir()}/#{ent}" # srcdir
1416
# picked up many entries from cvs-1.11.1/src/ignore.c
1418
core RCSLOG tags TAGS .make.state
1419
.nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1420
*~ *.old *.bak *.BAK *.orig *.rej _$* *$
1426
glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1430
%w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1431
%w( config setup install clean distclean ).map {|t| sprintf(fmt, t) }
1435
def glob_select(pat, ents)
1436
re = globs2re([pat])
1437
ents.select {|ent| re =~ ent }
1440
def glob_reject(pats, ents)
1442
ents.reject {|ent| re =~ ent }
1454
pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
1465
unless File.directory?('test')
1466
$stderr.puts 'no test in this package' if verbose?
1469
$stderr.puts 'Running tests...' if verbose?
1473
setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
1475
runner = Test::Unit::AutoRunner.new(true)
1476
runner.to_run << TESTDIR
1485
exec_task_traverse 'clean'
1486
rm_f @config.savefile
1487
rm_f 'InstalledFiles'
1490
alias clean_dir_bin noop
1491
alias clean_dir_lib noop
1492
alias clean_dir_data noop
1493
alias clean_dir_conf noop
1494
alias clean_dir_man noop
1496
def clean_dir_ext(rel)
1497
return unless extdir?(curr_srcdir())
1498
make 'clean' if File.file?('Makefile')
1506
exec_task_traverse 'distclean'
1507
rm_f @config.savefile
1508
rm_f 'InstalledFiles'
1511
alias distclean_dir_bin noop
1512
alias distclean_dir_lib noop
1514
def distclean_dir_ext(rel)
1515
return unless extdir?(curr_srcdir())
1516
make 'distclean' if File.file?('Makefile')
1519
alias distclean_dir_data noop
1520
alias distclean_dir_conf noop
1521
alias distclean_dir_man noop
1527
def exec_task_traverse(task)
1528
run_hook "pre-#{task}"
1529
FILETYPES.each do |type|
1530
if type == 'ext' and config('without-ext') == 'yes'
1531
$stderr.puts 'skipping ext/* by user option' if verbose?
1534
traverse task, type, "#{task}_dir_#{type}"
1536
run_hook "post-#{task}"
1539
def traverse(task, rel, mid)
1541
run_hook "pre-#{task}"
1542
__send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1543
directories_of(curr_srcdir()).each do |d|
1544
traverse task, "#{rel}/#{d}", mid
1546
run_hook "post-#{task}"
1551
return unless File.dir?("#{@srcdir}/#{rel}")
1553
dir = File.basename(rel)
1554
Dir.mkdir dir unless File.dir?(dir)
1557
$stderr.puts '---> ' + rel if verbose?
1561
$stderr.puts '<--- ' + rel if verbose?
1562
@currdir = File.dirname(rel)
1566
path = [ "#{curr_srcdir()}/#{id}",
1567
"#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
1569
$stderr.puts "invoking hook script #{path}" if verbose?
1571
instance_eval File.read(path), path, 1
1574
setup_rb_error "hook #{path} failed:\n" + $!.message
1578
end # class Installer
1581
class SetupError < StandardError; end
1583
def setup_rb_error(msg)
1584
raise SetupError, msg
1589
ToplevelInstaller.invoke
1592
$stderr.puts $!.message
1593
$stderr.puts "Try 'ruby #{$0} --help' for detailed usage."