move to git_clone script

the puppet vcsrepo script is terrible, especially when trying to
change out the origin url. Just import functions from devstack
and drop a lot of code in the process.
This commit is contained in:
Sean Dague 2014-03-03 08:57:46 -05:00
parent 53086ca8db
commit b3e958bc0b
51 changed files with 136 additions and 2775 deletions

View File

@ -0,0 +1,118 @@
#!/bin/bash
#
# Functions taken liberally from devstack project, though trimmed down
# for local use.
# git update using reference as a branch.
# git_update_branch ref
function git_update_branch {
GIT_BRANCH=$1
git checkout -f origin/$GIT_BRANCH
# a local branch might not exist
git branch -D $GIT_BRANCH || true
git checkout -b $GIT_BRANCH
}
# git update using reference as a branch.
# git_update_remote_branch ref
function git_update_remote_branch {
GIT_BRANCH=$1
git checkout -b $GIT_BRANCH -t origin/$GIT_BRANCH
}
# git update using reference as a tag. Be careful editing source at that repo
# as working copy will be in a detached mode
# git_update_tag ref
function git_update_tag {
GIT_TAG=$1
git tag -d $GIT_TAG
# fetching given tag only
git_timed fetch origin tag $GIT_TAG
git checkout -f $GIT_TAG
}
# git clone only if directory doesn't exist already. Since ``DEST`` might not
# be owned by the installation user, we create the directory and change the
# ownership to the proper user.
# git_clone remote dest-dir branch
function git_clone {
GIT_REMOTE=$1
GIT_DEST=$2
GIT_REF=$3
# do a full clone only if the directory doesn't exist
if [[ ! -d $GIT_DEST ]]; then
git_timed clone $GIT_REMOTE $GIT_DEST
cd $GIT_DEST
# This checkout syntax works for both branches and tags
git checkout $GIT_REF
else
# if it does exist then simulate what clone does if asked to RECLONE
cd $GIT_DEST
# set the url to pull from and fetch
git remote set-url origin $GIT_REMOTE
git_timed fetch origin
# remove the existing ignored files (like pyc) as they cause breakage
# (due to the py files having older timestamps than our pyc, so python
# thinks the pyc files are correct using them)
find $GIT_DEST -name '*.pyc' -delete
# handle GIT_REF accordingly to type (tag, branch)
if [[ -n "`git show-ref refs/tags/$GIT_REF`" ]]; then
git_update_tag $GIT_REF
elif [[ -n "`git show-ref refs/heads/$GIT_REF`" ]]; then
git_update_branch $GIT_REF
elif [[ -n "`git show-ref refs/remotes/origin/$GIT_REF`" ]]; then
git_update_remote_branch $GIT_REF
else
die $LINENO "$GIT_REF is neither branch nor tag"
fi
fi
# print out the results so we know what change was used in the logs
cd $GIT_DEST
git show --oneline | head -1
}
# git can sometimes get itself infinitely stuck with transient network
# errors or other issues with the remote end. This wraps git in a
# timeout/retry loop and is intended to watch over non-local git
# processes that might hang. GIT_TIMEOUT, if set, is passed directly
# to timeout(1); otherwise the default value of 0 maintains the status
# quo of waiting forever.
# usage: git_timed <git-command>
function git_timed {
local count=0
local timeout=0
if [[ -n "${GIT_TIMEOUT}" ]]; then
timeout=${GIT_TIMEOUT}
fi
until timeout -s SIGINT ${timeout} git "$@"; do
# 124 is timeout(1)'s special return code when it reached the
# timeout; otherwise assume fatal failure
if [[ $? -ne 124 ]]; then
die $LINENO "git call failed: [git $@]"
fi
count=$(($count + 1))
warn "timeout ${count} for git call: [git $@]"
if [ $count -eq 3 ]; then
die $LINENO "Maximum of 3 git retries reached"
fi
sleep 5
done
}
URL=${1:-https://github.com/openstack-dev/devstack}
BRANCH=${2:-master}
LOCAL=${3:-/home/stack/devstack}
git_clone $URL $LOCAL $BRANCH

View File

@ -16,13 +16,22 @@ class devstack(
$branch = 'master'
}
vcsrepo { $dir:
ensure => latest,
provider => git,
source => $source,
require => Class["user::stack"],
file { "/usr/local/bin/git_clone.sh":
owner => "root",
group => "root",
mode => 755,
source => "puppet:///modules/devstack/git_clone.sh",
}
exec { "git_clone.sh":
require => File["/usr/local/bin/git_clone.sh"],
path => "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:.",
environment => "HOME=/home/$user",
user => 'stack',
revision => $branch
group => 'stack',
command => "/usr/local/bin/git_clone.sh $devstack_git $devstack_branch $dir",
logoutput => true,
timeout => 1200
}
if $is_compute == 'true' {
@ -36,7 +45,7 @@ class devstack(
group => $user,
mode => 755,
source => "puppet:///modules/devstack/local.sh",
require => vcsrepo[ $dir ]
require => Exec[ "git_clone.sh" ]
}
file { "$dir/local.conf":
@ -44,11 +53,11 @@ class devstack(
group => $user,
mode => 644,
source => "puppet:///modules/devstack/$localrc",
require => [vcsrepo[ $dir ], file["$dir/local.sh"]]
require => File["$dir/local.sh"]
}
exec {"stack.sh":
require => [vcsrepo[ $dir ], file["$dir/local.conf"]],
require => [ File["$dir/local.conf"], File["$dir/local.sh"] ],
cwd => $dir,
path => "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:.",
environment => "HOME=/home/$user",

View File

@ -1,41 +0,0 @@
2013-11-13 - Version 0.2.0
Summary:
This release mainly focuses on a number of bugfixes, which should
significantly improve the reliability of Git and SVN. Thanks to
our many contributors for all of these fixes!
Features:
- Git:
- Add autorequire for Package['git']
- HG:
- Allow user and identity properties.
- Bzr:
- "ensure => latest" support.
- SVN:
- Added configuration parameter.
- Add support for master svn repositories.
- CVS:
- Allow for setting the CVS_RSH environment variable.
Fixes:
- Handle Puppet::Util[::Execution].withenv for 2.x and 3.x properly.
- Change path_empty? to not do full directory listing.
- Overhaul spec tests to work with rspec2.
- Git:
- Improve Git SSH usage documentation.
- Add ssh session timeouts to prevent network issues from blocking runs.
- Fix git provider checkout of a remote ref on an existing repo.
- Allow unlimited submodules (thanks to --recursive).
- Use git checkout --force instead of short -f everywhere.
- Update git provider to handle checking out into an existing (empty) dir.
- SVN:
- Handle force property. for svn.
- Adds support for changing upstream repo url.
- Check that the URL of the WC matches the URL from the manifest.
- Changed from using "update" to "switch".
- Handle revision update without source switch.
- Fix svn provider to look for '^Revision:' instead of '^Last Changed Rev:'.
- CVS:
- Documented the "module" attribute.

View File

@ -1,22 +0,0 @@
source 'https://rubygems.org'
group :development, :test do
gem 'rake', :require => false
gem 'rspec-puppet', :require => false
gem 'puppetlabs_spec_helper', :require => false
gem 'rspec-system', :require => false
gem 'rspec-system-puppet', :require => false
gem 'rspec-system-serverspec', :require => false
gem 'serverspec', :require => false
gem 'puppet-lint', :require => false
gem 'pry', :require => false
gem 'simplecov', :require => false
end
if puppetversion = ENV['PUPPET_GEM_VERSION']
gem 'puppet', puppetversion, :require => false
else
gem 'puppet', :require => false
end
# vim:ft=ruby

View File

@ -1,91 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
builder (3.2.2)
coderay (1.0.9)
diff-lcs (1.2.4)
facter (1.7.3)
hiera (1.2.1)
json_pure
highline (1.6.19)
json_pure (1.8.0)
kwalify (0.7.2)
metaclass (0.0.1)
method_source (0.8.2)
mocha (0.14.0)
metaclass (~> 0.0.1)
multi_json (1.8.0)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
net-ssh (2.7.0)
nokogiri (1.5.10)
pry (0.9.12.2)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
puppet (3.3.0)
facter (~> 1.6)
hiera (~> 1.0)
rgen (~> 0.6.5)
puppet-lint (0.3.2)
puppetlabs_spec_helper (0.4.1)
mocha (>= 0.10.5)
rake
rspec (>= 2.9.0)
rspec-puppet (>= 0.1.1)
rake (10.1.0)
rbvmomi (1.6.0)
builder
nokogiri (>= 1.4.1)
trollop
rgen (0.6.6)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.5)
rspec-expectations (2.14.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.3)
rspec-puppet (0.1.6)
rspec
rspec-system (2.2.1)
kwalify (~> 0.7.2)
net-scp (~> 1.1)
net-ssh (~> 2.6)
nokogiri (~> 1.5.9)
rbvmomi (~> 1.6)
rspec (~> 2.13)
systemu (~> 2.5)
rspec-system-puppet (2.2.0)
rspec-system (~> 2.0)
rspec-system-serverspec (1.0.0)
rspec-system (~> 2.0)
serverspec (~> 0.6.0)
serverspec (0.6.3)
highline
net-ssh
rspec (~> 2.0)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
slop (3.4.6)
systemu (2.5.2)
trollop (2.0)
PLATFORMS
ruby
DEPENDENCIES
pry
puppet
puppet-lint
puppetlabs_spec_helper
rake
rspec-puppet
rspec-system
rspec-system-puppet
rspec-system-serverspec
serverspec
simplecov

View File

@ -1,17 +0,0 @@
Copyright (C) 2010-2012 Puppet Labs Inc.
Puppet Labs can be contacted at: info@puppetlabs.com
This program and entire repository is free software; you can
redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software
Foundation; either version 2 of the License, or any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

View File

@ -1,4 +0,0 @@
name 'puppetlabs/vcsrepo'
version '0.2.0'
summary 'Manage repositories from various version control systems'
description 'Manage repositories from various version control systems'

View File

@ -1,47 +0,0 @@
Using vcsrepo with Bazaar
=========================
To create a blank repository
----------------------------
Define a `vcsrepo` without a `source` or `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => bzr
}
To branch from an existing repository
-------------------------------------
Provide the `source` location:
vcsrepo { "/path/to/repo":
ensure => present,
provider => bzr,
source => 'lp:myproj'
}
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":
ensure => present,
provider => bzr,
source => 'lp:myproj',
revision => 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x'
}
For sources that use SSH (eg, `bzr+ssh://...`, `sftp://...`)
------------------------------------------------------------
Manage your SSH keys with Puppet and use `require` in your `vcsrepo`
to ensure they are present. For more information, see the `require`
metaparameter documentation[1].
More Examples
-------------
For examples you can run, see `examples/bzr/`
[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require

View File

@ -1,66 +0,0 @@
Using vcsrepo with CVS
======================
To create a blank repository
----------------------------
Define a `vcsrepo` without a `source` or `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => cvs
}
To checkout/update from a repository
------------------------------------
To get the current mainline:
vcsrepo { "/path/to/workspace":
ensure => present,
provider => cvs,
source => ":pserver:anonymous@example.com:/sources/myproj"
}
To get a specific module on the current mainline:
vcsrepo {"/vagrant/lockss-daemon-source":
ensure => present,
provider => cvs,
source => ":pserver:anonymous@lockss.cvs.sourceforge.net:/cvsroot/lockss",
module => "lockss-daemon",
}
You can use the `compression` parameter (it works like CVS `-z`):
vcsrepo { "/path/to/workspace":
ensure => present,
provider => cvs,
compression => 3,
source => ":pserver:anonymous@example.com:/sources/myproj"
}
For a specific tag, use `revision`:
vcsrepo { "/path/to/workspace":
ensure => present,
provider => cvs,
compression => 3,
source => ":pserver:anonymous@example.com:/sources/myproj",
revision => "SOMETAG"
}
For sources that use SSH
------------------------
Manage your SSH keys with Puppet and use `require` in your `vcsrepo`
to ensure they are present. For more information, see the `require`
metaparameter documentation[1].
More Examples
-------------
For examples you can run, see `examples/cvs/`
[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require

View File

@ -1,95 +0,0 @@
Using vcsrepo with Git
======================
To create a blank repository
----------------------------
Define a `vcsrepo` without a `source` or `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => git
}
If you're defining this for a central/"official" repository, you'll
probably want to make it a "bare" repository. Do this by setting
`ensure` to `bare` instead of `present`:
vcsrepo { "/path/to/repo":
ensure => bare,
provider => git
}
To clone/pull a repository
----------------------------
To get the current [master] HEAD:
vcsrepo { "/path/to/repo":
ensure => present,
provider => git,
source => "git://example.com/repo.git"
}
For a specific revision or branch (can be a commit SHA, tag or branch name):
vcsrepo { "/path/to/repo":
ensure => present,
provider => git,
source => 'git://example.com/repo.git',
revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31'
}
vcsrepo { "/path/to/repo":
ensure => present,
provider => git,
source => 'git://example.com/repo.git',
revision => '1.1.2rc1'
}
vcsrepo { "/path/to/repo":
ensure => present,
provider => git,
source => 'git://example.com/repo.git',
revision => 'development'
}
Check out as a user:
vcsrepo { "/path/to/repo":
ensure => present,
provider => git,
source => 'git://example.com/repo.git',
revision => '0c466b8a5a45f6cd7de82c08df2fb4ce1e920a31',
user => 'someUser'
}
Keep the repository at the latest revision (note: this will always overwrite local changes to the repository):
vcsrepo { "/path/to/repo":
ensure => latest,
provider => git,
source => 'git://example.com/repo.git',
revision => 'master',
}
For sources that use SSH (eg, `username@server:...`)
----------------------------------------------------
If your SSH key is associated with a user, simply fill the `user` parameter to use his keys.
Example:
user => 'toto' # will use toto's $HOME/.ssh setup
Otherwise, manage your SSH keys with Puppet and use `require` in your `vcsrepo` to ensure they are present.
For more information, see the `require` metaparameter documentation[1].
More Examples
-------------
For examples you can run, see `examples/git/`
[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require

View File

@ -1,73 +0,0 @@
Using vcsrepo with Mercurial
============================
To create a blank repository
----------------------------
Define a `vcsrepo` without a `source` or `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg
}
To clone/pull & update a repository
-----------------------------------
To get the default branch tip:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg,
source => "http://hg.example.com/myrepo"
}
For a specific changeset, use `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg,
source => "http://hg.example.com/myrepo",
revision => '21ea4598c962'
}
You can also set `revision` to a tag:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg,
source => "http://hg.example.com/myrepo",
revision => '1.1.2'
}
Check out as a user:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg,
source => "http://hg.example.com/myrepo",
user => 'user'
}
Specify an SSH identity key:
vcsrepo { "/path/to/repo":
ensure => present,
provider => hg,
source => "ssh://hg@hg.example.com/myrepo",
identity => "/home/user/.ssh/id_dsa,
}
For sources that use SSH (eg, `ssh://...`)
------------------------------------------
Manage your SSH keys with Puppet and use `require` in your `vcsrepo`
to ensure they are present. For more information, see the `require`
metaparameter documentation[1].
More Examples
-------------
For examples you can run, see `examples/hg/`
[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require

View File

@ -1,62 +0,0 @@
Using vcsrepo with Subversion
=============================
To create a blank repository
----------------------------
To create a blank repository suitable for use as a central repository,
define a `vcsrepo` without a `source` or `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => svn
}
To checkout from a repository
-----------------------------
Provide a `source` qualified to the branch/tag you want:
vcsrepo { "/path/to/repo":
ensure => present,
provider => svn,
source => "svn://svnrepo/hello/branches/foo"
}
You can provide a specific `revision`:
vcsrepo { "/path/to/repo":
ensure => present,
provider => svn,
source => "svn://svnrepo/hello/branches/foo",
revision => '1234'
}
Using a specified Subversion 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":
ensure => present,
provider => svn,
source => "svn://svnrepo/hello/branches/foo",
configuration => "/path/to/.subversion"
}
For sources that use SSH (eg, `svn+ssh://...`)
----------------------------------------------
Manage your SSH keys with Puppet and use `require` in your `vcsrepo`
to ensure they are present. For more information, see the `require`
metaparameter documentation[1].
More Examples
-------------
For examples you can run, see `examples/svn/`
[1]: http://docs.puppetlabs.com/references/stable/metaparameter.html#require

View File

@ -1,32 +0,0 @@
vcsrepo
=======
[![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-vcsrepo.png?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-vcsrepo)
Purpose
-------
This provides a single type, `vcsrepo`.
This type can be used to describe:
* A working copy checked out from a (remote or local) source, at an
arbitrary revision
* A "blank" working copy not associated with a source (when it makes
sense for the VCS being used)
* A "blank" central repository (when the distinction makes sense for the VCS
being used)
Supported Version Control Systems
---------------------------------
This module supports a wide range of VCS types, each represented by a
separate provider.
For information on how to use this module with a specific VCS, see
`README.<VCS>.markdown`.
License
-------
See LICENSE.

View File

@ -1 +0,0 @@
require 'puppetlabs_spec_helper/rake_tasks'

View File

@ -1,6 +0,0 @@
vcsrepo { '/tmp/vcstest-bzr-branch':
ensure => present,
provider => bzr,
source => 'lp:do',
revision => '1312',
}

View File

@ -1,4 +0,0 @@
vcsrepo { '/tmp/vcstest-bzr-init':
ensure => present,
provider => bzr,
}

View File

@ -1,11 +0,0 @@
vcsrepo { '/tmp/vcstest-cvs-repo':
ensure => present,
provider => cvs,
}
vcsrepo { '/tmp/vcstest-cvs-workspace-local':
ensure => present,
provider => cvs,
source => '/tmp/vcstest-cvs-repo',
require => Vcsrepo['/tmp/vcstest-cvs-repo'],
}

View File

@ -1,5 +0,0 @@
vcsrepo { '/tmp/vcstest-cvs-workspace-remote':
ensure => present,
provider => cvs,
source => ':pserver:anonymous@cvs.sv.gnu.org:/sources/leetcvrt',
}

View File

@ -1,4 +0,0 @@
vcsrepo { '/tmp/vcstest-git-bare':
ensure => bare,
provider => git,
}

View File

@ -1,5 +0,0 @@
vcsrepo { '/tmp/vcstest-git-clone':
ensure => present,
provider => git,
source => 'git://github.com/bruce/rtex.git',
}

View File

@ -1,4 +0,0 @@
vcsrepo { '/tmp/vcstest-git-wc':
ensure => present,
provider => git,
}

View File

@ -1,6 +0,0 @@
vcsrepo { '/tmp/vcstest-hg-clone':
ensure => present,
provider => hg,
source => 'http://hg.basho.com/riak',
revision => 'riak-0.5.3',
}

View File

@ -1,4 +0,0 @@
vcsrepo { '/tmp/vcstest-hg-init':
ensure => present,
provider => hg,
}

View File

@ -1,5 +0,0 @@
vcsrepo { '/tmp/vcstest-svn-checkout':
ensure => present,
provider => svn,
source => 'http://svn.edgewall.org/repos/babel/trunk',
}

View File

@ -1,4 +0,0 @@
vcsrepo { '/tmp/vcstest-svn-server':
ensure => present,
provider => svn,
}

View File

@ -1,42 +0,0 @@
require 'tmpdir'
require 'digest/md5'
require 'fileutils'
# Abstract
class Puppet::Provider::Vcsrepo < Puppet::Provider
private
def set_ownership
owner = @resource.value(:owner) || nil
group = @resource.value(:group) || nil
FileUtils.chown_R(owner, group, @resource.value(:path))
end
def path_exists?
File.directory?(@resource.value(:path))
end
def path_empty?
# Path is empty if the only entries are '.' and '..'
d = Dir.new(@resource.value(:path))
d.read # should return '.'
d.read # should return '..'
d.read.nil?
end
# Note: We don't rely on Dir.chdir's behavior of automatically returning the
# value of the last statement -- for easier stubbing.
def at_path(&block) #:nodoc:
value = nil
Dir.chdir(@resource.value(:path)) do
value = yield
end
value
end
def tempdir
@tempdir ||= File.join(Dir.tmpdir, 'vcsrepo-' + Digest::MD5.hexdigest(@resource.value(:path)))
end
end

View File

@ -1,85 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:bzr, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports Bazaar repositories"
optional_commands :bzr => 'bzr'
has_features :reference_tracking
def create
if !@resource.value(:source)
create_repository(@resource.value(:path))
else
clone_repository(@resource.value(:revision))
end
end
def working_copy_exists?
File.directory?(File.join(@resource.value(:path), '.bzr'))
end
def exists?
working_copy_exists?
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def revision
at_path do
current_revid = bzr('version-info')[/^revision-id:\s+(\S+)/, 1]
desired = @resource.value(:revision)
begin
desired_revid = bzr('revision-info', desired).strip.split(/\s+/).last
rescue Puppet::ExecutionFailure
# Possible revid available during update (but definitely not current)
desired_revid = nil
end
if current_revid == desired_revid
desired
else
current_revid
end
end
end
def revision=(desired)
at_path do
begin
bzr('update', '-r', desired)
rescue Puppet::ExecutionFailure
bzr('update', '-r', desired, ':parent')
end
end
end
def latest
at_path do
bzr('version-info', ':parent')[/^revision-id:\s+(\S+)/, 1]
end
end
def latest?
at_path do
return self.revision == self.latest
end
end
private
def create_repository(path)
bzr('init', path)
end
def clone_repository(revision)
args = ['branch']
if revision
args.push('-r', revision)
end
args.push(@resource.value(:source),
@resource.value(:path))
bzr(*args)
end
end

View File

@ -1,137 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:cvs, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports CVS repositories/workspaces"
optional_commands :cvs => 'cvs'
has_features :gzip_compression, :reference_tracking, :modules, :cvs_rsh
def create
if !@resource.value(:source)
create_repository(@resource.value(:path))
else
checkout_repository
end
update_owner
end
def exists?
if @resource.value(:source)
directory = File.join(@resource.value(:path), 'CVS')
else
directory = File.join(@resource.value(:path), 'CVSROOT')
end
File.directory?(directory)
end
def working_copy_exists?
File.directory?(File.join(@resource.value(:path), 'CVS'))
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def latest?
debug "Checking for updates because 'ensure => latest'"
at_path do
# We cannot use -P to prune empty dirs, otherwise
# CVS would report those as "missing", regardless
# if they have contents or updates.
is_current = (runcvs('-nq', 'update', '-d').strip == "")
if (!is_current) then debug "There are updates available on the checkout's current branch/tag." end
return is_current
end
end
def latest
# CVS does not have a conecpt like commit-IDs or change
# sets, so we can only have the current branch name (or the
# requested one, if that differs) as the "latest" revision.
should = @resource.value(:revision)
current = self.revision
return should != current ? should : current
end
def revision
if !@rev
if File.exist?(tag_file)
contents = File.read(tag_file).strip
# Note: Doesn't differentiate between N and T entries
@rev = contents[1..-1]
else
@rev = 'HEAD'
end
debug "Checkout is on branch/tag '#{@rev}'"
end
return @rev
end
def revision=(desired)
at_path do
runcvs('update', '-dr', desired, '.')
update_owner
@rev = desired
end
end
private
def tag_file
File.join(@resource.value(:path), 'CVS', 'Tag')
end
def checkout_repository
dirname, basename = File.split(@resource.value(:path))
Dir.chdir(dirname) do
args = ['-d', @resource.value(:source)]
if @resource.value(:compression)
args.push('-z', @resource.value(:compression))
end
args.push('checkout')
if @resource.value(:revision)
args.push('-r', @resource.value(:revision))
end
args.push('-d', basename, module_name)
runcvs(*args)
end
end
# When the source:
# * Starts with ':' (eg, :pserver:...)
def module_name
if (m = @resource.value(:module))
m
elsif (source = @resource.value(:source))
source[0, 1] == ':' ? File.basename(source) : '.'
end
end
def create_repository(path)
runcvs('-d', path, 'init')
end
def update_owner
if @resource.value(:owner) or @resource.value(:group)
set_ownership
end
end
def runcvs(*args)
if @resource.value(:cvs_rsh)
debug "Using CVS_RSH = " + @resource.value(:cvs_rsh)
e = { :CVS_RSH => @resource.value(:cvs_rsh) }
else
e = {}
end
# The location of withenv changed from Puppet 2.x to 3.x
withenv = Puppet::Util.method(:withenv) if Puppet::Util.respond_to?(:withenv)
withenv = Puppet::Util::Execution.method(:withenv) if Puppet::Util::Execution.respond_to?(:withenv)
fail("Cannot set custom environment #{e}") if e && !withenv
withenv.call e do
Puppet.debug cvs *args
end
end
end

View File

@ -1,12 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:dummy, :parent => Puppet::Provider::Vcsrepo) do
desc "Dummy default provider"
defaultfor :vcsrepo => :dummy
def working_copy_exists?
providers = @resource.class.providers.map{|x| x.to_s}.sort.reject{|x| x == "dummy"}.join(", ") rescue "none"
raise("vcsrepo resource must have a provider, available: #{providers}")
end
end

View File

@ -1,323 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports Git repositories"
##TODO modify the commands below so that the su - is included
optional_commands :git => 'git',
:su => 'su'
has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes, :user
def create
if !@resource.value(:source)
init_repository(@resource.value(:path))
else
clone_repository(@resource.value(:source), @resource.value(:path))
if @resource.value(:revision)
if @resource.value(:ensure) == :bare
notice "Ignoring revision for bare repository"
else
checkout
end
end
if @resource.value(:ensure) != :bare
update_submodules
end
end
update_owner_and_excludes
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def latest?
at_path do
return self.revision == self.latest
end
end
def latest
branch = on_branch?
if branch == 'master'
return get_revision("#{@resource.value(:remote)}/HEAD")
elsif branch == '(no branch)'
return get_revision('HEAD')
else
return get_revision("#{@resource.value(:remote)}/%s" % branch)
end
end
def revision
update_references
current = at_path { git_with_identity('rev-parse', 'HEAD').chomp }
return current unless @resource.value(:revision)
if tag_revision?(@resource.value(:revision))
canonical = at_path { git_with_identity('show', @resource.value(:revision)).scan(/^commit (.*)/).to_s }
else
# if it's not a tag, look for it as a local ref
canonical = at_path { git_with_identity('rev-parse', '--revs-only', @resource.value(:revision)).chomp }
if canonical.empty?
# git rev-parse executed properly but didn't find the ref;
# look for it in the remote
remote_ref = at_path { git_with_identity('ls-remote', '--heads', '--tags', @resource.value(:remote), @resource.value(:revision)).chomp }
if remote_ref.empty?
fail("#{@resource.value(:revision)} is not a local or remote ref")
end
# $ git ls-remote --heads --tags origin feature/cvs
# 7d4244b35e72904e30130cad6d2258f901c16f1a refs/heads/feature/cvs
canonical = remote_ref.split.first
end
end
if current == canonical
@resource.value(:revision)
else
current
end
end
def revision=(desired)
checkout(desired)
if local_branch_revision?(desired)
# reset instead of pull to avoid merge conflicts. assuming remote is
# authoritative.
# might be worthwhile to have an allow_local_changes param to decide
# whether to reset or pull when we're ensuring latest.
at_path { git_with_identity('reset', '--hard', "#{@resource.value(:remote)}/#{desired}") }
end
if @resource.value(:ensure) != :bare
update_submodules
end
update_owner_and_excludes
end
def bare_exists?
bare_git_config_exists? && !working_copy_exists?
end
def working_copy_exists?
File.directory?(File.join(@resource.value(:path), '.git'))
end
def exists?
working_copy_exists? || bare_exists?
end
def update_remote_origin_url
current = git_with_identity('config', 'remote.origin.url')
unless @resource.value(:source).nil?
if current.nil? or current.strip != @resource.value(:source)
git_with_identity('config', 'remote.origin.url', @resource.value(:source))
end
end
end
def update_references
at_path do
update_remote_origin_url
git_with_identity('fetch', @resource.value(:remote))
git_with_identity('fetch', '--tags', @resource.value(:remote))
update_owner_and_excludes
end
end
private
def bare_git_config_exists?
File.exist?(File.join(@resource.value(:path), 'config'))
end
def clone_repository(source, path)
check_force
args = ['clone']
if @resource.value(:ensure) == :bare
args << '--bare'
end
if !File.exist?(File.join(@resource.value(:path), '.git'))
args.push(source, path)
Dir.chdir("/") do
git_with_identity(*args)
end
else
notice "Repo has already been cloned"
end
end
def check_force
if path_exists? and not path_empty?
if @resource.value(:force)
notice "Removing %s to replace with vcsrepo." % @resource.value(:path)
destroy
else
raise Puppet::Error, "Could not create repository (non-repository at path)"
end
end
end
def init_repository(path)
check_force
if @resource.value(:ensure) == :bare && working_copy_exists?
convert_working_copy_to_bare
elsif @resource.value(:ensure) == :present && bare_exists?
convert_bare_to_working_copy
else
# normal init
FileUtils.mkdir(@resource.value(:path))
FileUtils.chown(@resource.value(:user), nil, @resource.value(:path)) if @resource.value(:user)
args = ['init']
if @resource.value(:ensure) == :bare
args << '--bare'
end
at_path do
git_with_identity(*args)
end
end
end
# Convert working copy to bare
#
# Moves:
# <path>/.git
# to:
# <path>/
def convert_working_copy_to_bare
notice "Converting working copy repository to bare repository"
FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir)
FileUtils.rm_rf(@resource.value(:path))
FileUtils.mv(tempdir, @resource.value(:path))
end
# Convert bare to working copy
#
# Moves:
# <path>/
# to:
# <path>/.git
def convert_bare_to_working_copy
notice "Converting bare repository to working copy repository"
FileUtils.mv(@resource.value(:path), tempdir)
FileUtils.mkdir(@resource.value(:path))
FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git'))
if commits_in?(File.join(@resource.value(:path), '.git'))
reset('HEAD')
git_with_identity('checkout', '--force')
update_owner_and_excludes
end
end
def commits_in?(dot_git)
Dir.glob(File.join(dot_git, 'objects/info/*'), File::FNM_DOTMATCH) do |e|
return true unless %w(. ..).include?(File::basename(e))
end
false
end
def checkout(revision = @resource.value(:revision))
if !local_branch_revision? && remote_branch_revision?
at_path { git_with_identity('checkout', '-b', revision, '--track', "#{@resource.value(:remote)}/#{revision}") }
else
at_path { git_with_identity('checkout', '--force', revision) }
end
end
def reset(desired)
at_path do
git_with_identity('reset', '--hard', desired)
end
end
def update_submodules
at_path do
git_with_identity('submodule', 'update', '--init', '--recursive')
end
end
def remote_branch_revision?(revision = @resource.value(:revision))
# git < 1.6 returns '#{@resource.value(:remote)}/#{revision}'
# git 1.6+ returns 'remotes/#{@resource.value(:remote)}/#{revision}'
branch = at_path { branches.grep /(remotes\/)?#{@resource.value(:remote)}\/#{revision}/ }
branch unless branch.empty?
end
def local_branch_revision?(revision = @resource.value(:revision))
at_path { branches.include?(revision) }
end
def tag_revision?(revision = @resource.value(:revision))
at_path { tags.include?(revision) }
end
def branches
at_path { git_with_identity('branch', '-a') }.gsub('*', ' ').split(/\n/).map { |line| line.strip }
end
def on_branch?
at_path { git_with_identity('branch', '-a') }.split(/\n/).grep(/\*/).first.to_s.gsub('*', '').strip
end
def tags
at_path { git_with_identity('tag', '-l') }.split(/\n/).map { |line| line.strip }
end
def set_excludes
at_path { open('.git/info/exclude', 'w') { |f| @resource.value(:excludes).each { |ex| f.write(ex + "\n") }}}
end
def get_revision(rev)
if !working_copy_exists?
create
end
at_path do
update_remote_origin_url
git_with_identity('fetch', @resource.value(:remote))
git_with_identity('fetch', '--tags', @resource.value(:remote))
end
current = at_path { git_with_identity('rev-parse', rev).strip }
if @resource.value(:revision)
if local_branch_revision?
canonical = at_path { git_with_identity('rev-parse', @resource.value(:revision)).strip }
elsif remote_branch_revision?
canonical = at_path { git_with_identity('rev-parse', "#{@resource.value(:remote)}/" + @resource.value(:revision)).strip }
end
current = @resource.value(:revision) if current == canonical
end
update_owner_and_excludes
return current
end
def update_owner_and_excludes
if @resource.value(:owner) or @resource.value(:group)
set_ownership
end
if @resource.value(:excludes)
set_excludes
end
end
def git_with_identity(*args)
if @resource.value(:identity)
Tempfile.open('git-helper') do |f|
f.puts '#!/bin/sh'
f.puts "exec ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -oConnectTimeout=120 -i #{@resource.value(:identity)} $*"
f.close
FileUtils.chmod(0755, f.path)
env_save = ENV['GIT_SSH']
ENV['GIT_SSH'] = f.path
ret = git(*args)
ENV['GIT_SSH'] = env_save
return ret
end
elsif @resource.value(:user)
su(@resource.value(:user), '-c', "git #{args.join(' ')}" )
else
git(*args)
end
end
end

View File

@ -1,115 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:hg, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports Mercurial repositories"
optional_commands :hg => 'hg',
:su => 'su'
has_features :reference_tracking, :ssh_identity, :user
def create
if !@resource.value(:source)
create_repository(@resource.value(:path))
else
clone_repository(@resource.value(:revision))
end
update_owner
end
def working_copy_exists?
File.directory?(File.join(@resource.value(:path), '.hg'))
end
def exists?
working_copy_exists?
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def latest?
at_path do
return self.revision == self.latest
end
end
def latest
at_path do
begin
hg_wrapper('incoming', '--branch', '.', '--newest-first', '--limit', '1')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1]
rescue Puppet::ExecutionFailure
# If there are no new changesets, return the current nodeid
self.revision
end
end
end
def revision
at_path do
current = hg_wrapper('parents')[/^changeset:\s+(?:-?\d+):(\S+)/m, 1]
desired = @resource.value(:revision)
if desired
# Return the tag name if it maps to the current nodeid
mapped = hg_wrapper('tags')[/^#{Regexp.quote(desired)}\s+\d+:(\S+)/m, 1]
if current == mapped
desired
else
current
end
else
current
end
end
end
def revision=(desired)
at_path do
begin
hg_wrapper('pull')
rescue
end
begin
hg_wrapper('merge')
rescue Puppet::ExecutionFailure
# If there's nothing to merge, just skip
end
hg_wrapper('update', '--clean', '-r', desired)
end
update_owner
end
private
def create_repository(path)
hg_wrapper('init', path)
end
def clone_repository(revision)
args = ['clone']
if revision
args.push('-u', revision)
end
args.push(@resource.value(:source),
@resource.value(:path))
hg_wrapper(*args)
end
def update_owner
if @resource.value(:owner) or @resource.value(:group)
set_ownership
end
end
def hg_wrapper(*args)
if @resource.value(:identity)
args += ["--ssh", "ssh -oStrictHostKeyChecking=no -oPasswordAuthentication=no -oKbdInteractiveAuthentication=no -oChallengeResponseAuthentication=no -i #{@resource.value(:identity)}"]
end
if @resource.value(:user)
args.map! { |a| if a =~ /\s/ then "'#{a}'" else a end } # Adds quotes to arguments with whitespaces.
su(@resource.value(:user), '-c', "hg #{args.join(' ')}")
else
hg(*args)
end
end
end

View File

@ -1,124 +0,0 @@
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:svn, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports Subversion repositories"
optional_commands :svn => 'svn',
:svnadmin => 'svnadmin',
:svnlook => 'svnlook'
has_features :filesystem_types, :reference_tracking, :basic_auth, :configuration
def create
if !@resource.value(:source)
create_repository(@resource.value(:path))
else
checkout_repository(@resource.value(:source),
@resource.value(:path),
@resource.value(:revision))
end
update_owner
end
def working_copy_exists?
if File.directory?(@resource.value(:path))
# :path is an svn checkout
return true if File.directory?(File.join(@resource.value(:path), '.svn'))
# :path is an svn server
return true if svnlook('uuid', @resource.value(:path))
end
false
end
def exists?
working_copy_exists?
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def latest?
at_path do
(self.revision >= self.latest) and (@resource.value(:source) == self.sourceurl)
end
end
def buildargs
args = ['--non-interactive']
if @resource.value(:basic_auth_username) && @resource.value(:basic_auth_password)
args.push('--username', @resource.value(:basic_auth_username))
args.push('--password', @resource.value(:basic_auth_password))
args.push('--no-auth-cache')
end
if @resource.value(:force)
args.push('--force')
end
if @resource.value(:configuration)
args.push('--config-dir', @resource.value(:configuration))
end
args
end
def latest
args = buildargs.push('info', '-r', 'HEAD')
at_path do
svn(*args)[/^Revision:\s+(\d+)/m, 1]
end
end
def sourceurl
args = buildargs.push('info')
at_path do
svn(*args)[/^URL:\s+(\S+)/m, 1]
end
end
def revision
args = buildargs.push('info')
at_path do
svn(*args)[/^Revision:\s+(\d+)/m, 1]
end
end
def revision=(desired)
args = if @resource.value(:source)
buildargs.push('switch', '-r', desired, @resource.value(:source))
else
buildargs.push('update', '-r', desired)
end
at_path do
svn(*args)
end
update_owner
end
private
def checkout_repository(source, path, revision)
args = buildargs.push('checkout')
if revision
args.push('-r', revision)
end
args.push(source, path)
svn(*args)
end
def create_repository(path)
args = ['create']
if @resource.value(:fstype)
args.push('--fs-type', @resource.value(:fstype))
end
args << path
svnadmin(*args)
end
def update_owner
if @resource.value(:owner) or @resource.value(:group)
set_ownership
end
end
end

View File

@ -1,198 +0,0 @@
require 'pathname'
Puppet::Type.newtype(:vcsrepo) do
desc "A local version control repository"
feature :gzip_compression,
"The provider supports explicit GZip compression levels"
feature :basic_auth,
"The provider supports HTTP Basic Authentication"
feature :bare_repositories,
"The provider differentiates between bare repositories
and those with working copies",
:methods => [:bare_exists?, :working_copy_exists?]
feature :filesystem_types,
"The provider supports different filesystem types"
feature :reference_tracking,
"The provider supports tracking revision references that can change
over time (eg, some VCS tags and branch names)"
feature :ssh_identity,
"The provider supports a configurable SSH identity file"
feature :user,
"The provider can run as a different user"
feature :modules,
"The repository contains modules that can be chosen of"
feature :multiple_remotes,
"The repository tracks multiple remote repositories"
feature :configuration,
"The configuration directory to use"
feature :cvs_rsh,
"The provider understands the CVS_RSH environment variable"
ensurable do
attr_accessor :latest
def insync?(is)
@should ||= []
case should
when :present
return true unless [:absent, :purged, :held].include?(is)
when :latest
if is == :latest
return true
else
return false
end
when :bare
return is == :bare
end
end
newvalue :present do
notice "Creating repository from present"
provider.create
end
newvalue :bare, :required_features => [:bare_repositories] do
if !provider.exists?
provider.create
end
end
newvalue :absent do
provider.destroy
end
newvalue :latest, :required_features => [:reference_tracking] do
if provider.exists?
if provider.respond_to?(:update_references)
provider.update_references
end
if provider.respond_to?(:latest?)
reference = provider.latest || provider.revision
else
reference = resource.value(:revision) || provider.revision
end
notice "Updating to latest '#{reference}' revision"
provider.revision = reference
else
notice "Creating repository from latest"
provider.create
end
end
def retrieve
prov = @resource.provider
if prov
if prov.working_copy_exists?
(@should.include?(:latest) && prov.latest?) ? :latest : :present
elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
:bare
else
:absent
end
else
raise Puppet::Error, "Could not find provider"
end
end
end
newparam :path do
desc "Absolute path to repository"
isnamevar
validate do |value|
path = Pathname.new(value)
unless path.absolute?
raise ArgumentError, "Path must be absolute: #{path}"
end
end
end
newparam :source do
desc "The source URI for the repository"
end
newparam :fstype, :required_features => [:filesystem_types] do
desc "Filesystem type"
end
newproperty :revision do
desc "The revision of the repository"
newvalue(/^\S+$/)
end
newparam :owner do
desc "The user/uid that owns the repository files"
end
newparam :group do
desc "The group/gid that owns the repository files"
end
newparam :user do
desc "The user to run for repository operations"
end
newparam :excludes do
desc "Files to be excluded from the repository"
end
newparam :force do
desc "Force repository creation, destroying any files on the path in the process."
newvalues(:true, :false)
defaultto false
end
newparam :compression, :required_features => [:gzip_compression] do
desc "Compression level"
validate do |amount|
unless Integer(amount).between?(0, 6)
raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
end
end
end
newparam :basic_auth_username, :required_features => [:basic_auth] do
desc "HTTP Basic Auth username"
end
newparam :basic_auth_password, :required_features => [:basic_auth] do
desc "HTTP Basic Auth password"
end
newparam :identity, :required_features => [:ssh_identity] do
desc "SSH identity file"
end
newparam :module, :required_features => [:modules] do
desc "The repository module to manage"
end
newparam :remote, :required_features => [:multiple_remotes] do
desc "The remote repository to track"
defaultto "origin"
end
newparam :configuration, :required_features => [:configuration] do
desc "The configuration directory to use"
end
newparam :cvs_rsh, :required_features => [:cvs_rsh] do
desc "The value to be used for the CVS_RSH environment variable."
end
autorequire(:package) do
['git', 'git-core']
end
end

View File

@ -1,171 +0,0 @@
{
"name": "puppetlabs/vcsrepo",
"version": "0.2.0",
"source": "UNKNOWN",
"author": "puppetlabs",
"license": "Apache License, Version 2.0",
"summary": "Manage repositories from various version control systems",
"description": "Manage repositories from various version control systems",
"project_page": "UNKNOWN",
"dependencies": [
],
"types": [
{
"name": "vcsrepo",
"doc": "A local version control repository",
"properties": [
{
"name": "ensure",
"doc": " Valid values are `present`, `bare`, `absent`, `latest`."
},
{
"name": "revision",
"doc": "The revision of the repository Values can match `/^\\S+$/`."
}
],
"parameters": [
{
"name": "path",
"doc": "Absolute path to repository"
},
{
"name": "source",
"doc": "The source URI for the repository"
},
{
"name": "fstype",
"doc": "Filesystem type Requires features filesystem_types."
},
{
"name": "owner",
"doc": "The user/uid that owns the repository files"
},
{
"name": "group",
"doc": "The group/gid that owns the repository files"
},
{
"name": "user",
"doc": "The user to run for repository operations"
},
{
"name": "excludes",
"doc": "Files to be excluded from the repository"
},
{
"name": "force",
"doc": "Force repository creation, destroying any files on the path in the process. Valid values are `true`, `false`."
},
{
"name": "compression",
"doc": "Compression level Requires features gzip_compression."
},
{
"name": "basic_auth_username",
"doc": "HTTP Basic Auth username Requires features basic_auth."
},
{
"name": "basic_auth_password",
"doc": "HTTP Basic Auth password Requires features basic_auth."
},
{
"name": "identity",
"doc": "SSH identity file Requires features ssh_identity."
},
{
"name": "module",
"doc": "The repository module to manage Requires features modules."
},
{
"name": "remote",
"doc": "The remote repository to track Requires features multiple_remotes."
},
{
"name": "configuration",
"doc": "The configuration directory to use Requires features configuration."
},
{
"name": "cvs_rsh",
"doc": "The value to be used for the CVS_RSH environment variable. Requires features cvs_rsh."
}
],
"providers": [
{
"name": "bzr",
"doc": "Supports Bazaar repositories\n\nRequired binaries: `bzr`. Supported features: `reference_tracking`."
},
{
"name": "cvs",
"doc": "Supports CVS repositories/workspaces\n\nRequired binaries: `cvs`. Supported features: `cvs_rsh`, `gzip_compression`, `modules`, `reference_tracking`."
},
{
"name": "dummy",
"doc": "Dummy default provider\n\nDefault for `vcsrepo` == `dummy`."
},
{
"name": "git",
"doc": "Supports Git repositories\n\nRequired binaries: `git`, `su`. Supported features: `bare_repositories`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `user`."
},
{
"name": "hg",
"doc": "Supports Mercurial repositories\n\nRequired binaries: `hg`, `su`. Supported features: `reference_tracking`, `ssh_identity`, `user`."
},
{
"name": "svn",
"doc": "Supports Subversion repositories\n\nRequired binaries: `svn`, `svnadmin`, `svnlook`. Supported features: `basic_auth`, `configuration`, `filesystem_types`, `reference_tracking`."
}
]
}
],
"checksums": {
"CHANGELOG": "c41bec2dddc2a3de4c10b56e4d348492",
"Gemfile": "a25ee68d266f452c3cf19537736e778d",
"Gemfile.lock": "aac999a29c92e12f0af120c97bda73f7",
"LICENSE": "b8d96fef1f55096f9d39326408122136",
"Modulefile": "e69308b7a49f10b2695057c33eeba5f6",
"README.BZR.markdown": "97f638d169a1c39d461c3f2c0e2ec32f",
"README.CVS.markdown": "7bc2fd4def5d18451dc8d5fc86d2910c",
"README.GIT.markdown": "9adc244b55c7441076541dfc7fdd1a68",
"README.HG.markdown": "438ebb7b5262edea0a5b69856dfc9415",
"README.SVN.markdown": "4f8de2b336022700aa557a59c7770e57",
"README.markdown": "aa36edae60f06e5cb0fef00c3d5b6618",
"Rakefile": "0254db5d3fc38c67a2c160d7296a24f8",
"examples/bzr/branch.pp": "05c66419324a576b9b28df876673580d",
"examples/bzr/init_repo.pp": "fadd2321866ffb0aacff698d2dc1f0ca",
"examples/cvs/local.pp": "7fbde03a5c71edf168267ae42d0bbcbc",
"examples/cvs/remote.pp": "491f18f752752bec6133a88de242c44d",
"examples/git/bare_init.pp": "7cf56abffdf99f379153166f18f961f8",
"examples/git/clone.pp": "0e3181990c095efee1498ccfca5897fb",
"examples/git/working_copy_init.pp": "99d92d9957e78a0c03f9cbed989c79ca",
"examples/hg/clone.pp": "c92bbd704a4c2da55fff5f45955ce6d1",
"examples/hg/init_repo.pp": "bf5fa0ab48a2f5a1ccb63768d961413d",
"examples/svn/checkout.pp": "9ef7a8fbd3a763fa3894efa864047023",
"examples/svn/server.pp": "94b26f6e50d5e411b33b1ded1bc2138a",
"lib/puppet/provider/vcsrepo/bzr.rb": "52f4d40153e0a3bc54be1b7dfa18b5f1",
"lib/puppet/provider/vcsrepo/cvs.rb": "1ce8d98a2ffad4bf0c575af014270c8b",
"lib/puppet/provider/vcsrepo/dummy.rb": "2f8159468d6ecc8087debde858a80dd6",
"lib/puppet/provider/vcsrepo/git.rb": "7c453bfe9abe5367902f090b554c51e2",
"lib/puppet/provider/vcsrepo/hg.rb": "01887f986db627ffc1a8ff7a52328ddb",
"lib/puppet/provider/vcsrepo/svn.rb": "03b14667e002db9452c597e1b21718dd",
"lib/puppet/provider/vcsrepo.rb": "dbd72590771291f1db23a41ac048ed9d",
"lib/puppet/type/vcsrepo.rb": "bf01ae48b0d2ae542bc8c0f65da93c64",
"spec/fixtures/bzr_version_info.txt": "5edb13429faf2f0b9964b4326ef49a65",
"spec/fixtures/git_branch_a.txt": "2371229e7c1706c5ab8f90f0cd57230f",
"spec/fixtures/git_branch_feature_bar.txt": "70903a4dc56f7300fbaa54c295b52c4f",
"spec/fixtures/git_branch_none.txt": "acaa61de6a7f0f5ca39b763799dcb9a6",
"spec/fixtures/hg_parents.txt": "efc28a1bd3f1ce7fb4481f76feed3f6e",
"spec/fixtures/hg_tags.txt": "8383048b15adb3d58a92ea0c8b887537",
"spec/fixtures/svn_info.txt": "978db25720a098e5de48388fe600c062",
"spec/spec.opts": "a600ded995d948e393fbe2320ba8e51c",
"spec/spec_helper.rb": "ce4d39194e1b8486de8ec25f639f6762",
"spec/support/filesystem_helpers.rb": "eb2a8eb3769865004c84e971ccb1396c",
"spec/support/fixture_helpers.rb": "61781d99ea201e9da6d23c64a25cc285",
"spec/unit/puppet/provider/vcsrepo/bzr_spec.rb": "320b5be01c84f3424ac99729e42b4562",
"spec/unit/puppet/provider/vcsrepo/cvs_spec.rb": "24f760cb53be365ca185cd196c03743a",
"spec/unit/puppet/provider/vcsrepo/git_spec.rb": "2159d3a06a2a764dcf8e3da141390734",
"spec/unit/puppet/provider/vcsrepo/hg_spec.rb": "b6eabd1167753f1a6a87eeef897bc1c5",
"spec/unit/puppet/provider/vcsrepo/svn_spec.rb": "957328714f6df1e90b663514615f460e",
"spec/unit/puppet/type/README.markdown": "de26a7643813abd6c2e7e28071b1ef94"
}
}

View File

@ -1,5 +0,0 @@
revision-id: menesis@pov.lt-20100309191856-4wmfqzc803fj300x
date: 2010-03-09 21:18:56 +0200
build-date: 2010-03-14 00:42:43 -0800
revno: 2634
branch-nick: mytest

View File

@ -1,14 +0,0 @@
feature/foo
feature/bar
feature/baz
feature/quux
only/local
* master
refactor/foo
origin/HEAD
origin/feature/foo
origin/feature/bar
origin/feature/baz
origin/feature/quux
origin/only/remote
origin/master

View File

@ -1,14 +0,0 @@
feature/foo
* feature/bar
feature/baz
feature/quux
only/local
master
refactor/foo
origin/HEAD
origin/feature/foo
origin/feature/bar
origin/feature/baz
origin/feature/quux
origin/only/remote
origin/master

View File

@ -1,15 +0,0 @@
feature/foo
feature/bar
feature/baz
feature/quux
only/local
master
* (no branch)
refactor/foo
origin/HEAD
origin/feature/foo
origin/feature/bar
origin/feature/baz
origin/feature/quux
origin/only/remote
origin/master

View File

@ -1,6 +0,0 @@
changeset: 3:34e6012c783a
parent: 2:21ea4598c962
parent: 1:9d0ff0028458
user: Test User <test.user@example.com>
date: Fri Aug 07 13:13:02 2009 -0400
summary: merge

View File

@ -1,18 +0,0 @@
tip 1019:bca3f20b249b
0.9.1 1017:76ce7cca95d8
0.9 1001:dbaa6f4ec585
0.8 839:65b66ac0fc83
0.7.1 702:e1357f00129f
0.7 561:7b2af3b4c968
0.6.3 486:e38077f4e4aa
0.6.2 405:07bb099b7b10
0.6.1 389:93750f3fbbe2
0.6 369:34e6012c783a
0.5.3 321:5ffa6ae7e699
0.5.2 318:fdc2c2e4cebe
0.5.1 315:33a5ea0cbe7a
0.5 313:47490716f4c9
0.4 240:47fa3a14cc63
0.3.1 132:bc231db18e1c
0.3 130:661615e510dd
0.2 81:f98d13b442f6

View File

@ -1,10 +0,0 @@
Path: .
URL: http://example.com/svn/trunk
Repository Root: http://example.com/svn
Repository UUID: 75246ace-e253-0410-96dd-a7613ca8dc81
Revision: 4
Node Kind: directory
Schedule: normal
Last Changed Author: jon
Last Changed Rev: 3
Last Changed Date: 2008-08-07 11:34:25 -0700 (Thu, 07 Aug 2008)

View File

@ -1,6 +0,0 @@
--format
s
--colour
--loadby
mtime
--backtrace

View File

@ -1,13 +0,0 @@
require 'puppetlabs_spec_helper/module_spec_helper'
require 'simplecov'
require 'support/filesystem_helpers'
require 'support/fixture_helpers'
SimpleCov.start do
add_filter "/spec/"
end
RSpec.configure do |c|
c.include FilesystemHelpers
c.include FixtureHelpers
end

View File

@ -1,18 +0,0 @@
module FilesystemHelpers
def expects_chdir(path = resource.value(:path))
Dir.expects(:chdir).with(path).at_least_once.yields
end
def expects_mkdir(path = resource.value(:path))
Dir.expects(:mkdir).with(path).at_least_once
end
def expects_rm_rf(path = resource.value(:path))
FileUtils.expects(:rm_rf).with(path)
end
def expects_directory?(returns = true, path = resource.value(:path))
File.expects(:directory?).with(path).returns(returns)
end
end

View File

@ -1,7 +0,0 @@
module FixtureHelpers
def fixture(name, ext = '.txt')
File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', name.to_s + ext))
end
end

View File

@ -1,109 +0,0 @@
require 'spec_helper'
describe Puppet::Type.type(:vcsrepo).provider(:bzr_provider) do
let(:resource) { Puppet::Type.type(:vcsrepo).new({
:name => 'test',
:ensure => :present,
:provider => :bzr,
:revision => '2634',
:source => 'lp:do',
:path => '/tmp/test',
})}
let(:provider) { resource.provider }
before :each do
Puppet::Util.stubs(:which).with('bzr').returns('/usr/bin/bzr')
end
describe 'creating' do
context 'with defaults' do
it "should execute 'bzr clone -r' with the revision" do
provider.expects(:bzr).with('branch', '-r', resource.value(:revision), resource.value(:source), resource.value(:path))
provider.create
end
end
context 'without revision' do
it "should just execute 'bzr clone' without a revision" do
resource.delete(:revision)
provider.expects(:bzr).with('branch', resource.value(:source), resource.value(:path))
provider.create
end
end
context 'without source' do
it "should execute 'bzr init'" do
resource.delete(:source)
provider.expects(:bzr).with('init', resource.value(:path))
provider.create
end
end
end
describe 'destroying' do
it "it should remove the directory" do
provider.destroy
end
end
describe "checking existence" do
it "should check for the directory" do
File.expects(:directory?).with(File.join(resource.value(:path), '.bzr')).returns(true)
provider.exists?
end
end
describe "checking the revision property" do
before do
expects_chdir
provider.expects(:bzr).with('version-info').returns(File.read(fixtures('bzr_version_info.txt')))
@current_revid = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x'
end
context "when given a non-revid as the resource revision" do
context "when its revid is not different than the current revid" do
it "should return the ref" do
resource[:revision] = '2634'
provider.expects(:bzr).with('revision-info', '2634').returns("2634 menesis@pov.lt-20100309191856-4wmfqzc803fj300x\n")
provider.revision.should == resource.value(:revision)
end
end
context "when its revid is different than the current revid" do
it "should return the current revid" do
resource[:revision] = '2636'
provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2635 foo\n")
provider.revision.should == @current_revid
end
end
end
context "when given a revid as the resource revision" do
context "when it is the same as the current revid" do
it "should return it" do
resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300x'
provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("1234 #{resource.value(:revision)}\n")
provider.revision.should == resource.value(:revision)
end
end
context "when it is not the same as the current revid" do
it "should return the current revid" do
resource[:revision] = 'menesis@pov.lt-20100309191856-4wmfqzc803fj300y'
provider.expects(:bzr).with('revision-info', resource.value(:revision)).returns("2636 foo\n")
provider.revision.should == @current_revid
end
end
end
end
describe "setting the revision property" do
it "should use 'bzr update -r' with the revision" do
Dir.expects(:chdir).with('/tmp/test').at_least_once.yields
provider.expects(:bzr).with('update', '-r', 'somerev')
provider.revision = 'somerev'
end
end
end

View File

@ -1,115 +0,0 @@
require 'spec_helper'
describe Puppet::Type.type(:vcsrepo).provider(:cvs_provider) do
let(:resource) { Puppet::Type.type(:vcsrepo).new({
:name => 'test',
:ensure => :present,
:provider => :cvs,
:revision => '2634',
:source => 'lp:do',
:path => '/tmp/test',
})}
let(:provider) { resource.provider }
before :each do
Puppet::Util.stubs(:which).with('cvs').returns('/usr/bin/cvs')
end
describe 'creating' do
context "with a source" do
it "should execute 'cvs checkout'" do
resource[:source] = ':ext:source@example.com:/foo/bar'
resource[:revision] = 'an-unimportant-value'
expects_chdir('/tmp')
provider.expects(:cvs).with('-d', resource.value(:source), 'checkout', '-r', 'an-unimportant-value', '-d', 'test', 'bar')
provider.create
end
it "should just execute 'cvs checkout' without a revision" do
resource[:source] = ':ext:source@example.com:/foo/bar'
resource.delete(:revision)
provider.expects(:cvs).with('-d', resource.value(:source), 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source)))
provider.create
end
context "with a compression" do
it "should just execute 'cvs checkout' without a revision" do
resource[:source] = ':ext:source@example.com:/foo/bar'
resource[:compression] = '3'
resource.delete(:revision)
provider.expects(:cvs).with('-d', resource.value(:source), '-z', '3', 'checkout', '-d', File.basename(resource.value(:path)), File.basename(resource.value(:source)))
provider.create
end
end
end
context "when a source is not given" do
it "should execute 'cvs init'" do
resource.delete(:source)
provider.expects(:cvs).with('-d', resource.value(:path), 'init')
provider.create
end
end
end
describe 'destroying' do
it "it should remove the directory" do
provider.destroy
end
end
describe "checking existence" do
it "should check for the CVS directory with source" do
resource[:source] = ':ext:source@example.com:/foo/bar'
File.expects(:directory?).with(File.join(resource.value(:path), 'CVS'))
provider.exists?
end
it "should check for the CVSROOT directory without source" do
resource.delete(:source)
File.expects(:directory?).with(File.join(resource.value(:path), 'CVSROOT'))
provider.exists?
end
end
describe "checking the revision property" do
before do
@tag_file = File.join(resource.value(:path), 'CVS', 'Tag')
end
context "when CVS/Tag exists" do
before do
@tag = 'TAG'
File.expects(:exist?).with(@tag_file).returns(true)
end
it "should read CVS/Tag" do
File.expects(:read).with(@tag_file).returns("T#{@tag}")
provider.revision.should == @tag
end
end
context "when CVS/Tag does not exist" do
before do
File.expects(:exist?).with(@tag_file).returns(false)
end
it "assumes HEAD" do
provider.revision.should == 'HEAD'
end
end
end
describe "when setting the revision property" do
before do
@tag = 'SOMETAG'
end
it "should use 'cvs update -dr'" do
expects_chdir
provider.expects(:cvs).with('update', '-dr', @tag, '.')
provider.revision = @tag
end
end
end

View File

@ -1,369 +0,0 @@
require 'spec_helper'
describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do
let(:resource) { Puppet::Type.type(:vcsrepo).new({
:name => 'test',
:ensure => :present,
:provider => :git,
:revision => '2634',
:source => 'git@repo',
:path => '/tmp/test',
})}
let(:provider) { resource.provider }
before :each do
Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git')
end
context 'creating' do
context "with a revision that is a remote branch" do
it "should execute 'git clone' and 'git checkout -b'" do
resource[:revision] = 'only/remote'
Dir.expects(:chdir).with('/').at_least_once.yields
Dir.expects(:chdir).with('/tmp/test').at_least_once.yields
provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
provider.expects(:update_submodules)
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('checkout', '--force', resource.value(:revision))
provider.create
end
end
context "with a revision that is not a remote branch" do
it "should execute 'git clone' and 'git reset --hard'" do
resource[:revision] = 'a-commit-or-tag'
Dir.expects(:chdir).with('/').at_least_once.yields
Dir.expects(:chdir).with('/tmp/test').at_least_once.yields
provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
provider.expects(:update_submodules)
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('checkout', '--force', resource.value(:revision))
provider.create
end
it "should execute 'git clone' and submodule commands" do
resource.delete(:revision)
provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
provider.expects(:update_submodules)
provider.create
end
end
context "with an ensure of bare" do
context "with revision" do
it "should just execute 'git clone --bare'" do
resource[:ensure] = :bare
provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path))
provider.create
end
end
context "without revision" do
it "should just execute 'git clone --bare'" do
resource[:ensure] = :bare
resource.delete(:revision)
provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path))
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
resource[:ensure] = :present
resource.delete(:source)
expects_mkdir
expects_chdir
expects_directory?(false)
provider.expects(:bare_exists?).returns(false)
provider.expects(:git).with('init')
provider.create
end
end
context "when the path is a bare repository" do
it "should convert it to a working copy" do
resource[:ensure] = :present
resource.delete(:source)
provider.expects(:bare_exists?).returns(true)
provider.expects(:convert_bare_to_working_copy)
provider.create
end
end
context "when the path is not empty and not a repository" do
it "should raise an exception" do
provider.expects(:path_exists?).returns(true)
provider.expects(:path_empty?).returns(false)
proc { provider.create }.should raise_error(Puppet::Error)
end
end
end
context "when the path does not exist" do
it "should execute 'git init --bare'" do
resource[:ensure] = :bare
resource.delete(:source)
expects_chdir
expects_mkdir
expects_directory?(false)
provider.expects(:working_copy_exists?).returns(false)
provider.expects(:git).with('init', '--bare')
provider.create
end
end
context "when the path is a working copy repository" do
it "should convert it to a bare repository" do
resource[:ensure] = :bare
resource.delete(:source)
provider.expects(:working_copy_exists?).returns(true)
provider.expects(:convert_working_copy_to_bare)
provider.create
end
end
context "when the path is not empty and not a repository" do
it "should raise an exception" do
expects_directory?(true)
provider.expects(:path_empty?).returns(false)
proc { provider.create }.should raise_error(Puppet::Error)
end
end
end
context 'destroying' do
it "it should remove the directory" do
#expects_rm_rf
provider.destroy
end
end
context "checking the revision property" do
before do
expects_chdir('/tmp/test')
resource[:revision] = 'currentsha'
resource.delete(:source)
provider.expects(:git).with('rev-parse', 'HEAD').returns('currentsha')
end
context "when its SHA is not different than the current SHA" do
it "should return the ref" do
provider.expects(:git).with('config', 'remote.origin.url').returns('')
provider.expects(:git).with('fetch', 'origin') # FIXME
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha')
provider.expects(:git).with('tag', '-l').returns("Hello")
provider.revision.should == resource.value(:revision)
end
end
context "when its SHA is different than the current SHA" do
it "should return the current SHA" do
provider.expects(:git).with('config', 'remote.origin.url').returns('')
provider.expects(:git).with('fetch', 'origin') # FIXME
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('othersha')
provider.expects(:git).with('tag', '-l').returns("Hello")
provider.revision.should == 'currentsha'
end
end
context "when its a ref to a remote head" do
it "should return the revision" do
provider.expects(:git).with('config', 'remote.origin.url').returns('')
provider.expects(:git).with('fetch', 'origin') # FIXME
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.expects(:git).with('tag', '-l').returns("Hello")
provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('')
provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns("newsha refs/heads/#{resource.value(:revision)}")
provider.revision.should == 'currentsha'
end
end
context "when its a ref to non existant remote head" do
it "should fail" do
provider.expects(:git).with('config', 'remote.origin.url').returns('')
provider.expects(:git).with('fetch', 'origin') # FIXME
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.expects(:git).with('tag', '-l').returns("Hello")
provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('')
provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns('')
expect { provider.revision }.to raise_error(Puppet::Error, /not a local or remote ref$/)
end
end
context "when the source is modified" do
it "should update the origin url" do
resource[:source] = 'git://git@foo.com/bar.git'
provider.expects(:git).with('config', 'remote.origin.url').returns('old')
provider.expects(:git).with('config', 'remote.origin.url', 'git://git@foo.com/bar.git')
provider.expects(:git).with('fetch', 'origin') # FIXME
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha')
provider.expects(:git).with('tag', '-l').returns("Hello")
provider.revision.should == resource.value(:revision)
end
end
end
context "setting the revision property" do
before do
expects_chdir
end
context "when it's an existing local branch" do
it "should use 'git fetch' and 'git reset'" do
resource[:revision] = 'feature/foo'
provider.expects(:update_submodules)
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('checkout', '--force', resource.value(:revision))
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}")
provider.revision = resource.value(:revision)
end
end
context "when it's a remote branch" do
it "should use 'git fetch' and 'git reset'" do
resource[:revision] = 'only/remote'
provider.expects(:update_submodules)
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('checkout', '--force', resource.value(:revision))
provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}")
provider.revision = resource.value(:revision)
end
end
context "when it's a commit or tag" do
it "should use 'git fetch' and 'git reset'" do
resource[:revision] = 'a-commit-or-tag'
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
provider.expects(:git).with('checkout', '--force', resource.value(:revision))
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
provider.expects(:git).with('submodule', 'update', '--init', '--recursive')
provider.revision = resource.value(:revision)
end
end
end
context "updating references" do
it "should use 'git fetch --tags'" do
resource.delete(:source)
expects_chdir
provider.expects(:git).with('config', 'remote.origin.url').returns('')
provider.expects(:git).with('fetch', 'origin')
provider.expects(:git).with('fetch', '--tags', 'origin')
provider.update_references
end
end
context "checking if revision" do
before do
expects_chdir
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
end
context "is a local branch" do
context "when it's listed in 'git branch -a'" do
it "should return true" do
resource[:revision] = 'feature/foo'
provider.should be_local_branch_revision
end
end
context "when it's not listed in 'git branch -a'" do
it "should return false" do
resource[:revision] = 'feature/notexist'
provider.should_not be_local_branch_revision
end
end
end
context "is a remote branch" do
context "when it's listed in 'git branch -a' with an 'origin/' prefix" do
it "should return true" do
resource[:revision] = 'only/remote'
provider.should be_remote_branch_revision
end
end
context "when it's not listed in 'git branch -a' with an 'origin/' prefix" do
it "should return false" do
resource[:revision] = 'only/local'
provider.should_not be_remote_branch_revision
end
end
end
end
describe 'latest?' do
before do
expects_chdir('/tmp/test')
end
context 'when true' do
it do
provider.expects(:revision).returns('testrev')
provider.expects(:latest).returns('testrev')
provider.latest?.should be_true
end
end
context 'when false' do
it do
provider.expects(:revision).returns('master')
provider.expects(:latest).returns('testrev')
provider.latest?.should be_false
end
end
end
describe 'latest' do
before do
provider.expects(:get_revision).returns('master')
expects_chdir
end
context 'on master' do
it do
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
provider.latest.should == 'master'
end
end
context 'no branch' do
it do
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_none))
provider.latest.should == 'master'
end
end
context 'feature/bar' do
it do
provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_feature_bar))
provider.latest.should == 'master'
end
end
end
describe 'convert_working_copy_to_bare' do
it do
FileUtils.expects(:mv).returns(true)
FileUtils.expects(:rm_rf).returns(true)
FileUtils.expects(:mv).returns(true)
provider.instance_eval { convert_working_copy_to_bare }
end
end
describe 'convert_bare_to_working_copy' do
it do
FileUtils.expects(:mv).returns(true)
FileUtils.expects(:mkdir).returns(true)
FileUtils.expects(:mv).returns(true)
provider.expects(:commits_in?).returns(true)
# If you forget to stub these out you lose 3 hours of rspec work.
provider.expects(:reset).with('HEAD').returns(true)
provider.expects(:git_with_identity).returns(true)
provider.expects(:update_owner_and_excludes).returns(true)
provider.instance_eval { convert_bare_to_working_copy }
end
end
end

View File

@ -1,122 +0,0 @@
require 'spec_helper'
describe Puppet::Type.type(:vcsrepo).provider(:hg) do
let(:resource) { Puppet::Type.type(:vcsrepo).new({
:name => 'test',
:ensure => :present,
:provider => :hg,
:path => '/tmp/vcsrepo',
})}
let(:provider) { resource.provider }
before :each do
Puppet::Util.stubs(:which).with('hg').returns('/usr/bin/hg')
end
describe 'creating' do
context 'with source and revision' do
it "should execute 'hg clone -u' with the revision" do
resource[:source] = 'something'
resource[:revision] = '1'
provider.expects(:hg).with('clone', '-u',
resource.value(:revision),
resource.value(:source),
resource.value(:path))
provider.create
end
end
context 'without revision' do
it "should just execute 'hg clone' without a revision" do
resource[:source] = 'something'
provider.expects(:hg).with('clone', resource.value(:source), resource.value(:path))
provider.create
end
end
context "when a source is not given" do
it "should execute 'hg init'" do
provider.expects(:hg).with('init', resource.value(:path))
provider.create
end
end
end
describe 'destroying' do
it "it should remove the directory" do
expects_rm_rf
provider.destroy
end
end
describe "checking existence" do
it "should check for the directory" do
expects_directory?(true, File.join(resource.value(:path), '.hg'))
provider.exists?
end
end
describe "checking the revision property" do
before do
expects_chdir
end
context "when given a non-SHA as the resource revision" do
before do
provider.expects(:hg).with('parents').returns(fixture(:hg_parents))
provider.expects(:hg).with('tags').returns(fixture(:hg_tags))
end
context "when its SHA is not different than the current SHA" do
it "should return the ref" do
resource[:revision] = '0.6'
provider.revision.should == '0.6'
end
end
context "when its SHA is different than the current SHA" do
it "should return the current SHA" do
resource[:revision] = '0.5.3'
provider.revision.should == '34e6012c783a'
end
end
end
context "when given a SHA as the resource revision" do
before do
provider.expects(:hg).with('parents').returns(fixture(:hg_parents))
end
context "when it is the same as the current SHA", :resource => {:revision => '34e6012c783a'} do
it "should return it" do
resource[:revision] = '34e6012c783a'
provider.expects(:hg).with('tags').returns(fixture(:hg_tags))
provider.revision.should == resource.value(:revision)
end
end
context "when it is not the same as the current SHA", :resource => {:revision => 'not-the-same'} do
it "should return the current SHA" do
resource[:revision] = 'not-the-same'
provider.expects(:hg).with('tags').returns(fixture(:hg_tags))
provider.revision.should == '34e6012c783a'
end
end
end
end
describe "setting the revision property" do
before do
@revision = '6aa99e9b3ab1'
end
it "should use 'hg update ---clean -r'" do
expects_chdir
provider.expects(:hg).with('pull')
provider.expects(:hg).with('merge')
provider.expects(:hg).with('update', '--clean', '-r', @revision)
provider.revision = @revision
end
end
end

View File

@ -1,105 +0,0 @@
require 'spec_helper'
describe Puppet::Type.type(:vcsrepo).provider(:svn) do
let(:resource) { Puppet::Type.type(:vcsrepo).new({
:name => 'test',
:ensure => :present,
:provider => :svn,
:path => '/tmp/vcsrepo',
})}
let(:provider) { resource.provider }
before :each do
Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git')
end
describe 'creating' do
context 'with source and revision' do
it "should execute 'svn checkout' with a revision" do
resource[:source] = 'exists'
resource[:revision] = '1'
provider.expects(:svn).with('--non-interactive', 'checkout', '-r',
resource.value(:revision),
resource.value(:source),
resource.value(:path))
provider.create
end
end
context 'with source' do
it "should just execute 'svn checkout' without a revision" do
resource[:source] = 'exists'
provider.expects(:svn).with('--non-interactive', 'checkout',
resource.value(:source),
resource.value(:path))
provider.create
end
end
context 'with fstype' do
it "should execute 'svnadmin create' with an '--fs-type' option" do
resource[:fstype] = 'ext4'
provider.expects(:svnadmin).with('create', '--fs-type',
resource.value(:fstype),
resource.value(:path))
provider.create
end
end
context 'without fstype' do
it "should execute 'svnadmin create' without an '--fs-type' option" do
provider.expects(:svnadmin).with('create', resource.value(:path))
provider.create
end
end
end
describe 'destroying' do
it "it should remove the directory" do
expects_rm_rf
provider.destroy
end
end
describe "checking existence" do
it "should check for the directory" do
expects_directory?(true, resource.value(:path))
expects_directory?(true, File.join(resource.value(:path), '.svn'))
provider.exists?
end
end
describe "checking the revision property" do
before do
provider.expects(:svn).with('--non-interactive', 'info').returns(fixture(:svn_info))
end
it "should use 'svn info'" do
expects_chdir
provider.revision.should == '4' # From 'Revision', not 'Last Changed Rev'
end
end
describe "setting the revision property" 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
end
end
describe "setting the revision property and repo source" 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
end
end
end

View File

@ -1,4 +0,0 @@
Resource Type Specs
===================
Define specs for your resource types in this directory.