<commit_before>require 'puppet/util/execution'

Puppet::Type.type(:ruby_gem).provide(:rubygems) do
  include Puppet::Util::Execution
  desc ""

  def self.gemlist
    return @gemlist if defined?(@gemlist)

    mapping = Hash.new

    Dir["/opt/rubies/*"].each do |ruby|
      v = File.basename(ruby)
      mapping[v] = Array.new

      Dir["#{ruby}/lib/ruby/gems/*/gems/*"].each do |g|
        mapping[v] << File.basename(g)
      end
    end

    @gemlist = mapping
  end

  def self.instances
    return @instances if defined?(@instances)

    all_gems = Array.new

    gemlist.each do |r, gems|

      gems.each do |g|

        gem_name, _, gem_version = g.rpartition("-")

        all_gems << new({
          :name         => "#{gem_name} for #{r}",
          :gem          => gem_name,
          :ensure       => :installed,
          :version      => gem_version,
          :ruby_version => r,
          :provider     => :rubygems,
        })
      end
    end

    @instances = all_gems
  end

  def gemlist
    self.class.gemlist
  end

  def instances
    self.class.instances
  end

  def query
    gems = Array.new

    if gemlist.has_key?(@resource[:ruby_version])
      gems = gemlist[@resource[:ruby_version]].map { |g|
        gem_name, _, gem_version = g.rpartition("-")
        {
          :gem => gem_name,
          :version => gem_version,
        }
      }
    end

    if inst = gems.detect { |g|
        g[:gem] == @resource[:gem] && requirement.satisfied_by?(version(g[:version]))
      }

      {
        :name         => "#{inst[:gem]} for #{inst[:ruby_version]}",
        :gem          => inst[:gem],
        :ensure       => :installed,
        :version      => inst[:version],
        :ruby_version => inst[:ruby_version],
      }
    else
      {
        :ensure       => :uninstalled,
        :name         => "#{@resource[:gem]} for #{@respource[:ruby_version]}",
        :gem          => @resource[:geme],
        :ruby_version => @resource[:ruby_version],
      }
    end
  rescue
    require "pry"
    binding.pry
  end

  def create
    gem "install '#{@resource[:gem]}' --version '#{@resource[:version]}' --source '#{@resource[:source]}'"
  end

  def destroy
    gem "uninstall '#{@resource[:gem]}' --version '#{@resource[:version]}'"
  end

private
  def requirement
    Gem::Requirement.new(@resource[:version])
  end

  def version(v)
    Gem::Version.new(v.to_s)
  end

  def gem(command)
    execute "gem #{command}", {
      :failonfail => true,
      :uid        => user,
      :custom_environment => {
        "PATH" => "/opt/rubies/#{ruby_version}/bin",
      }
    }
  end

  def user
    Facter.value(:boxen_user) || Facter.value(:id)<commit_msg>Don't install gems if we're offline<commit_after>require 'puppet/util/execution'

Puppet::Type.type(:ruby_gem).provide(:rubygems) do
  include Puppet::Util::Execution
  desc ""

  def self.gemlist
    return @gemlist if defined?(@gemlist)

    mapping = Hash.new

    Dir["/opt/rubies/*"].each do |ruby|
      v = File.basename(ruby)
      mapping[v] = Array.new

      Dir["#{ruby}/lib/ruby/gems/*/gems/*"].each do |g|
        mapping[v] << File.basename(g)
      end
    end

    @gemlist = mapping
  end

  def self.instances
    return @instances if defined?(@instances)

    all_gems = Array.new

    gemlist.each do |r, gems|

      gems.each do |g|

        gem_name, _, gem_version = g.rpartition("-")

        all_gems << new({
          :name         => "#{gem_name} for #{r}",
          :gem          => gem_name,
          :ensure       => :installed,
          :version      => gem_version,
          :ruby_version => r,
          :provider     => :rubygems,
        })
      end
    end

    @instances = all_gems
  end

  def gemlist
    self.class.gemlist
  end

  def instances
    self.class.instances
  end

  def query
    gems = Array.new

    if gemlist.has_key?(@resource[:ruby_version])
      gems = gemlist[@resource[:ruby_version]].map { |g|
        gem_name, _, gem_version = g.rpartition("-")
        {
          :gem => gem_name,
          :version => gem_version,
        }
      }
    end

    if inst = gems.detect { |g|
        g[:gem] == @resource[:gem] && requirement.satisfied_by?(version(g[:version]))
      }

      {
        :name         => "#{inst[:gem]} for #{inst[:ruby_version]}",
        :gem          => inst[:gem],
        :ensure       => :installed,
        :version      => inst[:version],
        :ruby_version => inst[:ruby_version],
      }
    else
      {
        :ensure       => :uninstalled,
        :name         => "#{@resource[:gem]} for #{@respource[:ruby_version]}",
        :gem          => @resource[:geme],
        :ruby_version => @resource[:ruby_version],
      }
    end
  rescue
    require "pry"
    binding.pry
  end

  def create
    if Facter.value(:offline) == "true"
      Puppet.warn("Can't install gems because we're offline")
    else
      gem "install '#{@resource[:gem]}' --version '#{@resource[:version]}' --source '#{@resource[:source]}'"
    end
  end

  def destroy
    gem "uninstall '#{@resource[:gem]}' --version '#{@resource[:version]}'"
  end

private
  def requirement
    Gem::Requirement.new(@resource[:version])
  end

  def version(v)
    Gem::Version.new(v.to_s)
  end

  def gem(command)
    execute "gem #{command}", {
      :failonfail => true,
      :uid        => user,
      :custom_environment => {
        "PATH" => "/opt/rubies/#{ruby_version}/bin",
      }
    }
  end

  def user
    Facter.value(:boxen_user) || Facter.value(:id)
{'fraction_non_alphanumeric': 0.15669618651726008, 'fraction_numerical': 0.0, 'mean_word_length': 2.0744444444444445, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7576125', 'n_tokens_mistral': 1894, 'n_tokens_neox': 1796, 'n_words': 367}