From 5d6ef988af1ff90b4625b0426301cb6fad0268b8 Mon Sep 17 00:00:00 2001 From: Jonathan Tripathy Date: Tue, 20 Jan 2015 23:12:20 -0800 Subject: Implemented multiple remotes feature for git provider. --- lib/puppet/provider/vcsrepo/git.rb | 70 +++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/vcsrepo/git.rb b/lib/puppet/provider/vcsrepo/git.rb index 13e0793..9d3f7f3 100644 --- a/lib/puppet/provider/vcsrepo/git.rb +++ b/lib/puppet/provider/vcsrepo/git.rb @@ -14,13 +14,16 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) if !@resource.value(:source) init_repository(@resource.value(:path)) else - clone_repository(@resource.value(:source), @resource.value(:path)) + clone_repository(default_url, @resource.value(:path)) + update_remotes + if @resource.value(:revision) checkout end if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true update_submodules end + end update_owner_and_excludes end @@ -82,9 +85,25 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) bare_git_config_exists? && !working_copy_exists? end + # If :source is set to a hash (for supporting multiple remotes), + # we search for the URL for :remote. If it doesn't exist, + # we throw an error. If :source is just a string, we use that + # value for the default URL. + def default_url + if @resource.value(:source).is_a?(Hash) + if @resource.value(:source).has_key?(@resource.value(:remote)) + @resource.value(:source)[@resource.value(:remote)] + else + fail("You must specify the URL for #{@resource.value(:remote)} in the :source hash") + end + else + @resource.value(:source) + end + end + def working_copy_exists? if @resource.value(:source) and File.exists?(File.join(@resource.value(:path), '.git', 'config')) - File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{@resource.value(:source)}/).any? + File.readlines(File.join(@resource.value(:path), '.git', 'config')).grep(/#{default_url}/).any? else File.directory?(File.join(@resource.value(:path), '.git')) end @@ -94,18 +113,53 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) working_copy_exists? || bare_exists? end - def update_remote_origin_url - current = git_with_identity('config', "remote.#{@resource.value(:remote)}.url") - unless @resource.value(:source).nil? - if current.nil? or current.strip != @resource.value(:source) - git_with_identity('config', "remote.#{@resource.value(:remote)}.url", @resource.value(:source)) + def update_remote_url(remote_name, remote_url) + do_update = false + current = git_with_identity('config', '-l') + + unless remote_url.nil? + # Check if remote exists at all, regardless of URL. + # If remote doesn't exist, add it + if not current.include? "remote.#{remote_name}.url" + git_with_identity('remote','add', remote_name, remote_url) + return true + + # If remote exists, but URL doesn't match, update URL + elsif not current.include? "remote.#{remote_name}.url=#{remote_url}" + git_with_identity('remote','set-url', remote_name, remote_url) + return true + else + return false end end + + end + + def update_remotes + do_update = false + + # If supplied source is a hash of remote name and remote url pairs, then + # we loop around the hash. Otherwise, we assume single url specified + # in source property + if @resource.value(:source).is_a?(Hash) + @resource.value(:source).each do |remote_name, remote_url| + at_path { do_update |= update_remote_url(remote_name, remote_url) } + end + else + at_path { do_update |= update_remote_url(@resource.value(:remote), @resource.value(:source)) } + end + + # If at least one remote was added or updated, then we must + # call the 'git remote update' command + if do_update == true + at_path { git_with_identity('remote','update') } + end + end def update_references at_path do - update_remote_origin_url + update_remotes git_with_identity('fetch', @resource.value(:remote)) git_with_identity('fetch', '--tags', @resource.value(:remote)) update_owner_and_excludes -- cgit v1.2.3