summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@may.lt>2017-04-03 08:03:35 +0100
committerGitHub <noreply@github.com>2017-04-03 08:03:35 +0100
commit7b6ee3a816a4dfc71b239efe43641f01107aa094 (patch)
tree6294d3064db2ff511b12d5399dbeb79221db37ea
parent2d1d59afe0ec393c31dce6caabc8c85aaa7bba58 (diff)
parent0a943849f8b8866b7d38f3e76906aa14770ab051 (diff)
downloadchef-7b6ee3a816a4dfc71b239efe43641f01107aa094.tar.gz
Merge pull request #5942 from criteo-forks/fix_gem_installer
Fix cookbook gem installer
-rw-r--r--lib/chef/cookbook/gem_installer.rb10
-rw-r--r--spec/unit/cookbook/gem_installer_spec.rb70
2 files changed, 76 insertions, 4 deletions
diff --git a/lib/chef/cookbook/gem_installer.rb b/lib/chef/cookbook/gem_installer.rb
index df73ce3ee4..365b185426 100644
--- a/lib/chef/cookbook/gem_installer.rb
+++ b/lib/chef/cookbook/gem_installer.rb
@@ -36,10 +36,12 @@ class Chef
# Installs the gems into the omnibus gemset.
#
def install
- cookbook_gems = []
+ cookbook_gems = Hash.new { |h, k| h[k] = [] }
cookbook_collection.each do |cookbook_name, cookbook_version|
- cookbook_gems += cookbook_version.metadata.gems
+ cookbook_version.metadata.gems.each do |args|
+ cookbook_gems[args.first] += args[1..-1]
+ end
end
events.cookbook_gem_start(cookbook_gems)
@@ -49,8 +51,8 @@ class Chef
Dir.mktmpdir("chef-gem-bundle") do |dir|
File.open("#{dir}/Gemfile", "w+") do |tf|
tf.puts "source '#{Chef::Config[:rubygems_url]}'"
- cookbook_gems.each do |args|
- tf.puts "gem(*#{args.inspect})"
+ cookbook_gems.each do |gem_name, args|
+ tf.puts "gem(*#{([gem_name] + args).inspect})"
end
tf.close
Chef::Log.debug("generated Gemfile contents:")
diff --git a/spec/unit/cookbook/gem_installer_spec.rb b/spec/unit/cookbook/gem_installer_spec.rb
new file mode 100644
index 0000000000..69b714d977
--- /dev/null
+++ b/spec/unit/cookbook/gem_installer_spec.rb
@@ -0,0 +1,70 @@
+require "spec_helper"
+require "bundler/dsl"
+
+describe Chef::Cookbook::GemInstaller do
+ let(:cookbook_collection) do
+ {
+ test: double(
+ :cookbook,
+ metadata: double(
+ :metadata,
+ gems: [["httpclient"], ["nokogiri"]]
+ )
+ ),
+ test2: double(
+ :cookbook,
+ metadata: double(
+ :metadata,
+ gems: [["httpclient", ">= 2.0"]]
+ )
+ ),
+ test3: double(
+ :cookbook,
+ metadata: double(
+ :metadata,
+ gems: [["httpclient", ">= 1.0"]]
+ )
+ ),
+ }
+ end
+
+ let(:gem_installer) do
+ described_class.new(cookbook_collection, Chef::EventDispatch::Dispatcher.new)
+ end
+
+ let(:gemfile) do
+ StringIO.new
+ end
+
+ let(:shell_out) do
+ double(:shell_out, stdout: "")
+ end
+
+ let(:bundler_dsl) do
+ b = Bundler::Dsl.new
+ b.instance_eval(gemfile.string)
+ b
+ end
+
+ before(:each) do
+ # Prepare mocks: using a StringIO instead of a File
+ expect(Dir).to receive(:mktmpdir).and_yield("")
+ expect(File).to receive(:open).and_yield(gemfile)
+ expect(gemfile).to receive(:path).and_return("")
+ expect(IO).to receive(:read).and_return("")
+ expect(gem_installer).to receive(:shell_out!).and_return(shell_out)
+
+ end
+
+ it "generates a valid Gemfile" do
+ expect { gem_installer.install }.to_not raise_error
+
+ expect { bundler_dsl }.to_not raise_error
+ end
+
+ it "generate a Gemfile with all constraints" do
+ expect { gem_installer.install }.to_not raise_error
+
+ expect(bundler_dsl.dependencies.find { |d| d.name == "httpclient" }.requirements_list.length).to eql(2)
+ end
+end