r10k 3.11.0 → 3.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docker.yml +1 -1
  3. data/.github/workflows/rspec_tests.yml +2 -2
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.mkd +34 -0
  6. data/doc/dynamic-environments/configuration.mkd +35 -7
  7. data/doc/dynamic-environments/usage.mkd +26 -0
  8. data/doc/puppetfile.mkd +16 -4
  9. data/integration/tests/basic_functionality/basic_deployment.rb +176 -0
  10. data/lib/r10k/action/base.rb +1 -1
  11. data/lib/r10k/action/deploy/deploy_helpers.rb +4 -0
  12. data/lib/r10k/action/deploy/display.rb +1 -1
  13. data/lib/r10k/action/deploy/environment.rb +13 -8
  14. data/lib/r10k/action/deploy/module.rb +14 -10
  15. data/lib/r10k/action/puppetfile/check.rb +7 -5
  16. data/lib/r10k/action/puppetfile/install.rb +22 -16
  17. data/lib/r10k/action/puppetfile/purge.rb +12 -9
  18. data/lib/r10k/action/runner.rb +6 -0
  19. data/lib/r10k/action/visitor.rb +3 -0
  20. data/lib/r10k/cli/deploy.rb +1 -0
  21. data/lib/r10k/cli/puppetfile.rb +0 -1
  22. data/lib/r10k/content_synchronizer.rb +16 -4
  23. data/lib/r10k/environment/bare.rb +4 -7
  24. data/lib/r10k/environment/base.rb +64 -11
  25. data/lib/r10k/environment/name.rb +14 -9
  26. data/lib/r10k/environment/plain.rb +16 -0
  27. data/lib/r10k/environment/tarball.rb +78 -0
  28. data/lib/r10k/environment/with_modules.rb +6 -10
  29. data/lib/r10k/environment.rb +2 -0
  30. data/lib/r10k/errors.rb +5 -0
  31. data/lib/r10k/forge/module_release.rb +2 -1
  32. data/lib/r10k/git/cache.rb +4 -13
  33. data/lib/r10k/git/rugged/base_repository.rb +12 -1
  34. data/lib/r10k/git/rugged/cache.rb +8 -0
  35. data/lib/r10k/git/stateful_repository.rb +9 -0
  36. data/lib/r10k/initializers.rb +21 -7
  37. data/lib/r10k/logging.rb +78 -1
  38. data/lib/r10k/module/base.rb +5 -1
  39. data/lib/r10k/module/definition.rb +64 -0
  40. data/lib/r10k/module/forge.rb +10 -2
  41. data/lib/r10k/module/git.rb +22 -1
  42. data/lib/r10k/module/local.rb +6 -3
  43. data/lib/r10k/module/svn.rb +10 -0
  44. data/lib/r10k/module/tarball.rb +101 -0
  45. data/lib/r10k/module.rb +21 -2
  46. data/lib/r10k/module_loader/puppetfile/dsl.rb +8 -3
  47. data/lib/r10k/module_loader/puppetfile.rb +109 -30
  48. data/lib/r10k/puppetfile.rb +1 -2
  49. data/lib/r10k/settings.rb +46 -0
  50. data/lib/r10k/source/git.rb +18 -18
  51. data/lib/r10k/source/yaml.rb +1 -1
  52. data/lib/r10k/tarball.rb +183 -0
  53. data/lib/r10k/util/cacheable.rb +31 -0
  54. data/lib/r10k/util/downloader.rb +134 -0
  55. data/lib/r10k/util/purgeable.rb +6 -2
  56. data/lib/r10k/util/setopts.rb +2 -0
  57. data/lib/r10k/util/subprocess.rb +1 -0
  58. data/lib/r10k/version.rb +1 -1
  59. data/locales/r10k.pot +119 -71
  60. data/r10k.gemspec +2 -2
  61. data/r10k.yaml.example +28 -0
  62. data/spec/fixtures/tarball/tarball.tar.gz +0 -0
  63. data/spec/fixtures/unit/action/r10k_logging.yaml +12 -0
  64. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +8 -0
  65. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +10 -0
  66. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +10 -0
  67. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file +1 -0
  68. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/{managed_subdir_2 → subdir_allowlisted_2}/ignored_1 +0 -0
  69. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/unmanaged_symlink_dir +1 -0
  70. data/spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir +1 -0
  71. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_symlink_file +1 -0
  72. data/spec/integration/git/rugged/cache_spec.rb +33 -0
  73. data/spec/integration/util/purageable_spec.rb +41 -0
  74. data/spec/r10k-mocks/mock_env.rb +3 -0
  75. data/spec/r10k-mocks/mock_source.rb +7 -3
  76. data/spec/shared-contexts/tarball.rb +32 -0
  77. data/spec/spec_helper.rb +1 -0
  78. data/spec/unit/action/deploy/environment_spec.rb +80 -30
  79. data/spec/unit/action/deploy/module_spec.rb +52 -64
  80. data/spec/unit/action/puppetfile/check_spec.rb +17 -5
  81. data/spec/unit/action/puppetfile/install_spec.rb +42 -36
  82. data/spec/unit/action/puppetfile/purge_spec.rb +15 -17
  83. data/spec/unit/action/runner_spec.rb +52 -9
  84. data/spec/unit/environment/bare_spec.rb +13 -0
  85. data/spec/unit/environment/base_spec.rb +30 -17
  86. data/spec/unit/environment/git_spec.rb +2 -2
  87. data/spec/unit/environment/name_spec.rb +18 -0
  88. data/spec/unit/environment/plain_spec.rb +8 -0
  89. data/spec/unit/environment/svn_spec.rb +4 -3
  90. data/spec/unit/environment/tarball_spec.rb +45 -0
  91. data/spec/unit/environment/with_modules_spec.rb +3 -2
  92. data/spec/unit/git/cache_spec.rb +2 -15
  93. data/spec/unit/git/rugged/cache_spec.rb +19 -0
  94. data/spec/unit/module/base_spec.rb +8 -8
  95. data/spec/unit/module/forge_spec.rb +32 -4
  96. data/spec/unit/module/git_spec.rb +51 -10
  97. data/spec/unit/module/svn_spec.rb +18 -6
  98. data/spec/unit/module/tarball_spec.rb +70 -0
  99. data/spec/unit/module_loader/puppetfile_spec.rb +96 -31
  100. data/spec/unit/puppetfile_spec.rb +2 -2
  101. data/spec/unit/settings_spec.rb +25 -2
  102. data/spec/unit/tarball_spec.rb +57 -0
  103. data/spec/unit/util/cacheable_spec.rb +23 -0
  104. data/spec/unit/util/downloader_spec.rb +98 -0
  105. data/spec/unit/util/purgeable_spec.rb +22 -11
  106. metadata +44 -17
@@ -77,6 +77,11 @@ describe R10K::Action::Deploy::Module do
77
77
  basedir: '/some/nonexistent/path/control',
78
78
  environments: %w[first second]
79
79
  }
80
+ },
81
+ overrides: {
82
+ modules: {
83
+ pool_size: 4
84
+ }
80
85
  }
81
86
  )
82
87
  end
@@ -97,28 +102,22 @@ describe R10K::Action::Deploy::Module do
97
102
  )
98
103
  end
99
104
 
100
- before do
101
- @modules = []
105
+ it 'generate_types is true' do
106
+ expect(subject.settings[:overrides][:environments][:generate_types]).to eq(true)
107
+ end
108
+
109
+ it 'only calls puppet generate types on environments where the specified module was updated' do
102
110
  allow(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
103
- mod = R10K::Module::Local.new(environment.name, '/fakedir', {}, environment)
104
- if mod.name == 'first'
111
+ if environment.name == 'first'
112
+ expect(environment).to receive(:deploy).and_return(['first'])
105
113
  expect(environment).to receive(:generate_types!)
106
114
  else
115
+ expect(environment).to receive(:deploy).and_return([])
107
116
  expect(environment).not_to receive(:generate_types!)
108
117
  end
109
- @modules << mod
110
- expect(environment.puppetfile).to receive(:modules).and_return([mod]).twice
111
118
  original.call(environment, &block)
112
119
  end
113
- end
114
-
115
- it 'generate_types is true' do
116
- expect(subject.settings[:overrides][:environments][:generate_types]).to eq(true)
117
- end
118
-
119
- it 'only calls puppet generate types on environments with specified module' do
120
120
  subject.call
121
- expect(@modules.length).to be(2)
122
121
  end
123
122
  end
124
123
 
@@ -242,35 +241,33 @@ describe R10K::Action::Deploy::Module do
242
241
 
243
242
  allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
244
243
  allow(R10K::Git).to receive_message_chain(:cache, :generate).and_return(cache)
245
- allow_any_instance_of(R10K::Source::Git).to receive(:branch_names).and_return([R10K::Environment::Name.new('first', {})])
244
+ allow_any_instance_of(R10K::Source::Git).to receive(:environment_names).and_return([R10K::Environment::Name.new('first', {})])
246
245
 
247
246
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
248
247
  # For this test we want to have realistic Modules and access to
249
248
  # their internal Repos to validate the sync. Unfortunately, to
250
249
  # do so we do some invasive mocking, effectively implementing
251
- # our own R10K::Puppetfile#load. We directly update the Puppetfile's
252
- # internal ModuleLoader and then call `load` on it so it will create
253
- # the correct loaded_content.
254
- puppetfile = environment.puppetfile
255
- loader = puppetfile.loader
256
- expect(puppetfile).to receive(:load) do
250
+ # our own R10K::ModuleLoader::Puppetfile#load. We directly update
251
+ # the Environment's internal ModuleLoader and then call `load` on
252
+ # it so it will create the correct loaded_content.
253
+ loader = environment.loader
254
+ allow(loader).to receive(:puppetfile_content).and_return('')
255
+ expect(loader).to receive(:load) do
257
256
  loader.add_module('mod1', { git: 'git://remote' })
258
257
  loader.add_module('mod2', { git: 'git://remote' })
259
258
  loader.add_module('mod3', { git: 'git://remote' })
260
259
 
261
- allow(loader).to receive(:puppetfile_content).and_return('')
262
- loaded_content = loader.load
263
- puppetfile.instance_variable_set(:@loaded_content, loaded_content)
264
- puppetfile.instance_variable_set(:@loaded, true)
265
- end
266
-
267
- puppetfile.modules.each do |mod|
268
- if ['mod1', 'mod2'].include?(mod.name)
269
- expect(mod.should_sync?).to be(true)
270
- else
271
- expect(mod.should_sync?).to be(false)
260
+ loaded_content = loader.load!
261
+ loaded_content[:modules].each do |mod|
262
+ if ['mod1', 'mod2'].include?(mod.name)
263
+ expect(mod.should_sync?).to be(true)
264
+ else
265
+ expect(mod.should_sync?).to be(false)
266
+ end
267
+ expect(mod).to receive(:sync).and_call_original
272
268
  end
273
- expect(mod).to receive(:sync).and_call_original
269
+
270
+ loaded_content
274
271
  end
275
272
 
276
273
  original.call(environment, &block)
@@ -303,40 +300,39 @@ describe R10K::Action::Deploy::Module do
303
300
 
304
301
  allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
305
302
  allow(R10K::Git).to receive_message_chain(:cache, :generate).and_return(cache)
306
- allow_any_instance_of(R10K::Source::Git).to receive(:branch_names).and_return([R10K::Environment::Name.new('first', {}),
303
+ allow_any_instance_of(R10K::Source::Git).to receive(:environment_names).and_return([R10K::Environment::Name.new('first', {}),
307
304
  R10K::Environment::Name.new('second', {})])
308
305
 
309
306
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
310
- puppetfile = environment.puppetfile
307
+ loader = environment.loader
311
308
 
312
309
  if environment.name == 'first'
313
310
  # For this test we want to have realistic Modules and access to
314
311
  # their internal Repos to validate the sync. Unfortunately, to
315
312
  # do so we do some invasive mocking, effectively implementing
316
- # our own R10K::Puppetfile#load. We directly update the Puppetfile's
317
- # internal ModuleLoader and then call `load` on it so it will create
318
- # the correct loaded_content.
319
- loader = puppetfile.loader
320
- expect(puppetfile).to receive(:load) do
313
+ # our own R10K::ModuleLoader::Puppetfile#load. We directly update
314
+ # the Environment's internal ModuleLoader and then call `load` on
315
+ # it so it will create the correct loaded_content.
316
+ allow(loader).to receive(:puppetfile_content).and_return('')
317
+ expect(loader).to receive(:load) do
321
318
  loader.add_module('mod1', { git: 'git://remote' })
322
319
  loader.add_module('mod2', { git: 'git://remote' })
323
320
 
324
- allow(loader).to receive(:puppetfile_content).and_return('')
325
- loaded_content = loader.load
326
- puppetfile.instance_variable_set(:@loaded_content, loaded_content)
327
- puppetfile.instance_variable_set(:@loaded, true)
328
- end
329
-
330
- puppetfile.modules.each do |mod|
331
- if mod.name == 'mod1'
332
- expect(mod.should_sync?).to be(true)
333
- else
334
- expect(mod.should_sync?).to be(false)
321
+ loaded_content = loader.load!
322
+ loaded_content[:modules].each do |mod|
323
+ if mod.name == 'mod1'
324
+ expect(mod.should_sync?).to be(true)
325
+ else
326
+ expect(mod.should_sync?).to be(false)
327
+ end
328
+ expect(mod).to receive(:sync).and_call_original
335
329
  end
336
- expect(mod).to receive(:sync).and_call_original
330
+
331
+ loaded_content
337
332
  end
333
+
338
334
  else
339
- expect(puppetfile).not_to receive(:load)
335
+ expect(loader).not_to receive(:load)
340
336
  end
341
337
 
342
338
  original.call(environment, &block)
@@ -415,16 +411,13 @@ describe R10K::Action::Deploy::Module do
415
411
  allow(mock_subprocess).to receive(:logger=)
416
412
  expect(mock_subprocess).to receive(:execute)
417
413
 
418
- mock_mod = double('mock_mod', name: 'mod1')
419
-
420
414
  expect(R10K::Util::Subprocess).to receive(:new).
421
415
  with(["/generate/types/wrapper", "first"]).
422
416
  and_return(mock_subprocess)
423
417
 
424
418
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
425
419
  if environment.name == 'first'
426
- expect(environment).to receive(:deploy).and_return(true)
427
- expect(environment).to receive(:modules).and_return([mock_mod])
420
+ expect(environment).to receive(:deploy).and_return(['first'])
428
421
  end
429
422
  original.call(environment, &block)
430
423
  end.exactly(3).times
@@ -455,12 +448,9 @@ describe R10K::Action::Deploy::Module do
455
448
  with(["/generate/types/wrapper", "first third"]).
456
449
  and_return(mock_subprocess)
457
450
 
458
- mock_mod = double('mock_mod', name: 'mod1')
459
-
460
451
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
461
- expect(environment).to receive(:deploy).and_return(true)
462
452
  if ['first', 'third'].include?(environment.name)
463
- expect(environment).to receive(:modules).and_return([mock_mod])
453
+ expect(environment).to receive(:deploy).and_return(['mod1'])
464
454
  end
465
455
  original.call(environment, &block)
466
456
  end.exactly(3).times
@@ -473,9 +463,7 @@ describe R10K::Action::Deploy::Module do
473
463
 
474
464
  mock_mod2 = double('mock_mod', name: 'mod2')
475
465
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
476
- expect(environment).to receive(:deploy).and_return(true)
477
- # Envs have a different module than the one we asked to deploy
478
- expect(environment).to receive(:modules).and_return([mock_mod2])
466
+ expect(environment).to receive(:deploy).and_return([])
479
467
  original.call(environment, &block)
480
468
  end.exactly(3).times
481
469
 
@@ -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
@@ -159,10 +159,61 @@ describe R10K::Action::Runner do
159
159
  end
160
160
 
161
161
  describe "configuring logging" do
162
+ before(:each) do
163
+ R10K::Logging.outputters.clear
164
+ end
165
+
162
166
  it "sets the log level if :loglevel is provided" do
163
167
  runner = described_class.new({:opts => :yep, :loglevel => 'FATAL'}, %w[args yes], action_class)
164
- expect(R10K::Logging).to receive(:level=).with('FATAL')
168
+ # The settings/overrides system causes the level to be set twice
169
+ expect(R10K::Logging).to receive(:level=).with('FATAL').twice
170
+ runner.call
171
+ end
172
+
173
+ # The logging fixture tests require a platform with syslog
174
+ if !R10K::Util::Platform.windows?
175
+ it "sets the log level if the logging.level setting is provided" do
176
+ runner = described_class.new({ opts: :yep, config: 'spec/fixtures/unit/action/r10k_logging.yaml'}, %w[args yes], action_class)
177
+ expect(R10K::Logging).to receive(:level=).with('FATAL')
178
+ runner.call
179
+ end
180
+
181
+ it "sets the outputters if logging.outputs is provided" do
182
+ runner = described_class.new({ opts: :yep, config: 'spec/fixtures/unit/action/r10k_logging.yaml' }, %w[args yes], action_class)
183
+ expect(R10K::Logging).to receive(:add_outputters).with([
184
+ { type: 'file', parameters: { filename: 'r10k.log' } },
185
+ { type: 'syslog' }
186
+ ])
187
+ runner.call
188
+ end
189
+
190
+ it "disables the default outputter if the logging.disable_default_stderr setting is provided" do
191
+ runner = described_class.new({ opts: :yep, config: 'spec/fixtures/unit/action/r10k_logging.yaml'}, %w[args yes], action_class)
192
+ expect(R10K::Logging).to receive(:disable_default_stderr=).with(true)
193
+ runner.call
194
+ end
195
+
196
+ it "adds additional log outputs if the logging.outputs setting is provided" do
197
+ runner = described_class.new({ opts: :yep, config: 'spec/fixtures/unit/action/r10k_logging.yaml'}, %w[args yes], action_class)
198
+ runner.call
199
+ expect(R10K::Logging.outputters).to_not be_empty
200
+ end
201
+
202
+ it "disables the default output if the logging.disable_default_stderr setting is provided" do
203
+ runner = described_class.new({ opts: :yep, config: 'spec/fixtures/unit/action/r10k_logging.yaml'}, %w[args yes], action_class)
204
+ runner.call
205
+ expect(runner.logger.outputters).to satisfy { |outputs| outputs.any? { |output| output.is_a?(R10K::Logging::TerminalOutputter) && output.level == Log4r::OFF } }
206
+ end
207
+ end
208
+
209
+ it "doesn't add additional log outputs if the logging.outputs setting is not provided" do
210
+ runner.call
211
+ expect(R10K::Logging.outputters).to be_empty
212
+ end
213
+
214
+ it "includes the default stderr outputter" do
165
215
  runner.call
216
+ expect(runner.logger.outputters).to satisfy { |outputs| outputs.any? { |output| output.is_a? R10K::Logging::TerminalOutputter } }
166
217
  end
167
218
 
168
219
  it "does not modify the loglevel if :loglevel is not provided" do
@@ -310,14 +361,6 @@ describe R10K::Action::Runner do
310
361
  runner.setup_settings
311
362
  runner.setup_authorization
312
363
  end
313
-
314
- it 'errors if no custom forge URL is set' do
315
- options = { config: "spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml" }
316
- runner = described_class.new(options, %w[args yes], action_class)
317
- expect(PuppetForge::Connection).not_to receive(:authorization=).with('faketoken')
318
-
319
- expect { runner.setup_settings }.to raise_error(R10K::Error, /Cannot specify a Forge auth/)
320
- end
321
364
  end
322
365
 
323
366
  context "license auth" do
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'r10k/environment'
3
+
4
+ describe R10K::Environment::Bare do
5
+ it "warns on initialization" do
6
+ logger_spy = spy('logger')
7
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger_spy)
8
+
9
+ described_class.new('envname', '/basedir', 'dirname', {})
10
+
11
+ expect(logger_spy).to have_received(:warn).with(%r{deprecated.*envname})
12
+ end
13
+ 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
@@ -78,9 +78,9 @@ describe R10K::Environment::Git do
78
78
 
79
79
  describe "enumerating modules" do
80
80
  it "loads the Puppetfile and returns modules in that puppetfile" do
81
+ loaded = { desired_contents: [], managed_directories: [], purge_exclusions: [] }
81
82
  mod = double('A module', :name => 'dbl')
82
- expect(subject.puppetfile).to receive(:load)
83
- expect(subject.puppetfile).to receive(:modules).and_return [mod]
83
+ expect(subject.loader).to receive(:load).and_return(loaded.merge(modules: [mod]))
84
84
  expect(subject.modules).to eq([mod])
85
85
  end
86
86
  end