# class Chef::Provider::Package::Rubygems

### Attributes

cleanup_gem_env[R]
gem_env[R]

### Public Class Methods

new(new_resource, run_context=nil) click to toggle source
Calls superclass method Chef::Mixin::GetSourceFromPackage.new

    # File lib/chef/provider/package/rubygems.rb, line 366
    def initialize(new_resource, run_context=nil)
      super
      @cleanup_gem_env = true
      if new_resource.gem_binary
        if new_resource.options && new_resource.options.kind_of?(Hash)
          msg =  "options cannot be given as a hash when using an explicit gem_binary\n"
          msg << "in #{new_resource} from #{new_resource.source_line}"
          raise ArgumentError, msg
        end
        @gem_env = AlternateGemEnvironment.new(new_resource.gem_binary)
        Chef::Log.debug("#{@new_resource} using gem '#{new_resource.gem_binary}'")
      elsif is_omnibus? && (!@new_resource.instance_of? Chef::Resource::ChefGem)
        # Opscode Omnibus - The ruby that ships inside omnibus is only used for Chef
        # Default to installing somewhere more functional
        if new_resource.options && new_resource.options.kind_of?(Hash)
          msg = "options should be a string instead of a hash\n"
          msg << "in #{new_resource} from #{new_resource.source_line}"
          raise ArgumentError, msg
        end
        gem_location = find_gem_by_path
        @new_resource.gem_binary gem_location
        @gem_env = AlternateGemEnvironment.new(gem_location)
        Chef::Log.debug("#{@new_resource} using gem '#{gem_location}'")
      else
        @gem_env = CurrentGemEnvironment.new
        @cleanup_gem_env = false
        Chef::Log.debug("#{@new_resource} using gem from running ruby environment")
      end
    end

### Public Instance Methods

all_installed_versions() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 457
    def all_installed_versions
      @all_installed_versions ||= begin
        @gem_env.installed_versions(Gem::Dependency.new(gem_dependency.name, '>= 0'))
      end
    end

candidate_version() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 483
    def candidate_version
      @candidate_version ||= begin
        if target_version_already_installed?
          nil
        elsif source_is_remote?
          @gem_env.candidate_version_from_remote(gem_dependency, *gem_sources).to_s
        else
          @gem_env.candidate_version_from_file(gem_dependency, @new_resource.source).to_s
        end
      end
    end

cleanup_after_converge() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 476
    def cleanup_after_converge
      if @cleanup_gem_env
        logger.debug { "#{@new_resource} resetting gem environment to default" }
        Gem.clear_paths
      end
    end

current_version() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 433
    def current_version
      #raise 'todo'
      # If one or more matching versions are installed, the newest of them
      # is the current version
      if !matching_installed_versions.empty?
        gemspec = matching_installed_versions.last
        logger.debug { "#{@new_resource} found installed gem #{gemspec.name} version #{gemspec.version} matching #{gem_dependency}"}
        gemspec
      # If no version matching the requirements exists, the latest installed
      # version is the current version.
      elsif !all_installed_versions.empty?
        gemspec = all_installed_versions.last
        logger.debug { "#{@new_resource} newest installed version of gem #{gemspec.name} is #{gemspec.version}" }
        gemspec
      else
        logger.debug { "#{@new_resource} no installed version found for #{gem_dependency.to_s}"}
        nil
      end
    end

find_gem_by_path() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 410
    def find_gem_by_path
      Chef::Log.debug("#{@new_resource} searching for 'gem' binary in path: #{ENV['PATH']}")
      separator = ::File::ALT_SEPARATOR ? ::File::ALT_SEPARATOR : ::File::SEPARATOR
      path_to_first_gem = ENV['PATH'].split(::File::PATH_SEPARATOR).select { |path| ::File.exists?(path + separator + "gem") }.first
      raise Chef::Exceptions::FileNotFound, "Unable to find 'gem' binary in path: #{ENV['PATH']}" if path_to_first_gem.nil?
      path_to_first_gem + separator + "gem"
    end

gem_binary_path() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 527
    def gem_binary_path
      @new_resource.gem_binary || 'gem'
    end

gem_dependency() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 418
    def gem_dependency
      Gem::Dependency.new(@new_resource.package_name, @new_resource.version)
    end

gem_sources() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 463
    def gem_sources
      @new_resource.source ? Array(@new_resource.source) : nil
    end

install_package(name, version) click to toggle source

Installs the gem, using either the gems API or shelling out to `gem` according to the following criteria:

1. Use gems API (Gem::DependencyInstaller) by default

2. shell out to `gem install` when a String of options is given

3. use gems API with options if a hash of options is given

    # File lib/chef/provider/package/rubygems.rb, line 508
    def install_package(name, version)
      if source_is_remote? && @new_resource.gem_binary.nil?
        if @new_resource.options.nil?
          @gem_env.install(gem_dependency, :sources => gem_sources)
        elsif @new_resource.options.kind_of?(Hash)
          options = @new_resource.options
          options[:sources] = gem_sources
          @gem_env.install(gem_dependency, options)
        else
          install_via_gem_command(name, version)
        end
      elsif @new_resource.gem_binary.nil?
        @gem_env.install(@new_resource.source)
      else
        install_via_gem_command(name,version)
      end
      true
    end

install_via_gem_command(name, version) click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 531
    def install_via_gem_command(name, version)
      if @new_resource.source =~ /\.gem$/i
        name = @new_resource.source
      else
        src = @new_resource.source && "  --source=#{@new_resource.source} --source=http://rubygems.org"
      end
      if version
        shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
      else
        shell_out!("#{gem_binary_path} install \"#{name}\" -q --no-rdoc --no-ri #{src}#{opts}", :env=>nil)
      end
    end

is_omnibus?() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 396
    def is_omnibus?
      if RbConfig::CONFIG['bindir'] =~ %r/opt/(opscode|chef)/embedded/bin!
        Chef::Log.debug("#{@new_resource} detected omnibus installation in #{RbConfig::CONFIG['bindir']}")
        # Omnibus installs to a static path because of linking on unix, find it.
        true
      elsif RbConfig::CONFIG['bindir'].sub(/^[\w]:/, '')  == "/opscode/chef/embedded/bin"
        Chef::Log.debug("#{@new_resource} detected omnibus installation in #{RbConfig::CONFIG['bindir']}")
        # windows, with the drive letter removed
        true
      else
        false
      end
    end

load_current_resource() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 467
    def load_current_resource
      @current_resource = Chef::Resource::Package::GemPackage.new(@new_resource.name)
      @current_resource.package_name(@new_resource.package_name)
      if current_spec = current_version
        @current_resource.version(current_spec.version.to_s)
      end
      @current_resource
    end

logger() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 360
    def logger
      Chef::Log.logger
    end

matching_installed_versions() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 453
    def matching_installed_versions
      @matching_installed_versions ||= @gem_env.installed_versions(gem_dependency)
    end

purge_package(name, version) click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 570
    def purge_package(name, version)
      remove_package(name, version)
    end

remove_package(name, version) click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 548
    def remove_package(name, version)
      if @new_resource.gem_binary.nil?
        if @new_resource.options.nil?
          @gem_env.uninstall(name, version)
        elsif @new_resource.options.kind_of?(Hash)
          @gem_env.uninstall(name, version, @new_resource.options)
        else
          uninstall_via_gem_command(name, version)
        end
      else
        uninstall_via_gem_command(name, version)
      end
    end

source_is_remote?() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 422
    def source_is_remote?
      return true if @new_resource.source.nil?
      scheme = URI.parse(@new_resource.source).scheme
      # URI.parse gets confused by MS Windows paths with forward slashes.
      scheme = nil if scheme =~ /^[a-z]$/
      %w{http https}.include?(scheme)
    rescue URI::InvalidURIError
      Chef::Log.debug("#{@new_resource} failed to parse source '#{@new_resource.source}' as a URI, assuming a local path")
      false
    end

target_version_already_installed?() click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 495
    def target_version_already_installed?
      return false unless @current_resource && @current_resource.version
      return false if @current_resource.version.nil?

      Gem::Requirement.new(@new_resource.version).satisfied_by?(Gem::Version.new(@current_resource.version))
    end

uninstall_via_gem_command(name, version) click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 562
    def uninstall_via_gem_command(name, version)
      if version
        shell_out!("#{gem_binary_path} uninstall #{name} -q -x -I -v \"#{version}\"#{opts}", :env=>nil)
      else
        shell_out!("#{gem_binary_path} uninstall #{name} -q -x -I -a#{opts}", :env=>nil)
      end
    end

upgrade_package(name, version) click to toggle source

    # File lib/chef/provider/package/rubygems.rb, line 544
    def upgrade_package(name, version)
      install_package(name, version)
    end