summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel DeLeo <dan@opscode.com>2011-03-15 16:55:27 -0700
committerDaniel DeLeo <dan@opscode.com>2011-03-15 16:55:27 -0700
commit6bea580d4ecb3854cbbb2ce9d3758ab35ab041f2 (patch)
treec7f8471de5136f927f102a092f017cc452e36778
parent9a77819485148b0561a98bd6ea3d8abc7dd122f1 (diff)
parent78a5c4f3d95c713ca8831cb35e314d85009d9eaf (diff)
downloadchef-6bea580d4ecb3854cbbb2ce9d3758ab35ab041f2.tar.gz
Merge branch 'default-action-scm'
-rw-r--r--chef/lib/chef/provider/git.rb52
-rw-r--r--chef/lib/chef/resource/git.rb10
-rw-r--r--chef/lib/chef/resource/scm.rb3
-rw-r--r--chef/spec/unit/provider/git_spec.rb60
4 files changed, 63 insertions, 62 deletions
diff --git a/chef/lib/chef/provider/git.rb b/chef/lib/chef/provider/git.rb
index d82658d1dc..73e331af42 100644
--- a/chef/lib/chef/provider/git.rb
+++ b/chef/lib/chef/provider/git.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,16 +25,16 @@ require 'fileutils'
class Chef
class Provider
class Git < Chef::Provider
-
+
include Chef::Mixin::Command
-
+
def load_current_resource
@current_resource = Chef::Resource::Git.new(@new_resource.name)
if current_revision = find_current_revision
@current_resource.revision current_revision
end
end
-
+
def action_checkout
assert_target_directory_valid!
@@ -47,13 +47,13 @@ class Chef
Chef::Log.info "Taking no action, checkout destination #{@new_resource.destination} already exists or is a non-empty directory"
end
end
-
+
def action_export
action_checkout
FileUtils.rm_rf(::File.join(@new_resource.destination,".git"))
@new_resource.updated_by_last_action(true)
end
-
+
def action_sync
assert_target_directory_valid!
@@ -92,7 +92,7 @@ class Chef
def find_current_revision
if ::File.exist?(::File.join(cwd, ".git"))
status, result, error_message = output_of_command("git rev-parse HEAD", run_options(:cwd=>cwd))
-
+
# 128 is returned when we're not in a git repo. this is fine
unless [0,128].include?(status.exitstatus)
handle_command_failures(status, "STDOUT: #{result}\nSTDERR: #{error_message}")
@@ -100,27 +100,27 @@ class Chef
end
sha_hash?(result) ? result : nil
end
-
+
def clone
remote = @new_resource.remote
args = []
args << "-o #{remote}" unless remote == 'origin'
args << "--depth #{@new_resource.depth}" if @new_resource.depth
-
+
Chef::Log.info "Cloning repo #{@new_resource.repository} to #{@new_resource.destination}"
-
+
clone_cmd = "git clone #{args.join(' ')} #{@new_resource.repository} #{@new_resource.destination}"
run_command(run_options(:command => clone_cmd))
end
-
+
def checkout
sha_ref = target_revision
Chef::Log.info "Checking out branch: #{@new_resource.revision} reference: #{sha_ref}"
# checkout into a local branch rather than a detached HEAD
run_command(run_options(:command => "git checkout -b deploy #{sha_ref}", :cwd => @new_resource.destination))
end
-
+
def enable_submodules
if @new_resource.enable_submodules
Chef::Log.info "Enabling git submodules"
@@ -128,7 +128,7 @@ class Chef
run_command(run_options(:command => command, :cwd => @new_resource.destination))
end
end
-
+
def fetch_updates
setup_remote_tracking_branches if @new_resource.remote != 'origin'
@@ -161,18 +161,18 @@ class Chef
def target_revision
@target_revision ||= begin
assert_revision_not_remote
-
+
if sha_hash?(@new_resource.revision)
- @target_revision = @new_resource.revision
+ @target_revision = @new_resource.revision
else
resolved_reference = remote_resolve_reference
@target_revision = extract_revision(resolved_reference)
end
end
end
-
+
alias :revision_slug :target_revision
-
+
def remote_resolve_reference
command = git('ls-remote', @new_resource.repository, @new_resource.revision)
Chef::Log.debug("Executing #{command}")
@@ -187,20 +187,20 @@ class Chef
end
result
end
-
+
private
-
+
def run_options(run_opts={})
run_opts[:user] = @new_resource.user if @new_resource.user
run_opts[:group] = @new_resource.group if @new_resource.group
run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
run_opts
end
-
+
def cwd
@new_resource.destination
end
-
+
def git(*args)
["git", *args].compact.join(" ")
end
@@ -208,18 +208,18 @@ class Chef
def sha_hash?(string)
string =~ /^[0-9a-f]{40}$/
end
-
+
def assert_revision_not_remote
if @new_resource.revision =~ /^origin\//
reference = @new_resource.revision
error_text = "Deploying remote branches is not supported. " +
"Specify the remote branch as a local branch for " +
- "the git repository you're deploying from " +
+ "the git repository you're deploying from " +
"(ie: '#{reference.gsub('origin/', '')}' rather than '#{reference}')."
raise RuntimeError, error_text
end
end
-
+
def extract_revision(resolved_reference)
unless resolved_reference =~ /^([0-9a-f]{40})\s+(\S+)/
msg = "Unable to parse SHA reference for '#{@new_resource.revision}' in repository '#{@new_resource.repository}'. "
@@ -229,7 +229,7 @@ class Chef
end
$1
end
-
+
end
end
end
diff --git a/chef/lib/chef/resource/git.rb b/chef/lib/chef/resource/git.rb
index 2328fccd1d..f799ff94fa 100644
--- a/chef/lib/chef/resource/git.rb
+++ b/chef/lib/chef/resource/git.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,16 +21,16 @@ require "chef/resource/scm"
class Chef
class Resource
class Git < Chef::Resource::Scm
-
+
def initialize(name, run_context=nil)
super
@resource_name = :git
@provider = Chef::Provider::Git
end
-
+
alias :branch :revision
alias :reference :revision
-
+
end
end
end
diff --git a/chef/lib/chef/resource/scm.rb b/chef/lib/chef/resource/scm.rb
index 29191de32a..132dad6ede 100644
--- a/chef/lib/chef/resource/scm.rb
+++ b/chef/lib/chef/resource/scm.rb
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Scm < Chef::Resource
-
+
def initialize(name, run_context=nil)
super
@destination = name
@@ -33,6 +33,7 @@ class Chef
@ssh_wrapper = nil
@depth = nil
@allowed_actions.push(:checkout, :export, :sync, :diff, :log)
+ @action = [:sync]
end
def destination(arg=nil)
diff --git a/chef/spec/unit/provider/git_spec.rb b/chef/spec/unit/provider/git_spec.rb
index bbcc03121d..bdec9e8a89 100644
--- a/chef/spec/unit/provider/git_spec.rb
+++ b/chef/spec/unit/provider/git_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
describe Chef::Provider::Git do
-
+
before(:each) do
@current_resource = Chef::Resource::Git.new("web2.0 app")
@current_resource.revision("d35af14d41ae22b19da05d7d03a0bafc321b244c")
@@ -33,20 +33,20 @@ describe Chef::Provider::Git do
@provider = Chef::Provider::Git.new(@resource, @run_context)
@provider.current_resource = @current_resource
end
-
+
context "determining the revision of the currently deployed checkout" do
-
+
before do
@stdout = mock("standard out")
@stderr = mock("standard error")
@exitstatus = mock("exitstatus")
end
-
+
it "sets the current revison to nil if the deploy dir does not exist" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(false)
@provider.find_current_revision.should be_nil
end
-
+
it "determines the current revision when there is one" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
::File.should_receive(:directory?).with("/my/deploy/dir").and_return(true)
@@ -57,7 +57,7 @@ describe Chef::Provider::Git do
@provider.should_receive(:popen4).and_yield("fake-pid","no-stdin", @stdout, @stderr).and_return(@exitstatus)
@provider.find_current_revision.should eql("9b4d8dc38dd471246e7cfb1c3c1ad14b0f2bee13")
end
-
+
it "gives the current revision as nil when there is no current revision" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
::File.should_receive(:directory?).with("/my/deploy/dir").and_return(true)
@@ -69,21 +69,21 @@ describe Chef::Provider::Git do
@provider.find_current_revision.should be_nil
end
end
-
+
it "creates a current_resource with the currently deployed revision when a clone exists in the destination dir" do
@provider.stub!(:find_current_revision).and_return("681c9802d1c62a45b490786c18f0b8216b309440")
@provider.load_current_resource
@provider.current_resource.name.should eql(@resource.name)
@provider.current_resource.revision.should eql("681c9802d1c62a45b490786c18f0b8216b309440")
end
-
+
it "keeps the node and resource passed to it on initialize" do
@provider.node.should equal(@node)
@provider.new_resource.should equal(@resource)
end
-
+
context "resolving revisions to a SHA" do
-
+
before do
@stderr = mock("standard error")
@stderr.stub!(:string).and_return("")
@@ -92,7 +92,7 @@ describe Chef::Provider::Git do
@exitstatus.stub!(:exitstatus).and_return(0)
@git_ls_remote = "git ls-remote git://github.com/opscode/chef.git "
end
-
+
it "returns resource.revision as is if revision is already a full SHA" do
@provider.target_revision.should eql("d35af14d41ae22b19da05d7d03a0bafc321b244c")
end
@@ -105,19 +105,19 @@ describe Chef::Provider::Git do
and_return(@exitstatus)
@provider.target_revision.should eql("503c22a5e41f5ae3193460cca044ed1435029f53")
end
-
+
it "raises a runtime error if you try to deploy from ``origin''" do
@resource.revision("origin/")
lambda {@provider.target_revision}.should raise_error(RuntimeError)
end
-
+
it "raises a runtime error if the revision can't be resolved to any revision" do
@resource.revision "FAIL, that's the revision I want"
@stdout.stub!(:string).and_return("\n")
@provider.should_receive(:popen4).and_yield("pid","stdin",@stdout,@stderr).and_return(@exitstatus)
lambda {@provider.target_revision}.should raise_error(RuntimeError)
end
-
+
it "gives the latest HEAD revision SHA if nothing is specified" do
lots_of_shas = "28af684d8460ba4793eda3e7ac238c864a5d029a\tHEAD\n"+
"503c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/0.8-alpha\n"+
@@ -139,58 +139,58 @@ describe Chef::Provider::Git do
@provider.target_revision.should eql("28af684d8460ba4793eda3e7ac238c864a5d029a")
end
end
-
+
it "responds to :revision_slug as an alias for target_revision" do
@provider.should respond_to(:revision_slug)
end
-
+
it "runs a clone command with default git options" do
@resource.user "deployNinja"
@resource.ssh_wrapper "do_it_this_way.sh"
expected_cmd = 'git clone git://github.com/opscode/chef.git /my/deploy/dir'
- @provider.should_receive(:run_command).with(:command => expected_cmd, :user => "deployNinja",
+ @provider.should_receive(:run_command).with(:command => expected_cmd, :user => "deployNinja",
:environment =>{"GIT_SSH"=>"do_it_this_way.sh"})
@provider.clone
end
-
+
it "compiles a clone command using --depth for shallow cloning" do
@resource.depth 5
expected_cmd = 'git clone --depth 5 git://github.com/opscode/chef.git /my/deploy/dir'
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.clone
end
-
+
it "compiles a clone command with a remote other than ``origin''" do
@resource.remote "opscode"
expected_cmd = 'git clone -o opscode git://github.com/opscode/chef.git /my/deploy/dir'
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.clone
end
-
+
it "runs a checkout command with default options" do
expected_cmd = 'git checkout -b deploy d35af14d41ae22b19da05d7d03a0bafc321b244c'
@provider.should_receive(:run_command).with(:command => expected_cmd, :cwd => "/my/deploy/dir")
@provider.checkout
end
-
+
it "runs an enable_submodule command" do
@resource.enable_submodules true
expected_cmd = "git submodule init && git submodule update"
@provider.should_receive(:run_command).with(:command => expected_cmd, :cwd => "/my/deploy/dir")
@provider.enable_submodules
end
-
+
it "does nothing for enable_submodules if resource.enable_submodules #=> false" do
@provider.should_not_receive(:run_command)
@provider.enable_submodules
end
-
+
it "runs a sync command with default options" do
expected_cmd = "git fetch origin && git fetch origin --tags && git reset --hard d35af14d41ae22b19da05d7d03a0bafc321b244c"
@provider.should_receive(:run_command).with(:command=>expected_cmd, :cwd=> "/my/deploy/dir")
@provider.fetch_updates
end
-
+
it "runs a sync command with the user and group specified in the resource" do
@resource.user("whois")
@resource.group("thisis")
@@ -199,7 +199,7 @@ describe Chef::Provider::Git do
:user => "whois", :group => "thisis")
@provider.fetch_updates
end
-
+
it "configures remote tracking branches when remote is not ``origin''" do
@resource.remote "opscode"
conf_tracking_branches = "git config remote.opscode.url git://github.com/opscode/chef.git && " +
@@ -288,7 +288,7 @@ describe Chef::Provider::Git do
@provider.action_sync
@resource.should be_updated
end
-
+
it "clones the repo instead of fetching updates if the deploy directory is empty" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(false)
::File.stub!(:directory?).with("/my/deploy").and_return(true)
@@ -299,12 +299,12 @@ describe Chef::Provider::Git do
@provider.action_sync
@resource.should be_updated
end
-
+
it "does an export by cloning the repo then removing the .git directory" do
@provider.should_receive(:action_checkout)
FileUtils.should_receive(:rm_rf).with(@resource.destination + "/.git")
@provider.action_export
@resource.should be_updated
end
-
+
end