Class: Chef::Provider::Git
Instance Attribute Summary
#current_resource, #new_resource, #run_context
Instance Method Summary
collapse
#chdir_or_tmpdir, #handle_command_failures, #not_if, #only_if, #output_of_command, #run_command, #run_command_with_systems_locale
#popen4
#popen4
#action_nothing, build_from_file, #cookbook_name, #initialize, #node, #resource_collection
#convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #snake_case_basename
#method_missing
#data_bag, #data_bag_item, #platform?, #search, #value_for_platform
Constructor Details
This class inherits a constructor from Chef::Provider
Instance Method Details
#action_checkout ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/chef/provider/git.rb', line 38
def action_checkout
assert_target_directory_valid!
if target_dir_non_existant_or_empty?
clone
checkout
enable_submodules
@new_resource.updated_by_last_action(true)
else
Chef::Log.info "Taking no action, checkout destination #{@new_resource.destination} already exists or is a non-empty directory"
end
end
|
#action_export ⇒ Object
51
52
53
54
55
|
# File 'lib/chef/provider/git.rb', line 51
def action_export
action_checkout
FileUtils.rm_rf(::File.join(@new_resource.destination,".git"))
@new_resource.updated_by_last_action(true)
end
|
#action_sync ⇒ Object
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/chef/provider/git.rb', line 57
def action_sync
assert_target_directory_valid!
if existing_git_clone?
current_rev = find_current_revision
Chef::Log.debug "#{@new_resource} current revision: #{current_rev} target revision: #{target_revision}"
unless current_revision_matches_target_revision?
fetch_updates
enable_submodules
Chef::Log.info "#{@new_resource} updated to revision: #{target_revision}"
@new_resource.updated_by_last_action(true)
end
else
action_checkout
@new_resource.updated_by_last_action(true)
end
end
|
#assert_target_directory_valid! ⇒ Object
76
77
78
79
80
81
82
|
# File 'lib/chef/provider/git.rb', line 76
def assert_target_directory_valid!
target_parent_directory = ::File.dirname(@new_resource.destination)
unless ::File.directory?(target_parent_directory)
msg = "Cannot clone #{@new_resource} to #{@new_resource.destination}, the enclosing directory #{target_parent_directory} does not exist"
raise Chef::Exceptions::MissingParentDirectory, msg
end
end
|
#checkout ⇒ Object
117
118
119
120
121
122
|
# File 'lib/chef/provider/git.rb', line 117
def checkout
sha_ref = target_revision
Chef::Log.info "Checking out branch: #{@new_resource.revision} reference: #{sha_ref}"
run_command(run_options(:command => "git checkout -b deploy #{sha_ref}", :cwd => @new_resource.destination))
end
|
#clone ⇒ Object
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/chef/provider/git.rb', line 104
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
|
#current_revision_matches_target_revision? ⇒ Boolean
157
158
159
|
# File 'lib/chef/provider/git.rb', line 157
def current_revision_matches_target_revision?
(!@current_resource.revision.nil?) && (target_revision.strip.to_i(16) == @current_resource.revision.strip.to_i(16))
end
|
#enable_submodules ⇒ Object
124
125
126
127
128
129
130
|
# File 'lib/chef/provider/git.rb', line 124
def enable_submodules
if @new_resource.enable_submodules
Chef::Log.info "Enabling git submodules"
command = "git submodule init && git submodule update"
run_command(run_options(:command => command, :cwd => @new_resource.destination))
end
end
|
#existing_git_clone? ⇒ Boolean
84
85
86
|
# File 'lib/chef/provider/git.rb', line 84
def existing_git_clone?
::File.exist?(::File.join(@new_resource.destination, ".git"))
end
|
#fetch_updates ⇒ Object
132
133
134
135
136
137
138
139
|
# File 'lib/chef/provider/git.rb', line 132
def fetch_updates
setup_remote_tracking_branches if @new_resource.remote != 'origin'
fetch_command = "git fetch #{@new_resource.remote} && git fetch #{@new_resource.remote} --tags && git reset --hard #{target_revision}"
Chef::Log.debug "Fetching updates from #{new_resource.remote} and resetting to revison #{target_revision}"
run_command(run_options(:command => fetch_command, :cwd => @new_resource.destination))
end
|
#find_current_revision ⇒ Object
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/chef/provider/git.rb', line 92
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))
unless [0,128].include?(status.exitstatus)
handle_command_failures(status, "STDOUT: #{result}\nSTDERR: #{error_message}")
end
end
sha_hash?(result) ? result : nil
end
|
#load_current_resource ⇒ Object
31
32
33
34
35
36
|
# File 'lib/chef/provider/git.rb', line 31
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
|
#remote_resolve_reference ⇒ Object
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
# File 'lib/chef/provider/git.rb', line 176
def remote_resolve_reference
command = git('ls-remote', @new_resource.repository, @new_resource.revision)
Chef::Log.debug("Executing #{command}")
begin
status, result, error_message = output_of_command(command, run_options)
handle_command_failures(status, "STDOUT: #{result}\nSTDERR: #{error_message}")
rescue Chef::Exceptions::Exec => e
msg = "Could not access the remote Git repository. If this is a private repository, "
msg << "verify that the deploy key for your application has been added to your remote Git account.\n"
msg << e.message
raise Chef::Exceptions::Exec, msg
end
result
end
|
#setup_remote_tracking_branches ⇒ Object
Use git-config to setup a remote tracking branches. Could use git-remote but it complains when a remote of the same name already exists, git-config will just silenty overwrite the setting every time. This could cause wierd-ness in the remote cache if the url changes between calls, but as long as the repositories are all based from each other it should still work fine.
147
148
149
150
151
152
153
154
155
|
# File 'lib/chef/provider/git.rb', line 147
def setup_remote_tracking_branches
command = []
Chef::Log.info "Configuring remote tracking branches for repository #{@new_resource.repository} "+
"at remote #{@new_resource.remote}"
command << "git config remote.#{@new_resource.remote}.url #{@new_resource.repository}"
command << "git config remote.#{@new_resource.remote}.fetch +refs/heads/*:refs/remotes/#{@new_resource.remote}/*"
run_command(run_options(:command => command.join(" && "), :cwd => @new_resource.destination))
end
|
#target_dir_non_existant_or_empty? ⇒ Boolean
88
89
90
|
# File 'lib/chef/provider/git.rb', line 88
def target_dir_non_existant_or_empty?
!::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination).sort == ['.','..']
end
|
#target_revision ⇒ Object
Also known as:
revision_slug
161
162
163
164
165
166
167
168
169
170
171
172
|
# File 'lib/chef/provider/git.rb', line 161
def target_revision
@target_revision ||= begin
assert_revision_not_remote
if sha_hash?(@new_resource.revision)
@target_revision = @new_resource.revision
else
resolved_reference = remote_resolve_reference
@target_revision = (resolved_reference)
end
end
end
|