Class: Chef::Cookbook::GemInstaller

Inherits:
Object
  • Object
show all
Includes:
Mixin::ShellOut
Defined in:
lib/chef/cookbook/gem_installer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ShellOut

apply_default_env, maybe_add_timeout, #shell_out, #shell_out!

Constructor Details

#initialize(cookbook_collection, events) ⇒ GemInstaller

Returns a new instance of GemInstaller.



30
31
32
33
# File 'lib/chef/cookbook/gem_installer.rb', line 30

def initialize(cookbook_collection, events)
  @cookbook_collection = cookbook_collection
  @events = events
end

Instance Attribute Details

#cookbook_collectionChef::CookbookCollection

Returns the cookbook collection.

Returns:



28
29
30
# File 'lib/chef/cookbook/gem_installer.rb', line 28

def cookbook_collection
  @cookbook_collection
end

#eventsChef::EventDispatch::Dispatcher

Returns the client event dispatcher.

Returns:



26
27
28
# File 'lib/chef/cookbook/gem_installer.rb', line 26

def events
  @events
end

Instance Method Details

#installObject

Installs the gems into the omnibus gemset.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/chef/cookbook/gem_installer.rb', line 37

def install
  cookbook_gems = Hash.new { |h, k| h[k] = [] }

  cookbook_collection.each_value do |cookbook_version|
    cookbook_version..gems.each do |args|
      if cookbook_gems[args.first].last.is_a?(Hash)
        args << {} unless args.last.is_a?(Hash)
        args.last.merge!(cookbook_gems[args.first].pop) do |key, v1, v2|
          raise Chef::Exceptions::GemRequirementConflict.new(args.first, key, v1, v2) if v1 != v2

          v2
        end
      end
      cookbook_gems[args.first] += args[1..-1]
    end
  end

  events.cookbook_gem_start(cookbook_gems)

  unless cookbook_gems.empty?
    begin
      Dir.mktmpdir("chef-gem-bundle") do |dir|
        File.open("#{dir}/Gemfile", "w+") do |tf|
          Array(Chef::Config[:rubygems_url] || "https://www.rubygems.org").each do |s|
            tf.puts "source '#{s}'"
          end
          cookbook_gems.each do |gem_name, args|
            tf.puts "gem(*#{([gem_name] + args).inspect})"
          end
          tf.close
          Chef::Log.trace("generated Gemfile contents:")
          Chef::Log.trace(IO.read(tf.path))
          # Skip installation only if Chef::Config[:skip_gem_metadata_installation] option is true
          unless Chef::Config[:skip_gem_metadata_installation]
            # Add additional options to bundle install
            cmd = [ "bundle", "install", Chef::Config[:gem_installer_bundler_options] ]
            so = shell_out!(cmd, cwd: dir, env: { "PATH" => path_with_prepended_ruby_bin })
            Chef::Log.info(so.stdout)
          end
        end
      end
      Gem.clear_paths
    rescue Exception => e
      events.cookbook_gem_failed(e)
      raise
    end
  end

  events.cookbook_gem_finished
end