class Chef::Cookbook::GemInstaller
def initialize(cookbook_collection, events)
def initialize(cookbook_collection, events) @cookbook_collection = cookbook_collection @events = events end
def install
Installs the gems into the omnibus gemset.
def install cookbook_gems = Hash.new { |h, k| h[k] = [] } cookbook_collection.each_value do |cookbook_version| cookbook_version.metadata.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..] 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://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] ] env = { "PATH" => path_with_prepended_ruby_bin, "BUNDLE_SILENCE_ROOT_WARNING" => "1", } so = shell_out!(cmd, cwd: dir, env: env) 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
def path_with_prepended_ruby_bin
def path_with_prepended_ruby_bin env_path = ENV["PATH"].dup || "" existing_paths = env_path.split(File::PATH_SEPARATOR) existing_paths.unshift(RbConfig::CONFIG["bindir"]) env_path = existing_paths.join(File::PATH_SEPARATOR) env_path.encode("utf-8", invalid: :replace, undef: :replace) end