r10k 3.9.2 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec_tests.yml +1 -1
  3. data/.travis.yml +0 -10
  4. data/CHANGELOG.mkd +33 -0
  5. data/README.mkd +6 -0
  6. data/doc/dynamic-environments/configuration.mkd +25 -0
  7. data/doc/dynamic-environments/usage.mkd +26 -0
  8. data/doc/puppetfile.mkd +18 -5
  9. data/integration/Rakefile +3 -1
  10. data/integration/tests/basic_functionality/basic_deployment.rb +176 -0
  11. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +3 -9
  12. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +21 -25
  13. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
  14. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
  15. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
  16. data/lib/r10k/action/deploy/environment.rb +17 -2
  17. data/lib/r10k/action/deploy/module.rb +38 -7
  18. data/lib/r10k/action/puppetfile/check.rb +7 -5
  19. data/lib/r10k/action/puppetfile/install.rb +22 -16
  20. data/lib/r10k/action/puppetfile/purge.rb +12 -9
  21. data/lib/r10k/action/runner.rb +45 -10
  22. data/lib/r10k/cli/deploy.rb +5 -0
  23. data/lib/r10k/cli/puppetfile.rb +0 -1
  24. data/lib/r10k/content_synchronizer.rb +16 -4
  25. data/lib/r10k/environment/base.rb +64 -11
  26. data/lib/r10k/environment/with_modules.rb +6 -10
  27. data/lib/r10k/git/cache.rb +1 -1
  28. data/lib/r10k/git/rugged/credentials.rb +77 -0
  29. data/lib/r10k/git/stateful_repository.rb +8 -0
  30. data/lib/r10k/git.rb +3 -0
  31. data/lib/r10k/initializers.rb +4 -0
  32. data/lib/r10k/module/base.rb +42 -1
  33. data/lib/r10k/module/definition.rb +64 -0
  34. data/lib/r10k/module/forge.rb +17 -4
  35. data/lib/r10k/module/git.rb +24 -2
  36. data/lib/r10k/module/local.rb +2 -3
  37. data/lib/r10k/module/svn.rb +12 -1
  38. data/lib/r10k/module.rb +20 -2
  39. data/lib/r10k/module_loader/puppetfile/dsl.rb +42 -0
  40. data/lib/r10k/module_loader/puppetfile.rb +272 -0
  41. data/lib/r10k/puppetfile.rb +82 -160
  42. data/lib/r10k/settings/definition.rb +1 -1
  43. data/lib/r10k/settings.rb +58 -2
  44. data/lib/r10k/source/base.rb +10 -0
  45. data/lib/r10k/source/git.rb +5 -0
  46. data/lib/r10k/source/svn.rb +4 -0
  47. data/lib/r10k/util/purgeable.rb +70 -8
  48. data/lib/r10k/version.rb +1 -1
  49. data/locales/r10k.pot +165 -65
  50. data/r10k.gemspec +2 -0
  51. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +4 -0
  52. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +3 -0
  53. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +8 -0
  54. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +9 -0
  55. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +9 -0
  56. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_subdir_2/ignored_1 +0 -0
  57. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  58. data/spec/r10k-mocks/mock_env.rb +3 -0
  59. data/spec/r10k-mocks/mock_source.rb +7 -3
  60. data/spec/unit/action/deploy/environment_spec.rb +105 -30
  61. data/spec/unit/action/deploy/module_spec.rb +232 -42
  62. data/spec/unit/action/puppetfile/check_spec.rb +17 -5
  63. data/spec/unit/action/puppetfile/install_spec.rb +42 -36
  64. data/spec/unit/action/puppetfile/purge_spec.rb +15 -17
  65. data/spec/unit/action/runner_spec.rb +122 -26
  66. data/spec/unit/environment/base_spec.rb +30 -17
  67. data/spec/unit/environment/git_spec.rb +2 -2
  68. data/spec/unit/environment/svn_spec.rb +4 -3
  69. data/spec/unit/environment/with_modules_spec.rb +2 -1
  70. data/spec/unit/git/cache_spec.rb +14 -0
  71. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  72. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  73. data/spec/unit/module/base_spec.rb +54 -8
  74. data/spec/unit/module/forge_spec.rb +59 -5
  75. data/spec/unit/module/git_spec.rb +67 -17
  76. data/spec/unit/module/svn_spec.rb +35 -5
  77. data/spec/unit/module_loader/puppetfile_spec.rb +403 -0
  78. data/spec/unit/module_spec.rb +28 -0
  79. data/spec/unit/puppetfile_spec.rb +125 -189
  80. data/spec/unit/settings_spec.rb +47 -2
  81. data/spec/unit/util/purgeable_spec.rb +38 -6
  82. metadata +28 -2
@@ -3,7 +3,7 @@ require 'r10k/action/puppetfile/check'
3
3
 
4
4
  describe R10K::Action::Puppetfile::Check do
5
5
  let(:default_opts) { {root: "/some/nonexistent/path"} }
6
- let(:puppetfile) { instance_double('R10K::Puppetfile', :load! => true) }
6
+ let(:loader) { instance_double('R10K::ModuleLoader::Puppetfile', :load! => {}) }
7
7
 
8
8
  def checker(opts = {}, argv = [], settings = {})
9
9
  opts = default_opts.merge(opts)
@@ -11,7 +11,11 @@ describe R10K::Action::Puppetfile::Check do
11
11
  end
12
12
 
13
13
  before(:each) do
14
- allow(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", {moduledir: nil, puppetfile_path: nil}).and_return(puppetfile)
14
+ allow(R10K::ModuleLoader::Puppetfile).
15
+ to receive(:new).
16
+ with({
17
+ basedir: "/some/nonexistent/path",
18
+ }).and_return(loader)
15
19
  end
16
20
 
17
21
  it_behaves_like "a puppetfile action"
@@ -23,8 +27,11 @@ describe R10K::Action::Puppetfile::Check do
23
27
  end
24
28
 
25
29
  it "prints an error message when validating the Puppetfile syntax raised an error" do
26
- allow(puppetfile).to receive(:load!).and_raise(R10K::Error.new("Boom!"))
27
- allow(R10K::Errors::Formatting).to receive(:format_exception).with(instance_of(R10K::Error), anything).and_return("Formatted error message")
30
+ allow(loader).to receive(:load!).and_raise(R10K::Error.new("Boom!"))
31
+ allow(R10K::Errors::Formatting).
32
+ to receive(:format_exception).
33
+ with(instance_of(R10K::Error), anything).
34
+ and_return("Formatted error message")
28
35
 
29
36
  expect($stderr).to receive(:puts).with("Formatted error message")
30
37
 
@@ -34,7 +41,12 @@ describe R10K::Action::Puppetfile::Check do
34
41
  it "respects --puppetfile option" do
35
42
  allow($stderr).to receive(:puts)
36
43
 
37
- expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", {moduledir: nil, puppetfile_path: "/custom/puppetfile/path"}).and_return(puppetfile)
44
+ expect(R10K::ModuleLoader::Puppetfile).
45
+ to receive(:new).
46
+ with({
47
+ basedir: "/some/nonexistent/path",
48
+ puppetfile: "/custom/puppetfile/path"
49
+ }).and_return(loader)
38
50
 
39
51
  checker({puppetfile: "/custom/puppetfile/path"}).call
40
52
  end
@@ -3,9 +3,10 @@ require 'r10k/action/puppetfile/install'
3
3
 
4
4
  describe R10K::Action::Puppetfile::Install do
5
5
  let(:default_opts) { { root: "/some/nonexistent/path" } }
6
- let(:puppetfile) {
7
- R10K::Puppetfile.new('/some/nonexistent/path',
8
- {:moduledir => nil, :puppetfile_path => nil, :force => false})
6
+ let(:loader) {
7
+ R10K::ModuleLoader::Puppetfile.new({
8
+ basedir: '/some/nonexistent/path',
9
+ overrides: {force: false}})
9
10
  }
10
11
 
11
12
  def installer(opts = {}, argv = [], settings = {})
@@ -14,11 +15,11 @@ describe R10K::Action::Puppetfile::Install do
14
15
  end
15
16
 
16
17
  before(:each) do
17
- allow(puppetfile).to receive(:load!).and_return(nil)
18
- allow(R10K::Puppetfile).to receive(:new).
19
- with("/some/nonexistent/path",
20
- {:moduledir => nil, :puppetfile_path => nil, :force => false}).
21
- and_return(puppetfile)
18
+ allow(loader).to receive(:load!).and_return({})
19
+ allow(R10K::ModuleLoader::Puppetfile).to receive(:new).
20
+ with({basedir: "/some/nonexistent/path",
21
+ overrides: {force: false}}).
22
+ and_return(loader)
22
23
  end
23
24
 
24
25
  it_behaves_like "a puppetfile install action"
@@ -26,13 +27,19 @@ describe R10K::Action::Puppetfile::Install do
26
27
  describe "installing modules" do
27
28
  let(:modules) do
28
29
  (1..4).map do |idx|
29
- R10K::Module::Base.new("author/modname#{idx}", "/some/nonexistent/path/modname#{idx}", {})
30
+ R10K::Module::Base.new("author/modname#{idx}",
31
+ "/some/nonexistent/path/modname#{idx}",
32
+ {})
30
33
  end
31
34
  end
32
35
 
33
36
  before do
34
- allow(puppetfile).to receive(:modules).and_return(modules)
35
- allow(puppetfile).to receive(:modules_by_vcs_cachedir).and_return({none: modules})
37
+ allow(loader).to receive(:load!).and_return({
38
+ modules: modules,
39
+ managed_directories: [],
40
+ desired_contents: [],
41
+ purge_exclusions: []
42
+ })
36
43
  end
37
44
 
38
45
  it "syncs each module in the Puppetfile" do
@@ -50,15 +57,15 @@ describe R10K::Action::Puppetfile::Install do
50
57
  end
51
58
 
52
59
  describe "purging" do
53
- before do
54
- allow(puppetfile).to receive(:modules).and_return([])
55
- end
56
-
57
60
  it "purges the moduledir after installation" do
61
+ allow(loader).to receive(:load!).and_return({
62
+ modules: [],
63
+ desired_contents: [ 'root/foo' ],
64
+ managed_directories: [ 'root' ],
65
+ purge_exclusions: [ 'root/**/**.rb' ]
66
+ })
67
+
58
68
  mock_cleaner = double("cleaner")
59
- allow(puppetfile).to receive(:desired_contents).and_return(["root/foo"])
60
- allow(puppetfile).to receive(:managed_directories).and_return(["root"])
61
- allow(puppetfile).to receive(:purge_exclusions).and_return(["root/**/**.rb"])
62
69
 
63
70
  expect(R10K::Util::Cleaner).to receive(:new).
64
71
  with(["root"], ["root/foo"], ["root/**/**.rb"]).
@@ -70,35 +77,34 @@ describe R10K::Action::Puppetfile::Install do
70
77
  end
71
78
 
72
79
  describe "using custom paths" do
73
- it "can use a custom puppetfile path" do
74
- expect(R10K::Puppetfile).to receive(:new).
75
- with("/some/nonexistent/path",
76
- {:moduledir => nil, :force => false, puppetfile_path: "/some/other/path/Puppetfile"}).
77
- and_return(puppetfile)
80
+ it "can use a custom moduledir path" do
81
+ expect(R10K::ModuleLoader::Puppetfile).to receive(:new).
82
+ with({basedir: "/some/nonexistent/path",
83
+ overrides: { force: false },
84
+ puppetfile: "/some/other/path/Puppetfile"}).
85
+ and_return(loader)
78
86
 
79
87
  installer({puppetfile: "/some/other/path/Puppetfile"}).call
80
- end
81
88
 
82
- it "can use a custom moduledir path" do
83
- expect(R10K::Puppetfile).to receive(:new).
84
- with("/some/nonexistent/path",
85
- {:puppetfile_path => nil, :force => false, moduledir: "/some/other/path/site-modules"}).
86
- and_return(puppetfile)
89
+ expect(R10K::ModuleLoader::Puppetfile).to receive(:new).
90
+ with({basedir: "/some/nonexistent/path",
91
+ overrides: { force: false },
92
+ moduledir: "/some/other/path/site-modules"}).
93
+ and_return(loader)
87
94
 
88
95
  installer({moduledir: "/some/other/path/site-modules"}).call
89
96
  end
90
97
  end
91
98
 
92
99
  describe "forcing to overwrite local changes" do
93
- before do
94
- allow(puppetfile).to receive(:modules).and_return([])
95
- end
96
-
97
100
  it "can use the force overwrite option" do
101
+ allow(loader).to receive(:load!).and_return({ modules: [] })
102
+
98
103
  subject = described_class.new({root: "/some/nonexistent/path", force: true}, [], {})
99
- expect(R10K::Puppetfile).to receive(:new).
100
- with("/some/nonexistent/path", {:moduledir => nil, :puppetfile_path => nil, :force => true}).
101
- and_return(puppetfile)
104
+ expect(R10K::ModuleLoader::Puppetfile).to receive(:new).
105
+ with({basedir: "/some/nonexistent/path",
106
+ overrides: { force: true }}).
107
+ and_return(loader)
102
108
  subject.call
103
109
  end
104
110
 
@@ -4,11 +4,13 @@ require 'r10k/action/puppetfile/purge'
4
4
  describe R10K::Action::Puppetfile::Purge do
5
5
  let(:default_opts) { {root: "/some/nonexistent/path"} }
6
6
  let(:puppetfile) do
7
- instance_double('R10K::Puppetfile',
8
- :load! => nil,
9
- :managed_directories => %w{foo},
10
- :desired_contents => %w{bar},
11
- :purge_exclusions => %w{baz})
7
+ instance_double('R10K::ModuleLoader::Puppetfile',
8
+ :load! => {
9
+ :modules => %w{mod},
10
+ :managed_directories => %w{foo},
11
+ :desired_contents => %w{bar},
12
+ :purge_exclusions => %w{baz}
13
+ })
12
14
  end
13
15
 
14
16
  def purger(opts = {}, argv = [], settings = {})
@@ -17,8 +19,8 @@ describe R10K::Action::Puppetfile::Purge do
17
19
  end
18
20
 
19
21
  before(:each) do
20
- allow(R10K::Puppetfile).to receive(:new).
21
- with("/some/nonexistent/path", {moduledir: nil, puppetfile_path: nil}).
22
+ allow(R10K::ModuleLoader::Puppetfile).to receive(:new).
23
+ with({basedir: "/some/nonexistent/path"}).
22
24
  and_return(puppetfile)
23
25
  end
24
26
 
@@ -37,23 +39,19 @@ describe R10K::Action::Puppetfile::Purge do
37
39
  end
38
40
 
39
41
  describe "using custom paths" do
40
- before(:each) do
41
- allow(puppetfile).to receive(:purge!)
42
- end
43
-
44
42
  it "can use a custom puppetfile path" do
45
- expect(R10K::Puppetfile).to receive(:new).
46
- with("/some/nonexistent/path",
47
- {moduledir: nil, puppetfile_path: "/some/other/path/Puppetfile"}).
43
+ expect(R10K::ModuleLoader::Puppetfile).to receive(:new).
44
+ with({basedir: "/some/nonexistent/path",
45
+ puppetfile: "/some/other/path/Puppetfile"}).
48
46
  and_return(puppetfile)
49
47
 
50
48
  purger({puppetfile: "/some/other/path/Puppetfile"}).call
51
49
  end
52
50
 
53
51
  it "can use a custom moduledir path" do
54
- expect(R10K::Puppetfile).to receive(:new).
55
- with("/some/nonexistent/path",
56
- {moduledir: "/some/other/path/site-modules", puppetfile_path: nil}).
52
+ expect(R10K::ModuleLoader::Puppetfile).to receive(:new).
53
+ with({basedir: "/some/nonexistent/path",
54
+ moduledir: "/some/other/path/site-modules"}).
57
55
  and_return(puppetfile)
58
56
 
59
57
  purger({moduledir: "/some/other/path/site-modules"}).call
@@ -171,6 +171,86 @@ describe R10K::Action::Runner do
171
171
  end
172
172
  end
173
173
 
174
+ describe "configuring github app credentials" do
175
+ it 'errors if app id is passed without ssl key' do
176
+ runner = described_class.new(
177
+ { 'github-app-id': '/nonexistent', },
178
+ %w[args yes],
179
+ action_class
180
+ )
181
+ expect{ runner.call }.to raise_error(R10K::Error, /Must specify both id and SSL private key/)
182
+ end
183
+
184
+ it 'errors if ssl key is passed without app id' do
185
+ runner = described_class.new(
186
+ { 'github-app-key': '/nonexistent', },
187
+ %w[args yes],
188
+ action_class
189
+ )
190
+ expect{ runner.call }.to raise_error(R10K::Error, /Must specify both id and SSL private key/)
191
+ end
192
+
193
+ it 'errors if both app id and token paths are passed' do
194
+ runner = described_class.new(
195
+ { 'github-app-id': '/nonexistent', 'oauth-token': '/also/fake' },
196
+ %w[args yes],
197
+ action_class
198
+ )
199
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
200
+ end
201
+
202
+ it 'errors if both ssl key and token paths are passed' do
203
+ runner = described_class.new(
204
+ { 'github-app-key': '/nonexistent', 'oauth-token': '/also/fake' },
205
+ %w[args yes],
206
+ action_class
207
+ )
208
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
209
+ end
210
+
211
+ it 'errors if both ssl key and ssh key paths are passed' do
212
+ runner = described_class.new(
213
+ { 'github-app-key': '/nonexistent', 'private-key': '/also/fake' },
214
+ %w[args yes],
215
+ action_class
216
+ )
217
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
218
+ end
219
+
220
+ it 'errors if both app id and ssh key are passed' do
221
+ runner = described_class.new(
222
+ { 'github-app-id': '/nonexistent', 'private-key': '/also/fake' },
223
+ %w[args yes],
224
+ action_class
225
+ )
226
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
227
+ end
228
+
229
+ it 'saves the parameters in settings hash' do
230
+ runner = described_class.new(
231
+ { 'github-app-id': '123456', 'github-app-key': '/my/ssl/key', 'github-app-ttl': '600' },
232
+ %w[args yes],
233
+ action_class
234
+ )
235
+ runner.call
236
+ expect(runner.instance.settings[:git][:github_app_id]).to eq('123456')
237
+ expect(runner.instance.settings[:git][:github_app_key]).to eq('/my/ssl/key')
238
+ expect(runner.instance.settings[:git][:github_app_ttl]).to eq('600')
239
+ end
240
+
241
+ it 'saves the parameters in settings hash without ttl and uses its default value' do
242
+ runner = described_class.new(
243
+ { 'github-app-id': '123456', 'github-app-key': '/my/ssl/key', },
244
+ %w[args yes],
245
+ action_class
246
+ )
247
+ runner.call
248
+ expect(runner.instance.settings[:git][:github_app_id]).to eq('123456')
249
+ expect(runner.instance.settings[:git][:github_app_key]).to eq('/my/ssl/key')
250
+ expect(runner.instance.settings[:git][:github_app_ttl]).to eq('120')
251
+ end
252
+ end
253
+
174
254
  describe "configuring git credentials" do
175
255
  it 'errors if both token and key paths are passed' do
176
256
  runner = described_class.new({ 'oauth-token': '/nonexistent',
@@ -218,42 +298,58 @@ describe R10K::Action::Runner do
218
298
  end
219
299
 
220
300
  describe "configuration authorization" do
221
- context "when license is not present" do
222
- before(:each) do
223
- expect(R10K::Util::License).to receive(:load).and_return(nil)
224
- end
225
-
226
- it "does not set authorization header on connection class" do
227
- expect(PuppetForge::Connection).not_to receive(:authorization=)
301
+ context "settings auth" do
302
+ it "sets the configured token as the forge authorization header" do
303
+ options = { config: "spec/fixtures/unit/action/r10k_forge_auth.yaml" }
304
+ runner = described_class.new(options, %w[args yes], action_class)
305
+
306
+ expect(PuppetForge).to receive(:host=).with('http://private-forge.com')
307
+ expect(PuppetForge::Connection).to receive(:authorization=).with('faketoken')
308
+ expect(PuppetForge::Connection).to receive(:authorization).and_return('faketoken')
309
+ expect(R10K::Util::License).not_to receive(:load)
310
+ runner.setup_settings
228
311
  runner.setup_authorization
229
312
  end
230
313
  end
231
314
 
232
- context "when license is present but invalid" do
233
- before(:each) do
234
- expect(R10K::Util::License).to receive(:load).and_raise(R10K::Error.new('invalid license'))
235
- end
315
+ context "license auth" do
316
+ context "when license is not present" do
317
+ before(:each) do
318
+ expect(R10K::Util::License).to receive(:load).and_return(nil)
319
+ end
236
320
 
237
- it "issues warning to logger" do
238
- expect(runner.logger).to receive(:warn).with(/invalid license/)
239
- runner.setup_authorization
321
+ it "does not set authorization header on connection class" do
322
+ expect(PuppetForge::Connection).not_to receive(:authorization=)
323
+ runner.setup_authorization
324
+ end
240
325
  end
241
326
 
242
- it "does not set authorization header on connection class" do
243
- expect(PuppetForge::Connection).not_to receive(:authorization=)
244
- runner.setup_authorization
245
- end
246
- end
327
+ context "when license is present but invalid" do
328
+ before(:each) do
329
+ expect(R10K::Util::License).to receive(:load).and_raise(R10K::Error.new('invalid license'))
330
+ end
331
+
332
+ it "issues warning to logger" do
333
+ expect(runner.logger).to receive(:warn).with(/invalid license/)
334
+ runner.setup_authorization
335
+ end
247
336
 
248
- context "when license is present and valid" do
249
- before(:each) do
250
- mock_license = double('pe-license', :authorization_token => 'test token')
251
- expect(R10K::Util::License).to receive(:load).and_return(mock_license)
337
+ it "does not set authorization header on connection class" do
338
+ expect(PuppetForge::Connection).not_to receive(:authorization=)
339
+ runner.setup_authorization
340
+ end
252
341
  end
253
342
 
254
- it "sets authorization header on connection class" do
255
- expect(PuppetForge::Connection).to receive(:authorization=).with('test token')
256
- runner.setup_authorization
343
+ context "when license is present and valid" do
344
+ before(:each) do
345
+ mock_license = double('pe-license', :authorization_token => 'test token')
346
+ expect(R10K::Util::License).to receive(:load).and_return(mock_license)
347
+ end
348
+
349
+ it "sets authorization header on connection class" do
350
+ expect(PuppetForge::Connection).to receive(:authorization=).with('test token')
351
+ runner.setup_authorization
352
+ end
257
353
  end
258
354
  end
259
355
  end
@@ -3,10 +3,13 @@ require 'r10k/environment'
3
3
 
4
4
  describe R10K::Environment::Base do
5
5
 
6
- subject(:environment) { described_class.new('envname', '/some/imaginary/path', 'env_name', {}) }
6
+ let(:basepath) { '/some/imaginary/path' }
7
+ let(:envname) { 'env_name' }
8
+ let(:path) { File.join(basepath, envname) }
9
+ subject(:environment) { described_class.new('envname', basepath, envname, {}) }
7
10
 
8
11
  it "can return the fully qualified path" do
9
- expect(environment.path).to eq(Pathname.new('/some/imaginary/path/env_name'))
12
+ expect(environment.path).to eq(Pathname.new(path))
10
13
  end
11
14
 
12
15
  it "raises an exception when #sync is called" do
@@ -49,45 +52,55 @@ describe R10K::Environment::Base do
49
52
  describe "#purge_exclusions" do
50
53
  let(:mock_env) { instance_double("R10K::Environment::Base") }
51
54
  let(:mock_puppetfile) { instance_double("R10K::Puppetfile", :environment= => true, :environment => mock_env) }
55
+ let(:loader) do
56
+ instance_double("R10K::ModuleLoader::Puppetfile",
57
+ :environment= => nil,
58
+ :load => { :modules => @modules,
59
+ :managed_directories => @managed_dirs,
60
+ :desired_contents => @desired_contents,
61
+ :purge_exclusions => @purge_ex })
62
+ end
52
63
 
53
64
  before(:each) do
54
- allow(mock_puppetfile).to receive(:managed_directories).and_return([])
55
- allow(mock_puppetfile).to receive(:desired_contents).and_return([])
56
- allow(R10K::Puppetfile).to receive(:new).and_return(mock_puppetfile)
65
+ @modules = []
66
+ @managed_dirs = []
67
+ @desired_contents = []
68
+ @purge_exclusions = []
57
69
  end
58
70
 
59
71
  it "excludes .r10k-deploy.json" do
72
+ allow(R10K::ModuleLoader::Puppetfile).to receive(:new).and_return(loader)
73
+ subject.deploy
74
+
60
75
  expect(subject.purge_exclusions).to include(/r10k-deploy\.json/)
61
76
  end
62
77
 
63
78
  it "excludes puppetfile managed directories" do
64
- managed_dirs = [
79
+ @managed_dirs = [
65
80
  '/some/imaginary/path/env_name/modules',
66
81
  '/some/imaginary/path/env_name/data',
67
82
  ]
68
83
 
69
- expect(mock_puppetfile).to receive(:managed_directories).and_return(managed_dirs)
84
+ allow(R10K::ModuleLoader::Puppetfile).to receive(:new).and_return(loader)
85
+ subject.deploy
70
86
 
71
87
  exclusions = subject.purge_exclusions
72
88
 
73
- managed_dirs.each do |dir|
89
+ @managed_dirs.each do |dir|
74
90
  expect(exclusions).to include(dir)
75
91
  end
76
92
  end
77
93
 
78
94
  describe "puppetfile desired contents" do
79
- let(:desired_contents) do
80
- basedir = subject.path.to_s
81
-
82
- [ 'modules/apache', 'data/local/site' ].collect do |c|
83
- File.join(basedir, c)
84
- end
85
- end
86
95
 
87
96
  before(:each) do
88
- allow(File).to receive(:directory?).with(/^\/some\/imaginary\/path/).and_return(true)
97
+ @desired_contents = [ 'modules/apache', 'data/local/site' ].collect do |c|
98
+ File.join(path, c)
99
+ end
89
100
 
90
- expect(mock_puppetfile).to receive(:desired_contents).and_return(desired_contents)
101
+ allow(File).to receive(:directory?).and_return true
102
+ allow(R10K::ModuleLoader::Puppetfile).to receive(:new).and_return(loader)
103
+ subject.deploy
91
104
  end
92
105
 
93
106
  it "excludes desired directory contents with glob" do