Add mirror option for git cloning
authorStrech (Sergey Fedorov) <oni.strech@gmail.com>
Tue, 22 Dec 2015 22:02:26 +0000 (23:02 +0100)
committerStrech (Sergey Fedorov) <oni.strech@gmail.com>
Tue, 22 Dec 2015 22:02:26 +0000 (23:02 +0100)
Example:

vcsrepo { '/path/to/repo':
  ensure   => mirror,
  provider => git,
  source   => 'git://example.com/repo.git',
}

README.markdown
lib/puppet/provider/vcsrepo/git.rb
lib/puppet/type/vcsrepo.rb
spec/unit/puppet/provider/vcsrepo/git_spec.rb

index e878891..ffc2d7e 100644 (file)
@@ -94,6 +94,16 @@ vcsrepo { '/path/to/repo':
 }
 ~~~
 
+If you want to clone your repository as bare or mirror, you can set `ensure` to 'bare' or 'mirror':
+
+~~~
+vcsrepo { '/path/to/repo':
+  ensure   => mirror,
+  provider => git,
+  source   => 'git://example.com/repo.git',
+}
+~~~
+
 By default, `vcsrepo` will use the HEAD of the source repository's master branch. To use another branch or a specific commit, set `revision` to either a branch name or a commit SHA or tag.
 
 Branch name:
index 0249a3c..63986ab 100644 (file)
@@ -10,10 +10,14 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
   has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :branch, :submodules
 
   def create
-    if @resource.value(:revision) and @resource.value(:ensure) == :bare
+    if @resource.value(:revision) and ensure_bare_or_mirror?
       fail("Cannot set a revision (#{@resource.value(:revision)}) on a bare repository")
     end
     if !@resource.value(:source)
+      if @resource.value(:ensure) == :mirror
+        fail("Cannot init repository with mirror option, try bare instead")
+      end
+
       init_repository(@resource.value(:path))
     else
       clone_repository(default_url, @resource.value(:path))
@@ -22,7 +26,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
       if @resource.value(:revision)
         checkout
       end
-      if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true
+      if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
         update_submodules
       end
 
@@ -85,7 +89,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
       end
     end
     #TODO Would this ever reach here if it is bare?
-    if @resource.value(:ensure) != :bare && @resource.value(:submodules) == :true
+    if !ensure_bare_or_mirror? && @resource.value(:submodules) == :true
       update_submodules
     end
     update_owner_and_excludes
@@ -95,6 +99,10 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
     bare_git_config_exists? && !working_copy_exists?
   end
 
+  def ensure_bare_or_mirror?
+    [:bare, :mirror].include? @resource.value(:ensure)
+  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
@@ -197,9 +205,12 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
     if @resource.value(:branch)
       args.push('--branch', @resource.value(:branch).to_s)
     end
-    if @resource.value(:ensure) == :bare
-      args << '--bare'
+
+    case @resource.value(:ensure)
+    when :bare then args << '--bare'
+    when :mirror then args << '--mirror'
     end
+
     if @resource.value(:remote) != 'origin'
       args.push('--origin', @resource.value(:remote))
     end
index 290bdad..e2ef0b7 100644 (file)
@@ -69,6 +69,8 @@ Puppet::Type.newtype(:vcsrepo) do
         end
       when :bare
         return is == :bare
+      when :mirror
+        return is == :mirror
       end
     end
 
@@ -83,6 +85,12 @@ Puppet::Type.newtype(:vcsrepo) do
       end
     end
 
+    newvalue :mirror, :required_features => [:bare_repositories] do
+      if !provider.exists?
+        provider.create
+      end
+    end
+
     newvalue :absent do
       provider.destroy
     end
@@ -227,7 +235,7 @@ Puppet::Type.newtype(:vcsrepo) do
   newparam :conflict do
     desc "The action to take if conflicts exist between repository and working copy"
   end
-  
+
   newparam :trust_server_cert do
     desc "Trust server certificate"
     newvalues(:true, :false)
index 87113fa..6a8f58f 100644 (file)
@@ -10,7 +10,7 @@ end
    remote/origin/foo
 
 branches
-    end
+  end
   let(:resource) { Puppet::Type.type(:vcsrepo).new({
     :name     => 'test',
     :ensure   => :present,
@@ -111,6 +111,24 @@ branches
       end
     end
 
+    context "with an ensure of mirror" do
+      context "with revision" do
+        it "should raise an error" do
+          resource[:ensure] = :mirror
+          expect { provider.create }.to raise_error Puppet::Error, /cannot set a revision.+bare/i
+        end
+      end
+      context "without revision" do
+        it "should just execute 'git clone --mirror'" do
+          resource[:ensure] = :mirror
+          resource.delete(:revision)
+          provider.expects(:git).with('clone', '--mirror', resource.value(:source), resource.value(:path))
+          provider.expects(:update_remotes)
+          provider.create
+        end
+      end
+    end
+
     context "when a source is not given" do
       context "when the path does not exist" do
         it "should execute 'git init'" do
@@ -157,6 +175,14 @@ branches
         provider.expects(:git).with('init', '--bare')
         provider.create
       end
+
+      it "should raise an exeption" do
+        resource[:ensure] = :mirror
+        resource.delete(:source)
+        resource.delete(:revision)
+
+        expect { provider.create }.to raise_error Puppet::Error, /cannot init repository with mirror.+try bare/i
+      end
     end
 
     context "when the path is a working copy repository" do