class Setup::Installer

Installer class handles the actual install procedure.

NOTE: This new version does not support per-directory hooks.

Public Instance Methods

install() click to toggle source

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_bin() click to toggle source

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_data() click to toggle source

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_doc() click to toggle source

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_etc() click to toggle source

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_ext() click to toggle source

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_lib() click to toggle source

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_man() click to toggle source

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
install_prefix() click to toggle source
# File lib/setup/installer.rb, line 12
def install_prefix
  config.install_prefix
end

Private Instance Methods

binread(fname) click to toggle source

Binary read.

# File lib/setup/installer.rb, line 262
def binread(fname)
  File.open(fname, 'rb') do |f|
    return f.read
  end
end
destination(dir, file) click to toggle source

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
diff?(new_content, path) click to toggle source

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
directory?(path) click to toggle source

Comfirm a path is a directory and exists.

# File lib/setup/installer.rb, line 121
def directory?(path)
  File.directory?(path)
end
dllext() click to toggle source

Dynamic link library extension for this system.

# File lib/setup/installer.rb, line 145
def dllext
  config.dlext
  #Configuration::RBCONFIG['DLEXT']
end
files(dir) click to toggle source

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_file(dir, from, dest, mode, prefix=nil) click to toggle source

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_files(dir, list, dest, mode) click to toggle source

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
install_record() click to toggle source

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
install_shebang(files, dir) click to toggle source
# 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
mkdir_p(dirname) click to toggle source

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
new_shebang(old) click to toggle source
# 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
open_atomic_writer(path, &block) click to toggle source
# 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
prune_install_record() click to toggle source

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_installation(path) click to toggle source

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
report_transfer(source, directory) click to toggle source

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
select_dllext(files) click to toggle source

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
update_shebang_line(path) click to toggle source
# 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