diff options
author | Bryan McLellan <btm@opscode.com> | 2013-11-26 10:55:21 -0800 |
---|---|---|
committer | Bryan McLellan <btm@opscode.com> | 2013-11-26 10:55:21 -0800 |
commit | ac528c3f9871c2c35c53d313340726fde16d3936 (patch) | |
tree | a41671b2d699d648c1d0bcd7476d2828f158a3f9 | |
parent | 609701d408e49c27612bd321eaa1d467c2a088dd (diff) | |
parent | 8d9e96ab5fb4c8381755a252e83d445bcc8a958a (diff) | |
download | chef-ac528c3f9871c2c35c53d313340726fde16d3936.tar.gz |
Merge branch 'contributions'
-rw-r--r-- | chef.gemspec | 1 | ||||
-rw-r--r-- | lib/chef/application/apply.rb | 6 | ||||
-rw-r--r-- | lib/chef/application/solo.rb | 2 | ||||
-rw-r--r-- | lib/chef/client.rb | 19 | ||||
-rw-r--r-- | lib/chef/cookbook_uploader.rb | 10 | ||||
-rw-r--r-- | lib/chef/knife/cookbook_upload.rb | 8 | ||||
-rw-r--r-- | lib/chef/knife/data_bag_create.rb | 7 | ||||
-rw-r--r-- | lib/chef/knife/environment_compare.rb | 10 | ||||
-rw-r--r-- | lib/chef/mixin/command.rb | 23 | ||||
-rw-r--r-- | lib/chef/provider/cron.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/git.rb | 28 | ||||
-rw-r--r-- | lib/chef/resource/deploy.rb | 18 | ||||
-rw-r--r-- | lib/chef/resource/scm.rb | 18 | ||||
-rw-r--r-- | spec/unit/client_spec.rb | 14 | ||||
-rw-r--r-- | spec/unit/knife/cookbook_upload_spec.rb | 14 | ||||
-rw-r--r-- | spec/unit/knife/data_bag_create_spec.rb | 7 | ||||
-rw-r--r-- | spec/unit/knife/environment_compare_spec.rb | 49 | ||||
-rw-r--r-- | spec/unit/provider/cron_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/provider/git_spec.rb | 32 | ||||
-rw-r--r-- | spec/unit/resource/scm_spec.rb | 10 |
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") |