r10k 1.2.4 → 1.3.0rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/{CHANGELOG → CHANGELOG.mkd} +51 -41
- data/doc/dynamic-environments/configuration.mkd +1 -1
- data/doc/dynamic-environments/git-environments.markdown +19 -0
- data/doc/dynamic-environments/usage.mkd +6 -0
- data/lib/r10k/cli/deploy.rb +15 -0
- data/lib/r10k/cli/ext/logging.rb +0 -1
- data/lib/r10k/cli/module/deploy.rb +0 -1
- data/lib/r10k/cli/puppetfile.rb +2 -2
- data/lib/r10k/cli.rb +2 -16
- data/lib/r10k/deployment/environment.rb +9 -79
- data/lib/r10k/deployment/source.rb +15 -89
- data/lib/r10k/deployment.rb +13 -14
- data/lib/r10k/environment/base.rb +42 -0
- data/lib/r10k/environment/git.rb +79 -0
- data/lib/r10k/environment/svn.rb +73 -0
- data/lib/r10k/environment.rb +7 -0
- data/lib/r10k/execution.rb +0 -1
- data/lib/r10k/git/cache.rb +11 -5
- data/lib/r10k/git/repository.rb +1 -8
- data/lib/r10k/git/working_dir.rb +11 -34
- data/lib/r10k/git.rb +0 -1
- data/lib/r10k/instance_cache.rb +32 -0
- data/lib/r10k/keyed_factory.rb +39 -0
- data/lib/r10k/module/forge.rb +2 -3
- data/lib/r10k/module/svn.rb +0 -1
- data/lib/r10k/puppetfile.rb +0 -1
- data/lib/r10k/registry.rb +3 -31
- data/lib/r10k/source/base.rb +60 -0
- data/lib/r10k/source/git.rb +195 -0
- data/lib/r10k/source/svn.rb +140 -0
- data/lib/r10k/source.rb +39 -0
- data/lib/r10k/svn/remote.rb +48 -0
- data/lib/r10k/svn/working_dir.rb +0 -2
- data/lib/r10k/svn.rb +6 -0
- data/lib/r10k/task/deployment.rb +1 -2
- data/lib/r10k/task.rb +0 -2
- data/lib/r10k/task_runner.rb +0 -1
- data/lib/r10k/util/core_ext/hash_ext.rb +19 -0
- data/lib/r10k/util/subprocess.rb +0 -1
- data/lib/r10k/version.rb +1 -1
- data/lib/r10k.rb +1 -0
- data/spec/unit/deployment/environment_spec.rb +16 -15
- data/spec/unit/environment/git_spec.rb +81 -0
- data/spec/unit/environment/svn_spec.rb +76 -0
- data/spec/unit/git/repository_spec.rb +0 -10
- data/spec/unit/git/working_dir_spec.rb +1 -110
- data/spec/unit/{registry_spec.rb → instance_cache_spec.rb} +3 -3
- data/spec/unit/keyed_factory_spec.rb +51 -0
- data/spec/unit/source/git_spec.rb +274 -0
- data/spec/unit/source/svn_spec.rb +102 -0
- data/spec/unit/source_spec.rb +10 -0
- data/spec/unit/svn/remote_spec.rb +21 -0
- data/spec/unit/util/core_ext/hash_ext_spec.rb +63 -0
- metadata +36 -10
- data/lib/r10k/git/alternates.rb +0 -49
- data/spec/unit/git/alternates_spec.rb +0 -90
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'r10k/git'
|
2
|
+
require 'r10k/environment'
|
3
|
+
require 'r10k/util/purgeable'
|
4
|
+
require 'r10k/util/core_ext/hash_ext'
|
5
|
+
|
6
|
+
# This class implements a source for Git environments.
|
7
|
+
#
|
8
|
+
# A Git source generates environments by locally caching the given Git
|
9
|
+
# repository and enumerating the branches for the Git repository. Branches
|
10
|
+
# are mapped to environments without modification.
|
11
|
+
#
|
12
|
+
# @since 1.3.0
|
13
|
+
class R10K::Source::Git < R10K::Source::Base
|
14
|
+
|
15
|
+
include R10K::Logging
|
16
|
+
|
17
|
+
R10K::Source.register(:git, self)
|
18
|
+
# Register git as the default source
|
19
|
+
R10K::Source.register(nil, self)
|
20
|
+
|
21
|
+
# @!attribute [r] remote
|
22
|
+
# @return [String] The URL to the remote git repository
|
23
|
+
attr_reader :remote
|
24
|
+
|
25
|
+
# @!attribute [r] cache
|
26
|
+
# @api private
|
27
|
+
# @return [R10K::Git::Cache] The git cache associated with this source
|
28
|
+
attr_reader :cache
|
29
|
+
|
30
|
+
# @!attribute [r] settings
|
31
|
+
# @return [Hash<Symbol, Object>] Additional settings that configure how
|
32
|
+
# the source should behave.
|
33
|
+
attr_reader :settings
|
34
|
+
|
35
|
+
# @!attribute [r] invalid_branches
|
36
|
+
# @return [String] How Git branch names that cannot be cleanly mapped to
|
37
|
+
# Puppet environments will be handled.
|
38
|
+
attr_reader :invalid_branches
|
39
|
+
|
40
|
+
# Initialize the given source.
|
41
|
+
#
|
42
|
+
# @param name [String] The identifier for this source.
|
43
|
+
# @param basedir [String] The base directory where the generated environments will be created.
|
44
|
+
# @param options [Hash] An additional set of options for this source.
|
45
|
+
#
|
46
|
+
# @option options [Boolean] :prefix Whether to prefix the source name to the
|
47
|
+
# environment directory names. Defaults to false.
|
48
|
+
# @option options [String] :remote The URL to the base directory of the SVN repository
|
49
|
+
# @option options [Hash] :remote Additional settings that configure how the
|
50
|
+
# source should behave.
|
51
|
+
def initialize(name, basedir, options = {})
|
52
|
+
super
|
53
|
+
|
54
|
+
@environments = []
|
55
|
+
|
56
|
+
@remote = options[:remote]
|
57
|
+
@invalid_branches = (options[:invalid_branches] || 'correct_and_warn')
|
58
|
+
|
59
|
+
@cache = R10K::Git::Cache.generate(@remote)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Update the git cache for this git source to get the latest list of environments.
|
63
|
+
#
|
64
|
+
# @return [void]
|
65
|
+
def preload!
|
66
|
+
logger.info "Determining current branches for #{@remote.inspect}"
|
67
|
+
@cache.sync
|
68
|
+
end
|
69
|
+
alias fetch_remote preload!
|
70
|
+
|
71
|
+
# Load the git remote and create environments for each branch. If the cache
|
72
|
+
# has not been fetched, this will return an empty list.
|
73
|
+
#
|
74
|
+
# @return [Array<R10K::Environment::Git>]
|
75
|
+
def environments
|
76
|
+
if not @cache.cached?
|
77
|
+
[]
|
78
|
+
elsif not @environments.empty?
|
79
|
+
@environments
|
80
|
+
else
|
81
|
+
@environments = generate_environments()
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def generate_environments
|
86
|
+
envs = []
|
87
|
+
branch_names.each do |bn|
|
88
|
+
if bn.valid?
|
89
|
+
envs << R10K::Environment::Git.new(bn.name, @basedir, bn.dirname,
|
90
|
+
{:remote => remote, :ref => bn.name})
|
91
|
+
elsif bn.correct?
|
92
|
+
logger.warn "Environment #{bn.name.inspect} contained non-word characters, correcting name to #{bn.dirname}"
|
93
|
+
envs << R10K::Environment::Git.new(bn.name, @basedir, bn.dirname,
|
94
|
+
{:remote => remote, :ref => bn.name})
|
95
|
+
elsif bn.validate?
|
96
|
+
logger.error "Environment #{bn.name.inspect} contained non-word characters, ignoring it."
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
envs
|
101
|
+
end
|
102
|
+
|
103
|
+
include R10K::Util::Purgeable
|
104
|
+
|
105
|
+
def managed_directory
|
106
|
+
@basedir
|
107
|
+
end
|
108
|
+
|
109
|
+
def current_contents
|
110
|
+
dir = self.managed_directory
|
111
|
+
glob_part = @prefix ? @name.to_s() + '_*' : '*'
|
112
|
+
glob_exp = File.join(dir, glob_part)
|
113
|
+
|
114
|
+
Dir.glob(glob_exp).map do |fname|
|
115
|
+
File.basename fname
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# List all environments that should exist in the basedir for this source
|
120
|
+
# @note This implements a required method for the Purgeable mixin
|
121
|
+
# @return [Array<String>]
|
122
|
+
def desired_contents
|
123
|
+
@environments.map {|env| env.dirname }
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def branch_names
|
129
|
+
@cache.branches.map do |branch|
|
130
|
+
BranchName.new(branch, {
|
131
|
+
:prefix => @prefix,
|
132
|
+
:sourcename => @name,
|
133
|
+
:invalid => @invalid_branches,
|
134
|
+
})
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# @api private
|
139
|
+
class BranchName
|
140
|
+
|
141
|
+
attr_reader :name
|
142
|
+
|
143
|
+
INVALID_CHARACTERS = %r[\W]
|
144
|
+
|
145
|
+
def initialize(name, opts)
|
146
|
+
@name = name
|
147
|
+
@opts = opts
|
148
|
+
|
149
|
+
@prefix = opts[:prefix]
|
150
|
+
@sourcename = opts[:sourcename]
|
151
|
+
@invalid = opts[:invalid]
|
152
|
+
|
153
|
+
case @invalid
|
154
|
+
when 'correct_and_warn'
|
155
|
+
@validate = true
|
156
|
+
@correct = true
|
157
|
+
when 'correct'
|
158
|
+
@validate = false
|
159
|
+
@correct = true
|
160
|
+
when 'error'
|
161
|
+
@validate = true
|
162
|
+
@correct = false
|
163
|
+
when NilClass
|
164
|
+
@validate = opts[:validate]
|
165
|
+
@correct = opts[:correct]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def correct?; @correct end
|
170
|
+
def validate?; @validate end
|
171
|
+
|
172
|
+
def valid?
|
173
|
+
if @validate
|
174
|
+
! @name.match(INVALID_CHARACTERS)
|
175
|
+
else
|
176
|
+
true
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def dirname
|
181
|
+
dir = @name.dup
|
182
|
+
|
183
|
+
if @prefix
|
184
|
+
dir = "#{@sourcename}_#{dir}"
|
185
|
+
end
|
186
|
+
|
187
|
+
if @correct
|
188
|
+
dir.gsub!(INVALID_CHARACTERS, '_')
|
189
|
+
end
|
190
|
+
|
191
|
+
dir
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'r10k/svn'
|
2
|
+
require 'r10k/environment'
|
3
|
+
require 'r10k/util/purgeable'
|
4
|
+
require 'r10k/util/core_ext/hash_ext'
|
5
|
+
|
6
|
+
# This class implements a source for SVN environments.
|
7
|
+
#
|
8
|
+
# An SVN source generates environments by enumerating the branches and trunk
|
9
|
+
# for a given SVN remote. SVN repositories must conform to the conventional
|
10
|
+
# SVN repository structure with the directories trunk/, branches/, and
|
11
|
+
# optionally tags/ in the root of the repository. The trunk/ directory is
|
12
|
+
# specifically mapped to the production environment, branches are created
|
13
|
+
# as environments with the name of the given branch.
|
14
|
+
#
|
15
|
+
# @see http://svnbook.red-bean.com/en/1.7/svn.branchmerge.maint.html
|
16
|
+
# @since 1.3.0
|
17
|
+
class R10K::Source::SVN < R10K::Source::Base
|
18
|
+
|
19
|
+
R10K::Source.register(:svn, self)
|
20
|
+
|
21
|
+
# @!attribute [r] remote
|
22
|
+
# @return [String] The URL to the base directory of the SVN repository
|
23
|
+
attr_reader :remote
|
24
|
+
|
25
|
+
# @!attribute [r] svn_remote
|
26
|
+
# @api private
|
27
|
+
# @return [R10K::SVN::Remote]
|
28
|
+
attr_reader :svn_remote
|
29
|
+
|
30
|
+
# Initialize the given source.
|
31
|
+
#
|
32
|
+
# @param name [String] The identifier for this source.
|
33
|
+
# @param basedir [String] The base directory where the generated environments will be created.
|
34
|
+
# @param options [Hash] An additional set of options for this source.
|
35
|
+
#
|
36
|
+
# @option options [Boolean] :prefix Whether to prefix the source name to the
|
37
|
+
# environment directory names. Defaults to false.
|
38
|
+
# @option options [String] :remote The URL to the base directory of the SVN repository
|
39
|
+
def initialize(name, basedir, options = {})
|
40
|
+
super
|
41
|
+
|
42
|
+
@remote = options[:remote]
|
43
|
+
@environments = []
|
44
|
+
|
45
|
+
@svn_remote = R10K::SVN::Remote.new(@remote)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Enumerate the environments associated with this SVN source.
|
49
|
+
#
|
50
|
+
# @return [Array<R10K::Environment::SVN>] An array of environments created
|
51
|
+
# from this source.
|
52
|
+
def environments
|
53
|
+
if @environments.empty?
|
54
|
+
@environments = generate_environments()
|
55
|
+
end
|
56
|
+
|
57
|
+
@environments
|
58
|
+
end
|
59
|
+
|
60
|
+
# Generate a list of currently available SVN environments
|
61
|
+
#
|
62
|
+
# @todo respect environment name corrections
|
63
|
+
#
|
64
|
+
# @api protected
|
65
|
+
# @return [Array<R10K::Environment::SVN>] An array of environments created
|
66
|
+
# from this source.
|
67
|
+
def generate_environments
|
68
|
+
|
69
|
+
branch_names.map do |branch|
|
70
|
+
R10K::Environment::SVN.new(branch.name, @basedir, branch.dirname,
|
71
|
+
{ :remote => branch.remote })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
include R10K::Util::Purgeable
|
76
|
+
|
77
|
+
def managed_directory
|
78
|
+
@basedir
|
79
|
+
end
|
80
|
+
|
81
|
+
def current_contents
|
82
|
+
Dir.glob(File.join(@basedir, '*')).map do |fname|
|
83
|
+
File.basename fname
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# List all environments that should exist in the basedir for this source
|
88
|
+
# @note This implements a required method for the Purgeable mixin
|
89
|
+
# @return [Array<String>]
|
90
|
+
def desired_contents
|
91
|
+
@environments.map {|env| env.dirname }
|
92
|
+
end
|
93
|
+
|
94
|
+
include R10K::Logging
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def branch_names
|
99
|
+
branches = []
|
100
|
+
|
101
|
+
branch_opts = {
|
102
|
+
:prefix => @prefix,
|
103
|
+
:sourcename => @name,
|
104
|
+
}
|
105
|
+
|
106
|
+
branches << BranchName.new('production', "#{@remote}/trunk", branch_opts)
|
107
|
+
@svn_remote.branches.each do |branch|
|
108
|
+
branches << BranchName.new(branch, "#{@remote}/branches/#{branch}", branch_opts)
|
109
|
+
end
|
110
|
+
|
111
|
+
branches
|
112
|
+
end
|
113
|
+
|
114
|
+
# @api private
|
115
|
+
# @todo respect environment name corrections
|
116
|
+
class BranchName
|
117
|
+
|
118
|
+
attr_reader :name
|
119
|
+
attr_reader :remote
|
120
|
+
|
121
|
+
def initialize(name, remote, opts)
|
122
|
+
@name = name
|
123
|
+
@remote = remote
|
124
|
+
@opts = opts
|
125
|
+
|
126
|
+
@prefix = opts[:prefix]
|
127
|
+
@sourcename = opts[:sourcename]
|
128
|
+
end
|
129
|
+
|
130
|
+
def dirname
|
131
|
+
dir = @name.dup
|
132
|
+
|
133
|
+
if @prefix
|
134
|
+
dir = "#{@sourcename}_#{dir}"
|
135
|
+
end
|
136
|
+
|
137
|
+
dir
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/lib/r10k/source.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'r10k'
|
2
|
+
require 'r10k/keyed_factory'
|
3
|
+
require 'r10k/util/core_ext/hash_ext'
|
4
|
+
|
5
|
+
module R10K
|
6
|
+
module Source
|
7
|
+
def self.factory
|
8
|
+
@factory ||= R10K::KeyedFactory.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register(key, klass)
|
12
|
+
factory.register(key, klass)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.retrieve(key)
|
16
|
+
factory.retrieve(key)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.generate(type, basedir, name, options = {})
|
20
|
+
factory.generate(type, basedir, name, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_hash(name, hash)
|
24
|
+
hash.extend R10K::Util::CoreExt::HashExt::SymbolizeKeys
|
25
|
+
hash.symbolize_keys!
|
26
|
+
|
27
|
+
basedir = hash.delete(:basedir)
|
28
|
+
|
29
|
+
type = hash.delete(:type)
|
30
|
+
type = type.is_a?(String) ? type.to_sym : type
|
31
|
+
|
32
|
+
generate(type, name, basedir, hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'r10k/source/base'
|
36
|
+
require 'r10k/source/git'
|
37
|
+
require 'r10k/source/svn'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'r10k/util/subprocess'
|
2
|
+
|
3
|
+
class R10K::SVN::Remote
|
4
|
+
|
5
|
+
def initialize(baseurl)
|
6
|
+
@baseurl = baseurl
|
7
|
+
end
|
8
|
+
|
9
|
+
# @todo validate that the path to trunk exists in the remote
|
10
|
+
def trunk
|
11
|
+
"#{@baseurl}/trunk"
|
12
|
+
end
|
13
|
+
|
14
|
+
# @todo gracefully handle cases where no branches exist
|
15
|
+
def branches
|
16
|
+
text = svn ['ls', "#{@baseurl}/branches"]
|
17
|
+
text.lines.map do |line|
|
18
|
+
line.chomp!
|
19
|
+
line.gsub!(%r[/$], '')
|
20
|
+
line
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
include R10K::Logging
|
27
|
+
|
28
|
+
# Wrap SVN commands
|
29
|
+
#
|
30
|
+
# @param argv [Array<String>]
|
31
|
+
# @param opts [Hash]
|
32
|
+
#
|
33
|
+
# @option opts [Pathname] :cwd The directory to run the command in
|
34
|
+
#
|
35
|
+
# @return [String] The stdout from the given command
|
36
|
+
def svn(argv, opts = {})
|
37
|
+
argv.unshift('svn')
|
38
|
+
|
39
|
+
subproc = R10K::Util::Subprocess.new(argv)
|
40
|
+
subproc.raise_on_fail = true
|
41
|
+
subproc.logger = self.logger
|
42
|
+
|
43
|
+
subproc.cwd = opts[:cwd]
|
44
|
+
result = subproc.execute
|
45
|
+
|
46
|
+
result.stdout
|
47
|
+
end
|
48
|
+
end
|
data/lib/r10k/svn/working_dir.rb
CHANGED
data/lib/r10k/svn.rb
ADDED
data/lib/r10k/task/deployment.rb
CHANGED
data/lib/r10k/task.rb
CHANGED
data/lib/r10k/task_runner.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module R10K
|
2
|
+
module Util
|
3
|
+
module CoreExt
|
4
|
+
module HashExt
|
5
|
+
module SymbolizeKeys
|
6
|
+
def symbolize_keys!
|
7
|
+
self.keys.each do |key|
|
8
|
+
next unless key.is_a? String
|
9
|
+
if self[key.to_sym]
|
10
|
+
raise TypeError, "An existing interned key for #{key} exists, cannot overwrite"
|
11
|
+
end
|
12
|
+
self[key.to_sym] = self.delete(key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/r10k/util/subprocess.rb
CHANGED
data/lib/r10k/version.rb
CHANGED
data/lib/r10k.rb
CHANGED
@@ -2,23 +2,24 @@ require 'spec_helper'
|
|
2
2
|
require 'r10k/deployment/environment'
|
3
3
|
|
4
4
|
describe R10K::Deployment::Environment do
|
5
|
-
let(:remote) { 'git://github.com/adrienthebo/r10k-fixture-repo' }
|
6
|
-
let(:ref) { 'master' }
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
it "creates R10K::Environment::Git instances" do
|
7
|
+
subject = described_class.new('gitref', 'git://git-server.local/git-remote.git', '/some/nonexistent/dir')
|
8
|
+
expect(subject).to be_a_kind_of R10K::Environment::Git
|
9
|
+
end
|
10
|
+
|
11
|
+
it "uses the ref as the dirname by default" do
|
12
|
+
subject = described_class.new('gitref', 'git://git-server.local/git-remote.git', '/some/nonexistent/dir')
|
13
|
+
expect(subject.dirname).to eq 'gitref'
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
it "can specify an explicit dirname" do
|
17
|
+
subject = described_class.new('gitref', 'git://git-server.local/git-remote.git', '/some/nonexistent/dir', 'explicit-dirname')
|
18
|
+
expect(subject.dirname).to eq 'explicit-dirname'
|
19
|
+
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
21
|
+
it "supports prefixing for backwards compatibility" do
|
22
|
+
subject = described_class.new('gitref', 'git://git-server.local/git-remote.git', '/some/nonexistent/dir', nil, 'source')
|
23
|
+
expect(subject.dirname).to eq 'source_gitref'
|
23
24
|
end
|
24
25
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/environment'
|
3
|
+
|
4
|
+
describe R10K::Environment::Git do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
described_class.new(
|
8
|
+
'myenv',
|
9
|
+
'/some/nonexistent/environmentdir',
|
10
|
+
'gitref',
|
11
|
+
{
|
12
|
+
:remote => 'git://git-server.site/my-repo.git',
|
13
|
+
:ref => 'd026ea677116424d2968edb9cee8cbc24d09322b',
|
14
|
+
}
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:working_dir) { subject.working_dir }
|
19
|
+
|
20
|
+
describe "storing attributes" do
|
21
|
+
it "can return the environment name" do
|
22
|
+
expect(subject.name).to eq 'myenv'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can return the environment basedir" do
|
26
|
+
expect(subject.basedir).to eq '/some/nonexistent/environmentdir'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can return the environment dirname" do
|
30
|
+
expect(subject.dirname).to eq 'gitref'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can return the environment remote" do
|
34
|
+
expect(subject.remote).to eq 'git://git-server.site/my-repo.git'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can return the environment ref" do
|
38
|
+
expect(subject.ref).to eq 'd026ea677116424d2968edb9cee8cbc24d09322b'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "synchronizing the environment" do
|
43
|
+
it "updates all modules when creating a new environment" do
|
44
|
+
allow(working_dir).to receive(:cloned?).and_return(false)
|
45
|
+
expect(working_dir).to receive(:sync)
|
46
|
+
expect(subject).to receive(:sync_modules)
|
47
|
+
subject.sync
|
48
|
+
end
|
49
|
+
|
50
|
+
it "does not update all modules when updating an existing environment" do
|
51
|
+
allow(working_dir).to receive(:cloned?).and_return(true)
|
52
|
+
expect(working_dir).to receive(:sync)
|
53
|
+
expect(subject).to_not receive(:sync_modules)
|
54
|
+
subject.sync
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "generating a puppetfile for the environment" do
|
59
|
+
let(:puppetfile) { subject.puppetfile }
|
60
|
+
|
61
|
+
it "creates a puppetfile at the full path to the environment" do
|
62
|
+
expect(puppetfile.basedir).to eq '/some/nonexistent/environmentdir/gitref'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sets the moduledir to 'modules' relative to the environment path" do
|
66
|
+
expect(puppetfile.moduledir).to eq '/some/nonexistent/environmentdir/gitref/modules'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "sets the puppetfile path to 'Puppetfile' relative to the environment path" do
|
70
|
+
expect(puppetfile.puppetfile_path).to eq '/some/nonexistent/environmentdir/gitref/Puppetfile'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "enumerating modules" do
|
75
|
+
it "loads the Puppetfile and returns modules in that puppetfile" do
|
76
|
+
expect(subject.puppetfile).to receive(:load)
|
77
|
+
expect(subject.puppetfile).to receive(:modules).and_return [:modules]
|
78
|
+
expect(subject.modules).to eq([:modules])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|