class Setup::Installer
Installer
class handles the actual install procedure.
NOTE: This new version does not support per-directory hooks.
Public Instance Methods
Install package.
# File lib/setup/installer.rb, line 18 def install Dir.chdir(rootdir) do install_bin install_ext install_lib install_data install_man install_doc install_etc prune_install_record end end
Install binaries (executables).
# File lib/setup/installer.rb, line 32 def install_bin return unless directory?('bin') report_transfer('bin', config.bindir) #io.puts "* bin -> #{config.bindir}" unless quiet? files = files('bin') install_files('bin', files, config.bindir, 0755) #install_shebang(files, config.bindir) end
Install shared data.
# File lib/setup/installer.rb, line 66 def install_data return unless directory?('data') report_transfer('data', config.datadir) #io.puts "* data -> #{config.datadir}" unless quiet? files = files('data') install_files('data', files, config.datadir, 0644) end
Install documentation.
TODO: The use of the project name in the doc directory should be set during the config phase. Define a seperate config method for it.
# File lib/setup/installer.rb, line 95 def install_doc return unless config.doc? return unless directory?('doc') return unless project.name dir = File.join(config.docdir, "ruby-#{project.name}") report_transfer('doc', dir) #io.puts "* doc -> #{dir}" unless quiet? files = files('doc') install_files('doc', files, dir, 0644) end
Install configuration.
# File lib/setup/installer.rb, line 75 def install_etc return unless directory?('etc') report_transfer('etc', config.sysconfdir) files = files('etc') install_files('etc', files, config.sysconfdir, 0644) end
Install shared extension libraries.
# File lib/setup/installer.rb, line 42 def install_ext return unless directory?('ext') report_transfer('ext', config.sodir) #io.puts "* ext -> #{config.sodir}" unless quiet? files = files('ext') files = select_dllext(files) #install_files('ext', files, config.sodir, 0555) files.each do |file| name = File.join(File.dirname(File.dirname(file)), File.basename(file)) dest = destination(config.sodir, name) install_file('ext', file, dest, 0555, install_prefix) end end
Install library files.
# File lib/setup/installer.rb, line 57 def install_lib return unless directory?('lib') report_transfer('lib', config.rbdir) #io.puts "* lib -> #{config.rbdir}" unless quiet? files = files('lib') install_files('lib', files, config.rbdir, 0644) end
Install manpages.
# File lib/setup/installer.rb, line 83 def install_man return unless directory?('man') report_transfer('man', config.mandir) files = files('man') install_files('man', files, config.mandir, 0644) end
# File lib/setup/installer.rb, line 12 def install_prefix config.install_prefix end
Private Instance Methods
Binary read.
# File lib/setup/installer.rb, line 262 def binread(fname) File.open(fname, 'rb') do |f| return f.read end end
Determine actual destination including install_prefix.
# File lib/setup/installer.rb, line 247 def destination(dir, file) dest = install_prefix ? File.join(install_prefix, File.expand_path(dir)) : dir dest = File.join(dest, file) #if File.dir?(dest) dest = File.expand_path(dest) dest end
Is a current project file different from a previously installed file?
# File lib/setup/installer.rb, line 256 def diff?(new_content, path) return true unless File.exist?(path) new_content != binread(path) end
Comfirm a path
is a directory and exists.
# File lib/setup/installer.rb, line 121 def directory?(path) File.directory?(path) end
Dynamic link library extension for this system.
# File lib/setup/installer.rb, line 145 def dllext config.dlext #Configuration::RBCONFIG['DLEXT'] end
Get a list of project files given a project subdirectory.
# File lib/setup/installer.rb, line 126 def files(dir) files = Dir["#{dir}/**/*"] files = files.select{ |f| File.file?(f) } files = files.map{ |f| f.sub("#{dir}/", '') } files end
Install a project file.
# File lib/setup/installer.rb, line 160 def install_file(dir, from, dest, mode, prefix=nil) mkdir_p(File.dirname(dest)) if trace? or trial? #to = prefix ? File.join(prefix, dir, from) : File.join(dir, from) io.puts "install #{dir}/#{from} #{dest}" end return if trial? str = binread(File.join(dir, from)) if diff?(str, dest) trace_off { rm_f(dest) if File.exist?(dest) } File.open(dest, 'wb'){ |f| f.write(str) } File.chmod(mode, dest) end record_installation(dest) # record file as installed end
Install project files.
# File lib/setup/installer.rb, line 151 def install_files(dir, list, dest, mode) #mkdir_p(dest) #, install_prefix) list.each do |fname| rdest = destination(dest, fname) install_file(dir, fname, rdest, mode, install_prefix) end end
Get the install record file name, and ensure it’s location is prepared (ie. make it’s directory).
# File lib/setup/installer.rb, line 232 def install_record @install_record ||= ( file = INSTALL_RECORD dir = File.dirname(file) unless File.directory?(dir) FileUtils.mkdir_p(dir) end file ) end
# File lib/setup/installer.rb, line 274 def install_shebang(files, dir) files.each do |file| path = File.join(dir, File.basename(file)) update_shebang_line(path) end end
Install a directory.
# File lib/setup/installer.rb, line 187 def mkdir_p(dirname) #, prefix=nil) #dirname = destination(dirname) #dirname = File.join(prefix, File.expand_path(dirname)) if prefix return if File.directory?(dirname) io.puts "mkdir -p #{dirname}" if trace? or trial? return if trial? # Does not check '/', it's too abnormal. dirs = File.expand_path(dirname).split(%r<(?=/)>) if /\A[a-z]:\z/i =~ dirs[0] disk = dirs.shift dirs[0] = disk + dirs[0] end dirs.each_index do |idx| path = dirs[0..idx].join('') unless File.dir?(path) Dir.mkdir(path) end record_installation(path) # record directories made end end
# File lib/setup/installer.rb, line 309 def new_shebang(old) if /\Aruby/ =~ File.basename(old.cmd) Shebang.new(config.rubypath, old.args) elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' Shebang.new(config.rubypath, old.args[1..-1]) else return old unless config.shebang == 'all' Shebang.new(config.rubypath) end end
# File lib/setup/installer.rb, line 321 def open_atomic_writer(path, &block) tmpfile = File.basename(path) + '.tmp' begin File.open(tmpfile, 'wb', &block) File.rename tmpfile, File.basename(path) ensure File.unlink tmpfile if File.exist?(tmpfile) end end
Remove duplicates from the install record.
# File lib/setup/installer.rb, line 221 def prune_install_record entries = File.read(install_record).split("\n") entries.uniq! File.open(install_record, 'w') do |f| f << entries.join("\n") f << "\n" end end
Record that a file or directory was installed in the install record file.
# File lib/setup/installer.rb, line 213 def record_installation(path) File.open(install_record, 'a') do |f| f.puts(path) end #io.puts "installed #{path}" if trace? end
Display the file transfer taking place.
# File lib/setup/installer.rb, line 109 def report_transfer(source, directory) unless quiet? if install_prefix out = File.join(install_prefix, directory) else out = directory end io.puts "* #{source} -> #{out}" end end
Extract dynamic link libraries from all ext files.
# File lib/setup/installer.rb, line 134 def select_dllext(files) ents = files.select do |file| File.extname(file) == ".#{dllext}" end if ents.empty? && !files.empty? raise Error, "ruby extention not compiled: 'setup.rb compile' first" end ents end
# File lib/setup/installer.rb, line 282 def update_shebang_line(path) return if trial? return if config.shebang == 'never' old = Shebang.load(path) if old if old.args.size > 1 $stderr.puts "warning: #{path}" $stderr.puts "Shebang line has too many args." $stderr.puts "It is not portable and your program may not work." end new = new_shebang(old) return if new.to_s == old.to_s else return unless config.shebang == 'all' new = Shebang.new(config.rubypath) end $stderr.puts "updating shebang: #{File.basename(path)}" if trace? open_atomic_writer(path) do |output| File.open(path, 'rb') do |f| f.gets if old # discard output.puts new.to_s output.print f.read end end end