summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McLellan <btm@opscode.com>2013-11-26 10:55:21 -0800
committerBryan McLellan <btm@opscode.com>2013-11-26 10:55:21 -0800
commitac528c3f9871c2c35c53d313340726fde16d3936 (patch)
treea41671b2d699d648c1d0bcd7476d2828f158a3f9
parent609701d408e49c27612bd321eaa1d467c2a088dd (diff)
parent8d9e96ab5fb4c8381755a252e83d445bcc8a958a (diff)
downloadchef-ac528c3f9871c2c35c53d313340726fde16d3936.tar.gz
Merge branch 'contributions'
-rw-r--r--chef.gemspec1
-rw-r--r--lib/chef/application/apply.rb6
-rw-r--r--lib/chef/application/solo.rb2
-rw-r--r--lib/chef/client.rb19
-rw-r--r--lib/chef/cookbook_uploader.rb10
-rw-r--r--lib/chef/knife/cookbook_upload.rb8
-rw-r--r--lib/chef/knife/data_bag_create.rb7
-rw-r--r--lib/chef/knife/environment_compare.rb10
-rw-r--r--lib/chef/mixin/command.rb23
-rw-r--r--lib/chef/provider/cron.rb2
-rw-r--r--lib/chef/provider/git.rb28
-rw-r--r--lib/chef/resource/deploy.rb18
-rw-r--r--lib/chef/resource/scm.rb18
-rw-r--r--spec/unit/client_spec.rb14
-rw-r--r--spec/unit/knife/cookbook_upload_spec.rb14
-rw-r--r--spec/unit/knife/data_bag_create_spec.rb7
-rw-r--r--spec/unit/knife/environment_compare_spec.rb49
-rw-r--r--spec/unit/provider/cron_spec.rb6
-rw-r--r--spec/unit/provider/git_spec.rb32
-rw-r--r--spec/unit/resource/scm_spec.rb10
20 files changed, 223 insertions, 61 deletions
diff --git a/chef.gemspec b/chef.gemspec
index b65ec62d9b..4a05be1d11 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
s.email = "adam@opscode.com"
s.homepage = "http://wiki.opscode.com/display/chef"
+ s.add_dependency "mime-types", "~> 1.25"
s.add_dependency "mixlib-config", "~> 2.0"
s.add_dependency "mixlib-cli", "~> 1.3"
s.add_dependency "mixlib-log", "~> 1.3"
diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb
index 9bffa4824e..dfec31c51e 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -74,6 +74,12 @@ class Chef::Application::Apply < Chef::Application
:description => 'Enable whyrun mode',
:boolean => true
+ option :color,
+ :long => '--[no-]color',
+ :boolean => true,
+ :default => !Chef::Platform.windows?,
+ :description => "Use colored output, defaults to enabled"
+
def initialize
super
end
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 47825a9701..dc8a3588ad 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -55,7 +55,7 @@ class Chef::Application::Solo < Chef::Application
option :color,
:long => '--[no-]color',
:boolean => true,
- :default => true,
+ :default => !Chef::Platform.windows?,
:description => "Use colored output, defaults to enabled"
option :log_level,
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 30b714cded..6a39395bb6 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -543,8 +543,8 @@ class Chef
end
end
- def directory_not_empty?(path)
- File.exists?(path) && (Dir.entries(path).size > 2)
+ def empty_directory?(path)
+ !File.exists?(path) || (Dir.entries(path).size <= 2)
end
def is_last_element?(index, object)
@@ -556,15 +556,12 @@ class Chef
# Check for cookbooks in the path given
# Chef::Config[:cookbook_path] can be a string or an array
# if it's an array, go through it and check each one, raise error at the last one if no files are found
- Chef::Log.debug "Loading from cookbook_path: #{Array(Chef::Config[:cookbook_path]).map { |path| File.expand_path(path) }.join(', ')}"
- Array(Chef::Config[:cookbook_path]).each_with_index do |cookbook_path, index|
- if directory_not_empty?(cookbook_path)
- break
- else
- msg = "No cookbook found in #{Chef::Config[:cookbook_path].inspect}, make sure cookbook_path is set correctly."
- Chef::Log.fatal(msg)
- raise Chef::Exceptions::CookbookNotFound, msg if is_last_element?(index, Chef::Config[:cookbook_path])
- end
+ cookbook_paths = Array(Chef::Config[:cookbook_path])
+ Chef::Log.debug "Loading from cookbook_path: #{cookbook_paths.map { |path| File.expand_path(path) }.join(', ')}"
+ if cookbook_paths.all? {|path| empty_directory?(path) }
+ msg = "None of the cookbook paths set in Chef::Config[:cookbook_path], #{cookbook_paths.inspect}, contain any cookbooks"
+ Chef::Log.fatal(msg)
+ raise Chef::Exceptions::CookbookNotFound, msg
end
else
Chef::Log.warn("Node #{node_name} has an empty run list.") if run_context.node.run_list.empty?
diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb
index acd913e72c..2ae4703f01 100644
--- a/lib/chef/cookbook_uploader.rb
+++ b/lib/chef/cookbook_uploader.rb
@@ -17,10 +17,10 @@ class Chef
@work_queue ||= Queue.new
end
- def self.setup_worker_threads
+ def self.setup_worker_threads(concurrency=10)
@worker_threads ||= begin
work_queue
- (1...10).map do
+ (1...concurrency).map do
Thread.new do
loop do
work_queue.pop.call
@@ -34,6 +34,7 @@ class Chef
attr_reader :path
attr_reader :opts
attr_reader :rest
+ attr_reader :concurrency
# Creates a new CookbookUploader.
# ===Arguments:
@@ -50,10 +51,13 @@ class Chef
# * :rest A Chef::REST object that you have configured the way you like it.
# If you don't provide this, one will be created using the values
# in Chef::Config.
+ # * :concurrency An integer that decided how many threads will be used to
+ # perform concurrent uploads
def initialize(cookbooks, path, opts={})
@path, @opts = path, opts
@cookbooks = Array(cookbooks)
@rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
+ @concurrency = opts[:concurrency] || 10
end
def upload_cookbooks
@@ -73,7 +77,7 @@ class Chef
Chef::Log.info("Uploading files")
- self.class.setup_worker_threads
+ self.class.setup_worker_threads(concurrency)
checksums_to_upload = Set.new
diff --git a/lib/chef/knife/cookbook_upload.rb b/lib/chef/knife/cookbook_upload.rb
index d4a66e6925..a882cd7109 100644
--- a/lib/chef/knife/cookbook_upload.rb
+++ b/lib/chef/knife/cookbook_upload.rb
@@ -57,6 +57,12 @@ class Chef
:boolean => true,
:description => "Update cookbook versions even if they have been frozen"
+ option :concurrency,
+ :long => '--concurrency NUMBER_OF_THREADS',
+ :description => "How many concurrent threads will be used",
+ :default => 10,
+ :proc => lambda { |o| o.to_i }
+
option :environment,
:short => '-E',
:long => '--environment ENVIRONMENT',
@@ -228,7 +234,7 @@ WARNING
check_for_broken_links!(cb)
check_for_dependencies!(cb)
end
- Chef::CookbookUploader.new(cookbooks, config[:cookbook_path], :force => config[:force]).upload_cookbooks
+ Chef::CookbookUploader.new(cookbooks, config[:cookbook_path], :force => config[:force], :concurrency => config[:concurrency]).upload_cookbooks
rescue Chef::Exceptions::CookbookFrozen => e
ui.error e
raise
diff --git a/lib/chef/knife/data_bag_create.rb b/lib/chef/knife/data_bag_create.rb
index 55c1c71798..bc49c68448 100644
--- a/lib/chef/knife/data_bag_create.rb
+++ b/lib/chef/knife/data_bag_create.rb
@@ -67,6 +67,13 @@ class Chef
exit 1
end
+ begin
+ Chef::DataBag.validate_name!(@data_bag_name)
+ rescue Chef::Exceptions::InvalidDataBagName => e
+ ui.fatal(e.message)
+ exit(1)
+ end
+
# create the data bag
begin
rest.post_rest("data", { "name" => @data_bag_name })
diff --git a/lib/chef/knife/environment_compare.rb b/lib/chef/knife/environment_compare.rb
index 21160e8ac3..792ec444ea 100644
--- a/lib/chef/knife/environment_compare.rb
+++ b/lib/chef/knife/environment_compare.rb
@@ -27,7 +27,13 @@ class Chef
end
banner "knife environment compare [ENVIRONMENT..] (options)"
-
+
+ option :all,
+ :short => "-a",
+ :long => "--all",
+ :description => "Show all cookbooks",
+ :boolean => true
+
option :mismatch,
:short => "-m",
:long => "--mismatch",
@@ -51,7 +57,7 @@ class Chef
end
# Get all cookbooks so we can compare them all
- cookbooks = rest.get_rest("/cookbooks?num_versions=1")
+ cookbooks = rest.get_rest("/cookbooks?num_versions=1") if config[:all]
# display matrix view of in the requested format.
if config[:format] == 'summary'
diff --git a/lib/chef/mixin/command.rb b/lib/chef/mixin/command.rb
index fb75980f8f..c92315e718 100644
--- a/lib/chef/mixin/command.rb
+++ b/lib/chef/mixin/command.rb
@@ -144,19 +144,18 @@ class Chef
end
def handle_command_failures(status, command_output, opts={})
- unless opts[:ignore_failure]
- opts[:returns] ||= 0
- unless Array(opts[:returns]).include?(status.exitstatus)
- # if the log level is not debug, through output of command when we fail
- output = ""
- if Chef::Log.level == :debug || opts[:output_on_failure]
- output << "\n---- Begin output of #{opts[:command]} ----\n"
- output << command_output.to_s
- output << "\n---- End output of #{opts[:command]} ----\n"
- end
- raise Chef::Exceptions::Exec, "#{opts[:command]} returned #{status.exitstatus}, expected #{opts[:returns]}#{output}"
- end
+ return if opts[:ignore_failure]
+ opts[:returns] ||= 0
+ return if Array(opts[:returns]).include?(status.exitstatus)
+
+ # if the log level is not debug, through output of command when we fail
+ output = ""
+ if Chef::Log.level == :debug || opts[:output_on_failure]
+ output << "\n---- Begin output of #{opts[:command]} ----\n"
+ output << command_output.to_s
+ output << "\n---- End output of #{opts[:command]} ----\n"
end
+ raise Chef::Exceptions::Exec, "#{opts[:command]} returned #{status.exitstatus}, expected #{opts[:returns]}#{output}"
end
# Call #run_command but set LC_ALL to the system's current environment so it doesn't get changed to C.
diff --git a/lib/chef/provider/cron.rb b/lib/chef/provider/cron.rb
index f6f062a410..87452b4872 100644
--- a/lib/chef/provider/cron.rb
+++ b/lib/chef/provider/cron.rb
@@ -85,7 +85,7 @@ class Chef
def cron_different?
CRON_ATTRIBUTES.any? do |cron_var|
- !@new_resource.send(cron_var).nil? && @new_resource.send(cron_var) != @current_resource.send(cron_var)
+ @new_resource.send(cron_var) != @current_resource.send(cron_var)
end
end
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb
index b22004eda0..e77948d367 100644
--- a/lib/chef/provider/git.rb
+++ b/lib/chef/provider/git.rb
@@ -17,6 +17,7 @@
#
+require 'chef/exceptions'
require 'chef/log'
require 'chef/provider'
require 'chef/mixin/shell_out'
@@ -75,7 +76,9 @@ class Chef
def action_checkout
if target_dir_non_existent_or_empty?
clone
- checkout
+ if @new_resource.enable_checkout
+ checkout
+ end
enable_submodules
add_remotes
else
@@ -151,10 +154,11 @@ class Chef
def checkout
sha_ref = target_revision
+
converge_by("checkout ref #{sha_ref} branch #{@new_resource.revision}") do
# checkout into a local branch rather than a detached HEAD
- shell_out!("git checkout -b deploy #{sha_ref}", run_options(:cwd => @new_resource.destination))
- Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} reference: #{sha_ref}"
+ shell_out!("git checkout -b #{@new_resource.checkout_branch} #{sha_ref}", run_options(:cwd => @new_resource.destination))
+ Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} onto: #{@new_resource.checkout_branch} reference: #{sha_ref}"
end
end
@@ -269,12 +273,26 @@ class Chef
private
def run_options(run_opts={})
- run_opts[:user] = @new_resource.user if @new_resource.user
+ env = {}
+ if @new_resource.user
+ run_opts[:user] = @new_resource.user
+ # Certain versions of `git` misbehave if git configuration is
+ # inaccessible in $HOME. We need to ensure $HOME matches the
+ # user who is executing `git` not the user running Chef.
+ env['HOME'] = begin
+ require 'etc'
+ Etc.getpwnam(@new_resource.user).dir
+ rescue ArgumentError # user not found
+ raise Chef::Exceptions::User, "Could not determine HOME for specified user '#{@new_resource.user}' for resource '#{@new_resource.name}'"
+ end
+ end
run_opts[:group] = @new_resource.group if @new_resource.group
- run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
+ env['GIT_SSH'] = @new_resource.ssh_wrapper if @new_resource.ssh_wrapper
run_opts[:log_tag] = @new_resource.to_s
run_opts[:timeout] = @new_resource.timeout if @new_resource.timeout
+ run_opts[:environment] = env unless env.empty?
run_opts
+
end
def cwd
diff --git a/lib/chef/resource/deploy.rb b/lib/chef/resource/deploy.rb
index 76478ed07c..a08e8aeeea 100644
--- a/lib/chef/resource/deploy.rb
+++ b/lib/chef/resource/deploy.rb
@@ -81,6 +81,8 @@ class Chef
@allowed_actions.push(:force_deploy, :deploy, :rollback)
@additional_remotes = Hash[]
@keep_releases = 5
+ @enable_checkout = true
+ @checkout_branch = "deploy"
end
# where the checked out/cloned code goes
@@ -398,6 +400,22 @@ class Chef
)
end
+ def enable_checkout(arg=nil)
+ set_or_return(
+ :enable_checkout,
+ arg,
+ :kind_of => [TrueClass, FalseClass]
+ )
+ end
+
+ def checkout_branch(arg=nil)
+ set_or_return(
+ :checkout_branch,
+ arg,
+ :kind_of => String
+ )
+ end
+
# FIXME The Deploy resource may be passed to an SCM provider as its
# resource. The SCM provider knows that SCM resources can specify a
# timeout for SCM operations. The deploy resource must therefore support
diff --git a/lib/chef/resource/scm.rb b/lib/chef/resource/scm.rb
index d9a372900e..91782e4114 100644
--- a/lib/chef/resource/scm.rb
+++ b/lib/chef/resource/scm.rb
@@ -32,12 +32,14 @@ class Chef
@destination = name
@resource_name = :scm
@enable_submodules = false
+ @enable_checkout = true
@revision = "HEAD"
@remote = "origin"
@ssh_wrapper = nil
@depth = nil
@allowed_actions.push(:checkout, :export, :sync, :diff, :log)
@action = [:sync]
+ @checkout_branch = "deploy"
end
def destination(arg=nil)
@@ -130,6 +132,14 @@ class Chef
)
end
+ def enable_checkout(arg=nil)
+ set_or_return(
+ :enable_checkout,
+ arg,
+ :kind_of => [TrueClass, FalseClass]
+ )
+ end
+
def remote(arg=nil)
set_or_return(
:remote,
@@ -154,6 +164,14 @@ class Chef
)
end
+ def checkout_branch(arg=nil)
+ set_or_return(
+ :checkout_branch,
+ arg,
+ :kind_of => String
+ )
+ end
+
end
end
end
diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb
index 11c887d734..eb705e0386 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -447,6 +447,20 @@ shared_examples_for Chef::Client do
end
end
+ describe "assert_cookbook_path_not_empty" do
+ before do
+ Chef::Config[:solo] = true
+ Chef::Config[:cookbook_path] = ["/path/to/invalid/cookbook_path"]
+ end
+ context "when any directory of cookbook_path contains no cookbook" do
+ it "raises CookbookNotFound error" do
+ expect do
+ @client.send(:assert_cookbook_path_not_empty, nil)
+ end.to raise_error(Chef::Exceptions::CookbookNotFound, 'None of the cookbook paths set in Chef::Config[:cookbook_path], ["/path/to/invalid/cookbook_path"], contain any cookbooks')
+ end
+ end
+ end
+
end
describe Chef::Client do
diff --git a/spec/unit/knife/cookbook_upload_spec.rb b/spec/unit/knife/cookbook_upload_spec.rb
index d9f1b8f1ce..5572430b50 100644
--- a/spec/unit/knife/cookbook_upload_spec.rb
+++ b/spec/unit/knife/cookbook_upload_spec.rb
@@ -40,6 +40,20 @@ describe Chef::Knife::CookbookUpload do
@knife.ui.stub!(:stderr).and_return(@output)
end
+ describe 'with --concurrency' do
+ it 'should upload cookbooks with predefined concurrency' do
+ @cookbook_uploader = stub(:upload_cookbooks => nil)
+ Chef::CookbookVersion.stub(:list_all_versions).and_return({})
+ @knife.config[:concurrency] = 3
+ @test_cookbook = Chef::CookbookVersion.new('test_cookbook')
+ @cookbook_loader.stub!(:each).and_yield("test_cookbook", @test_cookbook)
+ @cookbook_loader.stub!(:cookbook_names).and_return(["test_cookbook"])
+ Chef::CookbookUploader.should_receive(:new).with( kind_of(Array), kind_of(Array),
+ {:force=>nil, :concurrency => 3}).and_return(double("Chef::CookbookUploader", :upload_cookbooks=> true))
+ @knife.run
+ end
+ end
+
describe 'run' do
before(:each) do
@cookbook_uploader = stub(:upload_cookbooks => nil)
diff --git a/spec/unit/knife/data_bag_create_spec.rb b/spec/unit/knife/data_bag_create_spec.rb
index 0ac9b6f033..b2f24bbb39 100644
--- a/spec/unit/knife/data_bag_create_spec.rb
+++ b/spec/unit/knife/data_bag_create_spec.rb
@@ -53,6 +53,13 @@ describe Chef::Knife::DataBagCreate do
@knife.run
end
+ it "tries to create a data bag with an invalid name when given one argument" do
+ @knife.name_args = ['invalid&char']
+ @knife.should_receive(:exit).with(1)
+
+ @knife.run
+ end
+
it "creates a data bag item when given two arguments" do
@knife.name_args = ['sudoing_admins', 'ME']
user_supplied_hash = {"login_name" => "alphaomega", "id" => "ME"}
diff --git a/spec/unit/knife/environment_compare_spec.rb b/spec/unit/knife/environment_compare_spec.rb
index 16e3b4d13d..3606b617a9 100644
--- a/spec/unit/knife/environment_compare_spec.rb
+++ b/spec/unit/knife/environment_compare_spec.rb
@@ -24,28 +24,19 @@ describe Chef::Knife::EnvironmentCompare do
@environments = {
"cita" => "http://localhost:4000/environments/cita",
- "citd" => "http://localhost:4000/environments/citd",
- "citm" => "http://localhost:4000/environments/citm",
- "citp" => "http://localhost:4000/environments/citp",
- "citt" => "http://localhost:4000/environments/citt"
+ "citm" => "http://localhost:4000/environments/citm"
}
@knife.stub(:environment_list).and_return(@environments)
@constraints = {
- "cita" => { "foo" => "= 0.2.0" },
- "citd" => { },
- "citm" => { "foo" => "= 0.2.0" },
- "citp" => { "bar" => "= 0.0.4" },
- "citt" => { "bar" => "= 0.0.1" }
+ "cita" => { "foo" => "= 1.0.1", "bar" => "= 0.0.4" },
+ "citm" => { "foo" => "= 1.0.1", "bar" => "= 0.0.2" }
}
@knife.stub(:constraint_list).and_return(@constraints)
- @cookbooks = {
- "foo"=>"= 0.2.0",
- "bar"=>"= 0.0.1"
- }
+ @cookbooks = { "foo"=>"= 1.0.1", "bar"=>"= 0.0.1" }
@knife.stub(:cookbook_list).and_return(@cookbooks)
@@ -67,24 +58,23 @@ describe Chef::Knife::EnvironmentCompare do
end
describe 'run' do
- it 'should display all environments / cookbooks and the version constraints of the cookbooks' do
+ it 'should display only cookbooks with version constraints' do
@knife.config[:format] = 'summary'
@knife.run
@environments.each do |item, url|
- @stdout.string.should match /#{item}/ and @stdout.string.lines.count.should be 8
+ @stdout.string.should match /#{item}/ and @stdout.string.lines.count.should be 4
end
end
- it 'should display 8 number of lines' do
+ it 'should display 4 number of lines' do
@knife.config[:format] = 'summary'
@knife.run
- @stdout.string.lines.count.should be 8
+ @stdout.string.lines.count.should be 4
end
-
end
describe 'with -m or --mismatch' do
- it 'should display mismatch environments / cookbooks and the version constraints of the cookbooks' do
+ it 'should display only cookbooks that have mismatching version constraints' do
@knife.config[:format] = 'summary'
@knife.config[:mismatch] = true
@knife.run
@@ -93,13 +83,30 @@ describe Chef::Knife::EnvironmentCompare do
end
end
- it 'should display 4 number of lines' do
+ it 'should display 3 number of lines' do
@knife.config[:format] = 'summary'
@knife.config[:mismatch] = true
@knife.run
- @stdout.string.lines.count.should be 4
+ @stdout.string.lines.count.should be 3
+ end
+ end
+
+ describe 'with -a or --all' do
+ it 'should display all cookbooks' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:all] = true
+ @knife.run
+ @constraints.each do |item, ver|
+ @stdout.string.should match /#{ver[1]}/
+ end
end
+ it 'should display 8 number of lines' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:all] = true
+ @knife.run
+ @stdout.string.lines.count.should be 8
+ end
end
end
diff --git a/spec/unit/provider/cron_spec.rb b/spec/unit/provider/cron_spec.rb
index 8a819b699c..35656e0ad6 100644
--- a/spec/unit/provider/cron_spec.rb
+++ b/spec/unit/provider/cron_spec.rb
@@ -291,6 +291,12 @@ CRONTAB
@provider.cron_different?.should eql(true)
end
+ it "should return true if mailto doesn't match" do
+ @current_resource.mailto "foo@bar.com"
+ @new_resource.mailto(nil)
+ @provider.cron_different?.should eql(true)
+ end
+
it "should return false if the objects are identical" do
@provider.cron_different?.should == false
end
diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb
index 2bf55930db..4c54a17958 100644
--- a/spec/unit/provider/git_spec.rb
+++ b/spec/unit/provider/git_spec.rb
@@ -172,13 +172,14 @@ SHAS
let(:default_options) do
{
:user => deploy_user,
- :environment => { "GIT_SSH" => wrapper },
+ :environment => { "GIT_SSH" => wrapper, "HOME" => "/home/deployNinja" },
:log_tag => "git[web2.0 app]"
}
end
before do
@resource.user deploy_user
@resource.ssh_wrapper wrapper
+ Etc.stub!(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja"))
end
context "without a timeout set" do
it "clones a repo with default git options" do
@@ -198,11 +199,13 @@ SHAS
it "runs a clone command with escaped destination" do
@resource.user "deployNinja"
+ Etc.stub!(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja"))
@resource.destination "/Application Support/with/space"
@resource.ssh_wrapper "do_it_this_way.sh"
expected_cmd = "git clone \"git://github.com/opscode/chef.git\" \"/Application Support/with/space\""
@provider.should_receive(:shell_out!).with(expected_cmd, :user => "deployNinja",
- :environment =>{"GIT_SSH"=>"do_it_this_way.sh"},
+ :environment =>{"GIT_SSH"=>"do_it_this_way.sh",
+ "HOME" => "/home/deployNinja"},
:log_tag => "git[web2.0 app]")
@provider.clone
end
@@ -252,11 +255,14 @@ SHAS
it "runs a sync command with the user and group specified in the resource" do
@resource.user("whois")
+ Etc.stub!(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/whois"))
@resource.group("thisis")
@provider.should_receive(:setup_remote_tracking_branches).with(@resource.remote, @resource.repository)
expected_cmd = "git fetch origin && git fetch origin --tags && git reset --hard d35af14d41ae22b19da05d7d03a0bafc321b244c"
@provider.should_receive(:shell_out!).with(expected_cmd, :cwd => "/my/deploy/dir",
- :user => "whois", :group => "thisis", :log_tag => "git[web2.0 app]")
+ :user => "whois", :group => "thisis",
+ :log_tag => "git[web2.0 app]",
+ :environment=>{"HOME"=>"/home/whois"})
@provider.fetch_updates
end
@@ -296,6 +302,7 @@ SHAS
it "runs the config with the user and group specified in the resource" do
@resource.user("whois")
@resource.group("thisis")
+ Etc.stub!(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/whois"))
command_response = double('shell_out')
command_response.stub(:exitstatus) { 1 }
expected_command = "git config --get remote.#{@resource.remote}.url"
@@ -304,13 +311,15 @@ SHAS
:log_tag => "git[web2.0 app]",
:user => "whois",
:group => "thisis",
+ :environment=>{"HOME"=>"/home/whois"},
:returns => [0,1,2]).and_return(command_response)
add_remote_command = "git remote add #{@resource.remote} #{@resource.repository}"
@provider.should_receive(:shell_out!).with(add_remote_command,
:cwd => "/my/deploy/dir",
:log_tag => "git[web2.0 app]",
:user => "whois",
- :group => "thisis")
+ :group => "thisis",
+ :environment=>{"HOME"=>"/home/whois"})
@provider.setup_remote_tracking_branches(@resource.remote, @resource.repository)
end
@@ -402,6 +411,21 @@ SHAS
# @resource.should be_updated
end
+ it "does not call checkout if enable_checkout is false" do
+ # will be invoked in load_current_resource
+ ::File.stub!(:exist?).with("/my/deploy/dir/.git").and_return(false)
+
+ ::File.stub!(:exist?).with("/my/deploy/dir").and_return(true)
+ ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub!(:entries).with("/my/deploy/dir").and_return(['.','..'])
+
+ @resource.enable_checkout false
+ @provider.should_receive(:clone)
+ @provider.should_not_receive(:checkout)
+ @provider.should_receive(:enable_submodules)
+ @provider.run_action(:checkout)
+ end
+
# REGRESSION TEST: on some OSes, the entries from an empty directory will be listed as
# ['..', '.'] but this shouldn't change the behavior
it "does a checkout by cloning the repo and then enabling submodules when the directory entries are listed as %w{.. .}" do
diff --git a/spec/unit/resource/scm_spec.rb b/spec/unit/resource/scm_spec.rb
index 8f6593a931..2141ae3c88 100644
--- a/spec/unit/resource/scm_spec.rb
+++ b/spec/unit/resource/scm_spec.rb
@@ -118,6 +118,16 @@ describe Chef::Resource::Scm do
@resource.enable_submodules.should be_false
end
+ it "takes a boolean for #enable_checkout" do
+ @resource.enable_checkout true
+ @resource.enable_checkout.should be_true
+ lambda {@resource.enable_checkout "lolz"}.should raise_error(ArgumentError)
+ end
+
+ it "defaults to enabling checkout" do
+ @resource.enable_checkout.should be_true
+ end
+
it "takes a string for the remote" do
@resource.remote "opscode"
@resource.remote.should eql("opscode")