diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5dafc58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.lock +.kitchen diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..6b8384e --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,45 @@ +--- +driver: + name: vagrant + customize: + cpus: 2 + memory: 1024 + cpuexecutioncap: 75 + +provisioner: + name: chef_solo + require_chef_omnibus: 12 + +platforms: + - name: ubuntu-14.04 + driver: + name: vagrant + driver_config: + gui: true + +suites: + - name: testkitchen_ruby_ng_cookbook_default_versions + run_list: + - recipe[ruby-ng_test] + - recipe[minitest-handler] + attributes: + minitest: + recipes: + - ruby-ng_test::default + ruby-ng: + ruby_version: 2.3 + - name: testkitchen_ruby_ng_cookbook_specific_versions + run_list: + - recipe[ruby-ng_test] + - recipe[minitest-handler] + attributes: + minitest: + recipes: + - ruby-ng_test::specific_versions + ruby-ng: + ruby_version: 2.3 + ruby_package_version: "2.3.5-1bbox2~trusty1" + hold_ruby_packages: true + # 1.15.4 is the newest table version as of 09/21/2017, but we are testing + # if we can install a specific older version. + bundler_version: 1.15.3 diff --git a/Berksfile b/Berksfile new file mode 100644 index 0000000..20c60a1 --- /dev/null +++ b/Berksfile @@ -0,0 +1,8 @@ +source 'https://api.berkshelf.com' + +metadata + +group :integration do + cookbook 'minitest-handler' + cookbook 'ruby-ng_test', path: 'test/cookbooks/ruby-ng_test' +end diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..ef13f0b --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +group :integration do + gem 'berkshelf' + gem 'test-kitchen', '~> 1.3' + gem 'kitchen-vagrant' +end diff --git a/attributes/default.rb b/attributes/default.rb index 606d373..ac679e8 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,2 +1,15 @@ default['ruby-ng']['experimental'] = false default['ruby-ng']['ruby_version'] = '2.1' + +# If this is set to "latest", Bundler is upgraded to the latest version. If this is not set, +# the existing (potentially outdated) version of Bundler is kept. +default['ruby-ng']['bundler_version'] = 'latest' + +# Likewise for the ruby packages themselves. However, this setting +# defaults to keeping the first version installed. +default['ruby-ng']['ruby_package_version'] = nil + +# Whether to hold the ruby package(s) after installation. Holding +# prevents the packages from being upgraded externally, e.g. +# when running apt-get update at the CLI. +default['ruby-ng']['hold_ruby_packages'] = false diff --git a/metadata.rb b/metadata.rb index 80e91e7..b2d5e8f 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'MIT' description 'Installs Ruby from brightbox/ruby-ng PPA' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.3.0' +version '0.4.0' supports 'ubuntu' diff --git a/recipes/default.rb b/recipes/default.rb index 886752e..2cfd8e8 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -22,9 +22,31 @@ pin_priority '666' end -package "ruby#{node['ruby-ng']['ruby_version']}" +v = node['ruby-ng']['ruby_version'] + +execute "hold ruby#{v} package" do + command "apt-mark hold ruby#{v}" + action :nothing +end + +package "ruby#{v}" do + if node['ruby-ng']['ruby_package_version'] + version node['ruby-ng']['ruby_package_version'] + end + + if node['ruby-ng']['hold_ruby_packages'] + notifies :run, "execute[hold ruby#{v} package]", :immediate + end +end + +bundler_version = node['ruby-ng']['bundler_version'] gem_package 'bundler' do gem_binary '/usr/bin/gem' options '-n /usr/bin' + if bundler_version == 'latest' + action :upgrade + elsif bundler_version + version bundler_version + end end diff --git a/recipes/dev.rb b/recipes/dev.rb index d1f206d..41e5ebd 100644 --- a/recipes/dev.rb +++ b/recipes/dev.rb @@ -1,4 +1,19 @@ include_recipe 'build-essential' include_recipe 'ruby-ng::default' -package "ruby#{node['ruby-ng']['ruby_version']}-dev" +v = node['ruby-ng']['ruby_version'] + +execute "hold ruby#{v}-dev package" do + command "apt-mark hold ruby#{v}-dev" + action :nothing +end + +package "ruby#{v}-dev" do + if node['ruby-ng']['ruby_package_version'] + version node['ruby-ng']['ruby_package_version'] + end + + if node['ruby-ng']['hold_ruby_packages'] + notifies :run, "execute[hold ruby#{v}-dev package]", :immediate + end +end diff --git a/test/cookbooks/ruby-ng_test/files/default/tests/minitest/default_test.rb b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/default_test.rb new file mode 100644 index 0000000..41ab8d1 --- /dev/null +++ b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/default_test.rb @@ -0,0 +1,23 @@ +require_relative 'helpers' + +describe_recipe "ruby-ng::default" do + include Helpers::RubyNgTests + + it 'Installs the ruby package' do + package("ruby#{node['ruby-ng']['ruby_version']}").must_be_installed + end + + it 'Installs the bundler gem' do + shell_out!('gem list bundler').stdout.must_match(/bundler \(/) + end +end + +describe_recipe "ruby-ng::dev" do + it 'Installs the ruby-dev package' do + package("ruby#{node['ruby-ng']['ruby_version']}-dev").must_be_installed + end + + it 'Installs the build-essential package' do + package('build-essential').must_be_installed + end +end diff --git a/test/cookbooks/ruby-ng_test/files/default/tests/minitest/helpers.rb b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/helpers.rb new file mode 100644 index 0000000..916d6b1 --- /dev/null +++ b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/helpers.rb @@ -0,0 +1,11 @@ +module Helpers + module RubyNgTests + require 'chef/mixin/shell_out' + + include Chef::Mixin::ShellOut + include MiniTest::Chef::Assertions + include MiniTest::Chef::Context + include MiniTest::Chef::Resources + end +end + diff --git a/test/cookbooks/ruby-ng_test/files/default/tests/minitest/specific_versions_test.rb b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/specific_versions_test.rb new file mode 100644 index 0000000..1c423e1 --- /dev/null +++ b/test/cookbooks/ruby-ng_test/files/default/tests/minitest/specific_versions_test.rb @@ -0,0 +1,41 @@ +require_relative 'helpers' + +describe_recipe "ruby-ng::default" do + include Helpers::RubyNgTests + + it 'Installs the ruby package' do + package("ruby#{node['ruby-ng']['ruby_version']}").must_be_installed.with(:version, [node['ruby-ng']['ruby_package_version']]) + end + + it 'holds the ruby-dev package' do + shell_out!('apt-mark showhold').stdout.must_match("ruby#{node['ruby-ng']['ruby_version']}-dev") + end + + # This test requires that node['ruby-ng']['bundler_version'] is set to a specific value, not to + # "latest". + it 'Installs the correct version of the bundler gem' do + cmd = 'gem list bundler' + gem_list_bundler_output = shell_out!(cmd).stdout + bundler_version = node['ruby-ng']['bundler_version'] + assert( + gem_list_bundler_output.include?("bundler (#{bundler_version})"), + "Expected bundler version #{bundler_version} " \ + "to be the only version reported in the results of command '#{cmd}'") + end +end + +describe_recipe "ruby-ng::dev" do + include Helpers::RubyNgTests + + it 'Installs the ruby-dev package' do + package("ruby#{node['ruby-ng']['ruby_version']}-dev").must_be_installed.with(:version, [node['ruby-ng']['ruby_package_version']]) + end + + it 'holds the ruby-dev package' do + shell_out!('apt-mark showhold').stdout.must_match("ruby#{node['ruby-ng']['ruby_version']}-dev") + end + + it 'Installs the build-essential package' do + package('build-essential').must_be_installed + end +end diff --git a/test/cookbooks/ruby-ng_test/metadata.rb b/test/cookbooks/ruby-ng_test/metadata.rb new file mode 100644 index 0000000..e9eec18 --- /dev/null +++ b/test/cookbooks/ruby-ng_test/metadata.rb @@ -0,0 +1,6 @@ +name 'ruby-ng_test' +description 'This cookbook is used with test-kitchen to test the parent cookbook, ruby-ng' +version '0.1.0' + +depends 'ruby-ng' + diff --git a/test/cookbooks/ruby-ng_test/recipes/default.rb b/test/cookbooks/ruby-ng_test/recipes/default.rb new file mode 100644 index 0000000..85e7ec4 --- /dev/null +++ b/test/cookbooks/ruby-ng_test/recipes/default.rb @@ -0,0 +1,2 @@ +include_recipe 'ruby-ng' +include_recipe 'ruby-ng::dev'