Merge pull request #237 from cmurphy/rspec-puppet-2
authorTP Honey <tphoney@users.noreply.github.com>
Wed, 22 Apr 2015 16:19:08 +0000 (17:19 +0100)
committerTP Honey <tphoney@users.noreply.github.com>
Wed, 22 Apr 2015 16:19:08 +0000 (17:19 +0100)
Testing updates

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

diff --git a/Gemfile b/Gemfile
index cc77f38..fcd27d5 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,15 @@
 source ENV['GEM_SOURCE'] || "https://rubygems.org"
 
+def location_for(place, fake_version = nil)
+  if place =~ /^(git:[^#]*)#(.*)/
+    [fake_version, { :git => $1, :branch => $2, :require => false }].compact
+  elsif place =~ /^file:\/\/(.*)/
+    ['>= 0', { :path => File.expand_path($1), :require => false }]
+  else
+    [place, { :require => false }]
+  end
+end
+
 group :development, :unit_tests do
   gem 'rspec-core', '3.1.7',     :require => false
   gem 'puppetlabs_spec_helper',  :require => false
@@ -8,8 +18,17 @@ group :development, :unit_tests do
   gem 'json',                    :require => false
 end
 
+beaker_version = ENV['BEAKER_VERSION']
+beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION']
 group :system_tests do
-  gem 'beaker-rspec',  :require => false
+  if beaker_version
+    gem 'beaker', *location_for(beaker_version)
+  end
+  if beaker_rspec_version
+    gem 'beaker-rspec', *location_for(beaker_rspec_version)
+  else
+    gem 'beaker-rspec',  :require => false
+  end
   gem 'serverspec',    :require => false
 end
 
index 9671fc5..2433d99 100644 (file)
@@ -49,7 +49,7 @@ Also, this module, like Puppet generally, will not create parent directories for
 
 To get started with the vcsrepo module, you must simply define the type `vcsrepo` with a path to your repository and the [type of VCS](#Usage) you're using in `provider` (in the below example, Git). 
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
     }
@@ -75,14 +75,14 @@ The vcsrepo module works with the following VCSs:
 To create a blank repository suitable for use as a central repository,
 define `vcsrepo` without `source` or `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
     }
 
 If you're defining `vcsrepo` for a central or official repository, you may want to make it a bare repository.  You do this by setting `ensure` to 'bare' rather than 'present'.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => bare,
       provider => git,
     }
@@ -91,17 +91,17 @@ If you're defining `vcsrepo` for a central or official repository, you may want
 
 To get the current HEAD on the master branch,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
-      source   => "git://example.com/repo.git",
+      source   => 'git://example.com/repo.git',
     }
 
 To get a specific revision or branch (can be a commit SHA, tag, or branch name),
 
  **SHA**
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
       source   => 'git://example.com/repo.git',
@@ -110,7 +110,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name),
 
 **Tag**
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
       source   => 'git://example.com/repo.git',
@@ -119,7 +119,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name),
 
 **Branch name**
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
       source   => 'git://example.com/repo.git',
@@ -128,7 +128,7 @@ To get a specific revision or branch (can be a commit SHA, tag, or branch name),
 
 To check out a branch as a specific user,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
       source   => 'git://example.com/repo.git',
@@ -138,7 +138,7 @@ To check out a branch as a specific user,
 
 To keep the repository at the latest revision (**WARNING:** this will always overwrite local changes to the repository),
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => latest,
       provider => git,
       source   => 'git://example.com/repo.git',
@@ -147,7 +147,7 @@ To keep the repository at the latest revision (**WARNING:** this will always ove
 
 To clone the repository but skip initialiazing submodules,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure     => latest,
       provider   => git,
       source     => 'git://example.com/repo.git',
@@ -157,12 +157,12 @@ To clone the repository but skip initialiazing submodules,
 ##### Using multiple remotes with a repository
 Instead of specifying a single string in the 'source' property, you can specify a hash with multiple name => URL mappings,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => git,
       source   => {
-        "origin"       => "https://github.com/puppetlabs/puppetlabs-vcsrepo.git"
-        "other_remote" => "https://github.com/other_user/puppetlabs-vcsrepo.git"
+        origin       => 'https://github.com/puppetlabs/puppetlabs-vcsrepo.git'
+        other_remote => 'https://github.com/other_user/puppetlabs-vcsrepo.git'
       },
     }
 
@@ -187,7 +187,7 @@ For more examples using Git, see `examples/git/`.
 To create a blank repository suitable for use as a central repository,
 define `vcsrepo` without `source` or `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => bzr,
     }
@@ -196,7 +196,7 @@ define `vcsrepo` without `source` or `revision`.
 
 Provide the `source` location to branch from an existing repository.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => bzr,
       source   => 'lp:myproj',
@@ -205,7 +205,7 @@ Provide the `source` location to branch from an existing repository.
 For a specific revision, use `revision` with a valid revisionspec
 (see `bzr help revisionspec` for more information on formatting a revision).
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => bzr,
       source   => 'lp:myproj',
@@ -228,7 +228,7 @@ For more examples using Bazaar, see `examples/bzr/`.
 To create a blank repository suitable for use as a central repository,
 define `vcsrepo` without `source` or `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => cvs,
     }
@@ -237,39 +237,39 @@ define `vcsrepo` without `source` or `revision`.
 
 To get the current mainline,
 
-    vcsrepo { "/path/to/workspace":
+    vcsrepo { '/path/to/workspace':
       ensure   => present,
       provider => cvs,
-      source   => ":pserver:anonymous@example.com:/sources/myproj",
+      source   => ':pserver:anonymous@example.com:/sources/myproj',
     }
     
 To get a specific module on the current mainline,
 
-    vcsrepo {"/vagrant/lockss-daemon-source":
+    vcsrepo {'/vagrant/lockss-daemon-source':
       ensure   => present,
       provider => cvs,
-      source   => ":pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss",
-      module   => "lockss-daemon",
+      source   => ':pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss',
+      module   => 'lockss-daemon',
     }
 
 
 You can use the `compression` parameter to set the GZIP compression levels for your repository history.
 
-    vcsrepo { "/path/to/workspace":
+    vcsrepo { '/path/to/workspace':
       ensure      => present,
       provider    => cvs,
       compression => 3,
-      source      => ":pserver:anonymous@example.com:/sources/myproj",
+      source      => ':pserver:anonymous@example.com:/sources/myproj',
     }
 
 For a specific tag, use `revision`.
 
-    vcsrepo { "/path/to/workspace":
+    vcsrepo { '/path/to/workspace':
       ensure      => present,
       provider    => cvs,
       compression => 3,
-      source      => ":pserver:anonymous@example.com:/sources/myproj",
-      revision    => "SOMETAG",
+      source      => ':pserver:anonymous@example.com:/sources/myproj',
+      revision    => 'SOMETAG',
     }
 
 #####Sources that use SSH
@@ -287,7 +287,7 @@ For for more examples using CVS, see `examples/cvs/`.
 To create a blank repository suitable for use as a central repository,
 define `vcsrepo` without `source` or `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
     }
@@ -296,51 +296,51 @@ define `vcsrepo` without `source` or `revision`.
 
 To get the default branch tip,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
-      source   => "http://hg.example.com/myrepo",
+      source   => 'http://hg.example.com/myrepo',
     }
 
 For a specific changeset, use `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
-      source   => "http://hg.example.com/myrepo",
+      source   => 'http://hg.example.com/myrepo',
       revision => '21ea4598c962',
     }
 
 You can also set `revision` to a tag.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
-      source   => "http://hg.example.com/myrepo",
+      source   => 'http://hg.example.com/myrepo',
       revision => '1.1.2',
     }
 
 To check out as a specific user,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
-      source   => "http://hg.example.com/myrepo",
+      source   => 'http://hg.example.com/myrepo',
       user     => 'user',
     }
 
 To specify an SSH identity key,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => hg,
-      source   => "ssh://hg@hg.example.com/myrepo",
-      identity => "/home/user/.ssh/id_dsa,
+      source   => 'ssh://hg@hg.example.com/myrepo',
+      identity => '/home/user/.ssh/id_dsa',
     }
 
 To specify a username and password for HTTP Basic authentication,
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => latest,
       provider => hg,
       source   => 'http://hg.example.com/myrepo',
@@ -364,7 +364,7 @@ To create an empty Workspace, define a `vcsrepo` without a `source` or `revision
 Environment variables P4PORT, P4USER, etc... are used to define the Perforce server
 connection settings.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure     => present,
       provider   => p4
     }
@@ -378,7 +378,7 @@ A Perforce configuration file can be used by setting the `P4CONFIG` environment
 defining `p4config`.  If a configuration is defined, then the environment variable for 
 `P4CLIENT` is replaced.
  
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure     => present,
       provider   => p4,
       p4config   => '.p4config'
@@ -388,7 +388,7 @@ defining `p4config`.  If a configuration is defined, then the environment variab
 
 To sync a depot path to head, ensure `latest`:
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
         ensure   => latest,
         provider => p4,
         source   => '//depot/branch/...'
@@ -396,7 +396,7 @@ To sync a depot path to head, ensure `latest`:
 
 For a specific changelist, ensure `present` and specify a `revision`:
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
         ensure   => present,
         provider => p4,
         source   => '//depot/branch/...',
@@ -405,7 +405,7 @@ For a specific changelist, ensure `present` and specify a `revision`:
 
 You can also set `revision` to a label:
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
         ensure   => present,
         provider => p4,
         source   => '//depot/branch/...',
@@ -428,7 +428,7 @@ For examples you can run, see `examples/p4/`
 To create a blank repository suitable for use as a central repository,
 define `vcsrepo` without `source` or `revision`.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => svn,
     }
@@ -437,18 +437,18 @@ define `vcsrepo` without `source` or `revision`.
 
 Provide a `source` pointing to the branch/tag you want to check out from a repository.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => svn,
-      source   => "svn://svnrepo/hello/branches/foo",
+      source   => 'svn://svnrepo/hello/branches/foo',
     }
 
 You can also provide a specific revision.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
       ensure   => present,
       provider => svn,
-      source   => "svn://svnrepo/hello/branches/foo",
+      source   => 'svn://svnrepo/hello/branches/foo',
       revision => '1234',
     }
 
@@ -456,11 +456,11 @@ You can also provide a specific revision.
 
 To use a specific configuration directory, provide a `configuration` parameter which should be a directory path on the local system where your svn configuration files are.  Typically, it is '/path/to/.subversion'.
 
-    vcsrepo { "/path/to/repo":
+    vcsrepo { '/path/to/repo':
         ensure        => present,
         provider      => svn,
-        source        => "svn://svnrepo/hello/branches/foo",
-        configuration => "/path/to/.subversion",
+        source        => 'svn://svnrepo/hello/branches/foo',
+        configuration => '/path/to/.subversion',
     }
 
 #####Sources that use SSH 
index 9d3f7f3..8101253 100644 (file)
@@ -5,7 +5,7 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
 
   commands :git => 'git'
 
-  has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user, :depth, :submodules
+  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
@@ -142,7 +142,8 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
     # 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|
+      @resource.value(:source).keys.sort.each do |remote_name|
+        remote_url = @resource.value(:source)[remote_name]
         at_path { do_update |= update_remote_url(remote_name, remote_url) }
       end
     else
@@ -180,6 +181,9 @@ Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo)
     if @resource.value(:depth) and @resource.value(:depth).to_i > 0
       args.push('--depth', @resource.value(:depth).to_s)
     end
+    if @resource.value(:branch)
+      args.push('--branch', @resource.value(:branch).to_s)
+    end
     if @resource.value(:ensure) == :bare
       args << '--bare'
     end
index a1b1714..905d5ad 100644 (file)
@@ -7,7 +7,7 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo)
            :svnadmin => 'svnadmin',
            :svnlook  => 'svnlook'
 
-  has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration
+  has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration, :conflict
 
   def create
     if !@resource.value(:source)
@@ -92,6 +92,11 @@ Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo)
            else
              buildargs.push('update', '-r', desired)
            end
+
+    if @resource.value(:conflict)
+      args.push('--accept', @resource.value(:conflict))
+    end
+
     at_path do
       svn(*args)
     end
index 3bf4029..e5dfbb5 100644 (file)
@@ -40,12 +40,18 @@ Puppet::Type.newtype(:vcsrepo) do
   feature :depth,
           "The provider can do shallow clones"
 
+  feature :branch,
+          "The name of the branch"
+
   feature :p4config,
           "The provider understands Perforce Configuration"
 
   feature :submodules,
           "The repository contains submodules which can be optionally initialized"
 
+  feature :conflict,
+          "The provider supports automatic conflict resolution"
+
   ensurable do
     attr_accessor :latest
 
@@ -204,6 +210,10 @@ Puppet::Type.newtype(:vcsrepo) do
     desc "The value to be used to do a shallow clone."
   end
 
+  newparam :branch, :required_features => [:branch] do
+    desc "The name of the branch to clone."
+  end
+
   newparam :p4config, :required_features => [:p4config] do
     desc "The Perforce P4CONFIG environment."
   end
@@ -214,6 +224,10 @@ Puppet::Type.newtype(:vcsrepo) do
     defaultto true
   end
 
+  newparam :conflict do
+    desc "The action to take if conflicts exist between repository and working copy"
+  end
+
   autorequire(:package) do
     ['git', 'git-core']
   end
index d0153a1..d33c98a 100644 (file)
@@ -263,7 +263,7 @@ branches
     context "when multiple sources are modified" do
       it "should update the urls" do
         resource[:source] = {"origin" => "git://git@foo.com/bar.git", "new_remote" => "git://git@foo.com/baz.git"}
-        provider.expects(:git).at_least_once.with('config', '-l').returns("remote.origin.url=git://git@foo.com/foo.git\n", "remote.origin.url=git://git@foo.com/bar.git\n")
+        provider.expects(:git).at_least_once.with('config', '-l').returns("remote.origin.url=git://git@foo.com/bar.git\n", "remote.origin.url=git://git@foo.com/foo.git\n")
         provider.expects(:git).with('remote', 'set-url', 'origin', 'git://git@foo.com/bar.git')
         provider.expects(:git).with('remote', 'add', 'new_remote', 'git://git@foo.com/baz.git')
         provider.expects(:git).with('remote','update')
index 494da52..77f0e03 100644 (file)
@@ -83,10 +83,22 @@ describe Puppet::Type.type(:vcsrepo).provider(:svn) do
     before do
       @revision = '30'
     end
-    it "should use 'svn update'" do
-      expects_chdir
-      provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision)
-      provider.revision = @revision
+    context 'with conflict' do
+      it "should use 'svn update'" do
+        resource[:conflict] = 'theirs-full'
+        expects_chdir
+        provider.expects(:svn).with('--non-interactive', 'update',
+                                    '-r', @revision,
+                                    '--accept', resource.value(:conflict))
+        provider.revision = @revision
+      end
+    end
+    context 'without conflict' do
+      it "should use 'svn update'" do
+        expects_chdir
+        provider.expects(:svn).with('--non-interactive', 'update', '-r', @revision)
+        provider.revision = @revision
+      end
     end
   end
 
@@ -94,11 +106,24 @@ describe Puppet::Type.type(:vcsrepo).provider(:svn) do
     before do
       @revision = '30'
     end
-    it "should use 'svn switch'" do
-      resource[:source] = 'an-unimportant-value'
-      expects_chdir
-      provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value')
-      provider.revision = @revision
+    context 'with conflict' do
+      it "should use 'svn switch'" do
+        resource[:source] = 'an-unimportant-value'
+        resource[:conflict] = 'theirs-full'
+        expects_chdir
+        provider.expects(:svn).with('--non-interactive', 'switch',
+                                    '-r', @revision, 'an-unimportant-value',
+                                    '--accept', resource.value(:conflict))
+        provider.revision = @revision
+      end
+    end
+    context 'without conflict' do
+      it "should use 'svn switch'" do
+        resource[:source] = 'an-unimportant-value'
+        expects_chdir
+        provider.expects(:svn).with('--non-interactive', 'switch', '-r', @revision, 'an-unimportant-value')
+        provider.revision = @revision
+      end
     end
   end