class PoiseRuby::RubyBuild::Provider

Inversion provider for `ruby_runtime` to install via ruby-build.

@since 1.0.0 @provides ruby_build

Public Class Methods

default_inversion_options(node, resource) click to toggle source

Add default options for ruby-build.

@param node [Chef::Node] Node to load from. @param resource [Chef::Resource] Resource to load from. @return [Hash]

Calls superclass method
# File lib/poise_ruby/ruby_build/provider.rb, line 37
def self.default_inversion_options(node, resource)
  super.merge({
    install_doc: false,
    install_repo: 'https://github.com/sstephenson/ruby-build.git',
    install_rev: 'master',
    prefix: '/opt/ruby_build',
  })
end

Public Instance Methods

ruby_binary() click to toggle source

Path to the compiled Ruby binary.

@return [String]

# File lib/poise_ruby/ruby_build/provider.rb, line 49
def ruby_binary
  ::File.join(options['prefix'], 'builds', new_resource.name, 'bin', 'ruby')
end
ruby_definition() click to toggle source

Find the full definition name to use with ruby-build. This is based on prefix matching from the `ruby-build –definitions` output. Only public because sigh scoping.

@!visibility private @return [String]

# File lib/poise_ruby/ruby_build/provider.rb, line 59
def ruby_definition
  @ruby_definition ||= begin
    cmd = shell_out!([::File.join(options['prefix'], 'install', options['install_rev'], 'bin', 'ruby-build'), '--definitions'])
    version_prefix = options['version']
    # Default for '', look for MRI 2.x.
    version_prefix = '2' if version_prefix == ''
    # Find the last line that starts with the target version.
    cmd.stdout.split(/\n/).reverse.find {|line| line.start_with?(version_prefix) } || options['version']
  end
end

Private Instance Methods

build_ruby() click to toggle source

Compile Ruby using ruby-build.

@return [Chef::Resource::Execute]

# File lib/poise_ruby/ruby_build/provider.rb, line 177
def build_ruby
  # Figure out the argument to disable docs
  disable_docs = if options['install_doc']
    nil
  elsif options['version'].start_with?('rbx')
    nil # Doesn't support?
  elsif options['version'].start_with?('ree')
    '--no-dev-docs'
  else
    '--disable-install-doc'
  end

  execute 'ruby-build install' do
    command [::File.join(options['prefix'], 'install', options['install_rev'], 'bin', 'ruby-build'), ruby_definition, ::File.join(options['prefix'], 'builds', new_resource.name)]
    user 'root'
    environment 'RUBY_CONFIGURE_OPTS' => disable_docs if disable_docs
  end
end
create_builds_directory() click to toggle source

Create the directory to hold compiled rubies.

@return [Chef::Resource::Directory]

# File lib/poise_ruby/ruby_build/provider.rb, line 136
def create_builds_directory
  directory ::File.join(options['prefix'], 'builds') do
    owner 'root'
    group 'root'
    mode '755'
  end
end
create_install_directory() click to toggle source

Create the directory to hold ruby-build installations.

@return [Chef::Resource::Directory]

# File lib/poise_ruby/ruby_build/provider.rb, line 125
def create_install_directory
  directory ::File.join(options['prefix'], 'install') do
    owner 'root'
    group 'root'
    mode '755'
  end
end
create_prefix_directory() click to toggle source

Create the base prefix directory.

@return [Chef::Resource::Directory]

# File lib/poise_ruby/ruby_build/provider.rb, line 114
def create_prefix_directory
  directory options['prefix'] do
    owner 'root'
    group 'root'
    mode '755'
  end
end
create_version_file() click to toggle source

Write out the concrete version to the VERSION file.

@return [Chef::Resource::File]

# File lib/poise_ruby/ruby_build/provider.rb, line 199
def create_version_file
  file version_file do
    owner 'root'
    group 'root'
    mode '644'
    content ruby_definition
  end
end
install_dependencies() click to toggle source

Install dependency packages needed to compile Ruby. A no-op if `no_dependencies` is set.

@return [Chef::Resource::Package]

# File lib/poise_ruby/ruby_build/provider.rb, line 160
def install_dependencies
  return if options['no_dependencies']
  poise_build_essential 'build_essential'
  unless options['version'].start_with?('jruby')
    pkgs = node.value_for_platform_family(
      debian: %w{libreadline6-dev zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev libxml2-dev libxslt1-dev},
      rhel: %w{tar bzip2 readline-devel zlib-devel libffi-devel openssl-devel libxml2-devel libxslt-devel},
      suse: %w{zlib-devel libffi-devel sqlite3-devel libxml2-devel libxslt-devel},
    )
    package pkgs if pkgs
  end
end
install_ruby() click to toggle source

Installs ruby-build and then uses that to install Ruby.

@return [void]

# File lib/poise_ruby/ruby_build/provider.rb, line 83
def install_ruby
  # We assume that if the version_file exists, ruby-build is already
  # installed. Calling #ruby_definition will shell out to ruby-build.
  if ::File.exists?(version_file) && IO.read(version_file) == ruby_definition
    # All set, bail out.
    return
  end

  converge_by("Installing Ruby #{options['version'].empty? ? new_resource.name : options['version']} via ruby-build") do
    notifying_block do
      create_prefix_directory
      create_install_directory
      create_builds_directory
      install_ruby_build
      install_dependencies
      # Possible failed install or a version change. Wipe the existing build.
      # If we weren't going to rebuild, we would have bailed out already.
      uninstall_ruby
    end
    # Second converge has ruby-build installed so using #ruby_definition
    # is safe.
    notifying_block do
      build_ruby
      create_version_file
    end
  end
end
install_ruby_build() click to toggle source

Clone ruby-build from GitHub or a similar git server. Will also install git via the `git` cookbook unless `no_dependencies` is set.

@return [Chef::Resource::Git]

# File lib/poise_ruby/ruby_build/provider.rb, line 148
def install_ruby_build
  poise_git ::File.join(options['prefix'], 'install', options['install_rev']) do
    repository options['install_repo']
    revision options['install_rev']
    user 'root'
  end
end
uninstall_ruby() click to toggle source

Delete the compiled Ruby, but leave ruby-build installed as it may be shared by other resources.

@return [Chef::Resource::Directory]

# File lib/poise_ruby/ruby_build/provider.rb, line 212
def uninstall_ruby
  directory ::File.join(options['prefix'], 'builds', new_resource.name) do
    action :delete
  end
end
version_file() click to toggle source

Path to the version record file. Should contain the actual version of Ruby installed in this folder.

@return [String]

# File lib/poise_ruby/ruby_build/provider.rb, line 76
def version_file
  ::File.join(options['prefix'], 'builds', new_resource.name, 'VERSION')
end