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
@@ -76,4 +76,32 @@ describe R10K::Module do
76
76
  R10K::Module.new('bar!quux', '/modulepath', {version: ["NOPE NOPE NOPE NOPE!"]})
77
77
  }.to raise_error RuntimeError, /doesn't have an implementation/
78
78
  end
79
+
80
+ describe 'Given a set of initialization parameters for R10K::Module' do
81
+ [ ['name', {git: 'git url'}],
82
+ ['name', {type: 'git', source: 'git url'}],
83
+ ['name', {svn: 'svn url'}],
84
+ ['name', {type: 'svn', source: 'svn url'}],
85
+ ['namespace-name', {version: '8.0.0'}],
86
+ ['namespace-name', {type: 'forge', version: '8.0.0'}]
87
+ ].each do |(name, options)|
88
+ it 'can handle the default_branch_override option' do
89
+ expect {
90
+ obj = R10K::Module.new(name, '/modulepath', options.merge({default_branch_override: 'foo'}))
91
+ expect(obj).to be_a_kind_of(R10K::Module::Base)
92
+ }.not_to raise_error
93
+ end
94
+ describe 'the exclude_spec setting' do
95
+ it 'sets the exclude_spec instance variable' do
96
+ obj = R10K::Module.new(name, '/modulepath', options.merge({exclude_spec: true}))
97
+ expect(obj.instance_variable_get("@exclude_spec")).to eq(true)
98
+ end
99
+ it 'can be overridden by the overrides map' do
100
+ options = options.merge({exclude_spec: false, overrides: {modules: {exclude_spec: true}}})
101
+ obj = R10K::Module.new(name, '/modulepath', options)
102
+ expect(obj.instance_variable_get("@exclude_spec")).to eq(true)
103
+ end
104
+ end
105
+ end
106
+ end
79
107
  end
@@ -10,7 +10,7 @@ describe R10K::Puppetfile do
10
10
  )
11
11
  end
12
12
 
13
- describe "a custom puppetfile Puppetfile.r10k" do
13
+ describe "a custom puppetfile_name" do
14
14
  it "is the basedir joined with '/Puppetfile.r10k' path" do
15
15
  expect(subject.puppetfile_path).to eq '/some/nonexistent/basedir/Puppetfile.r10k'
16
16
  end
@@ -18,6 +18,25 @@ describe R10K::Puppetfile do
18
18
 
19
19
  end
20
20
 
21
+ describe R10K::Puppetfile do
22
+
23
+ describe "a custom relative puppetfile_path" do
24
+ it "is the basedir joined with the puppetfile_path" do
25
+ relative_subject = described_class.new('/some/nonexistent/basedir',
26
+ {puppetfile_path: 'relative/Puppetfile'})
27
+ expect(relative_subject.puppetfile_path).to eq '/some/nonexistent/basedir/relative/Puppetfile'
28
+ end
29
+ end
30
+
31
+ describe "a custom absolute puppetfile_path" do
32
+ it "is the puppetfile_path as given" do
33
+ absolute_subject = described_class.new('/some/nonexistent/basedir',
34
+ {puppetfile_path: '/some/absolute/custom/Puppetfile'})
35
+ expect(absolute_subject.puppetfile_path).to eq '/some/absolute/custom/Puppetfile'
36
+ end
37
+ end
38
+ end
39
+
21
40
  describe R10K::Puppetfile do
22
41
 
23
42
  subject do
@@ -67,230 +86,147 @@ describe R10K::Puppetfile do
67
86
  end
68
87
  end
69
88
 
70
- describe "adding modules" do
71
- it "should transform Forge modules with a string arg to have a version key" do
72
- allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.moduledir, hash_including(version: '1.2.3'), anything).and_call_original
73
-
74
- expect { subject.add_module('puppet/test_module', '1.2.3') }.to change { subject.modules }
75
- expect(subject.modules.collect(&:name)).to include('test_module')
76
- end
77
-
78
- it "should not accept Forge modules with a version comparison" do
79
- allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.moduledir, hash_including(version: '< 1.2.0'), anything).and_call_original
80
-
81
- expect {
82
- subject.add_module('puppet/test_module', '< 1.2.0')
83
- }.to raise_error(RuntimeError, /module puppet\/test_module.*doesn't have an implementation/i)
84
-
85
- expect(subject.modules.collect(&:name)).not_to include('test_module')
86
- end
87
-
88
- it "should accept non-Forge modules with a hash arg" do
89
- module_opts = { git: 'git@example.com:puppet/test_module.git' }
90
-
91
- allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.moduledir, module_opts, anything).and_call_original
92
-
93
- expect { subject.add_module('puppet/test_module', module_opts) }.to change { subject.modules }
94
- expect(subject.modules.collect(&:name)).to include('test_module')
95
- end
96
-
97
- it "should accept non-Forge modules with a valid relative :install_path option" do
98
- module_opts = {
99
- install_path: 'vendor',
100
- git: 'git@example.com:puppet/test_module.git',
101
- }
102
-
103
- allow(R10K::Module).to receive(:new).with('puppet/test_module', File.join(subject.basedir, 'vendor'), module_opts, anything).and_call_original
104
-
105
- expect { subject.add_module('puppet/test_module', module_opts) }.to change { subject.modules }
106
- expect(subject.modules.collect(&:name)).to include('test_module')
107
- end
108
-
109
- it "should accept non-Forge modules with a valid absolute :install_path option" do
110
- install_path = File.join(subject.basedir, 'vendor')
111
-
112
- module_opts = {
113
- install_path: install_path,
114
- git: 'git@example.com:puppet/test_module.git',
115
- }
116
-
117
- allow(R10K::Module).to receive(:new).with('puppet/test_module', install_path, module_opts, anything).and_call_original
118
-
119
- expect { subject.add_module('puppet/test_module', module_opts) }.to change { subject.modules }
120
- expect(subject.modules.collect(&:name)).to include('test_module')
121
- end
89
+ describe "loading a Puppetfile" do
90
+ context 'using load' do
91
+ it "returns the loaded content" do
92
+ path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
93
+ subject = described_class.new(path, {})
122
94
 
123
- it "should reject non-Forge modules with an invalid relative :install_path option" do
124
- module_opts = {
125
- install_path: '../../vendor',
126
- git: 'git@example.com:puppet/test_module.git',
127
- }
95
+ loaded_content = subject.load
96
+ expect(loaded_content).to be_an_instance_of(Hash)
128
97
 
129
- allow(R10K::Module).to receive(:new).with('puppet/test_module', File.join(subject.basedir, 'vendor'), module_opts, anything).and_call_original
98
+ has_some_data = loaded_content.values.none?(&:empty?)
99
+ expect(has_some_data).to be true
100
+ end
130
101
 
131
- expect { subject.add_module('puppet/test_module', module_opts) }.to raise_error(R10K::Error, /cannot manage content.*is not within/i).and not_change { subject.modules }
132
- end
102
+ it "handles a relative basedir" do
103
+ path = File.join('spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
104
+ subject = described_class.new(path, {})
133
105
 
134
- it "should reject non-Forge modules with an invalid absolute :install_path option" do
135
- module_opts = {
136
- install_path: '/tmp/mydata/vendor',
137
- git: 'git@example.com:puppet/test_module.git',
138
- }
106
+ loaded_content = subject.load
107
+ expect(loaded_content).to be_an_instance_of(Hash)
139
108
 
140
- allow(R10K::Module).to receive(:new).with('puppet/test_module', File.join(subject.basedir, 'vendor'), module_opts, anything).and_call_original
109
+ has_some_data = loaded_content.values.none?(&:empty?)
110
+ expect(has_some_data).to be true
111
+ end
141
112
 
142
- expect { subject.add_module('puppet/test_module', module_opts) }.to raise_error(R10K::Error, /cannot manage content.*is not within/i).and not_change { subject.modules }
143
- end
113
+ it "is idempotent" do
114
+ path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
115
+ subject = described_class.new(path, {})
144
116
 
145
- it "should disable and not add modules that conflict with the environment" do
146
- env = instance_double('R10K::Environment::Base')
147
- mod = instance_double('R10K::Module::Base', name: 'conflict', origin: :puppetfile)
148
- allow(mod).to receive(:origin=).and_return(nil)
149
- allow(subject).to receive(:environment).and_return(env)
150
- allow(env).to receive(:'module_conflicts?').with(mod).and_return(true)
117
+ expect(subject.loader).to receive(:load!).and_call_original.once
151
118
 
152
- allow(R10K::Module).to receive(:new).with('test', anything, anything, anything).and_return(mod)
153
- expect { subject.add_module('test', {}) }.not_to change { subject.modules }
154
- end
155
- end
119
+ loaded_content1 = subject.load
120
+ expect(subject.loaded?).to be true
121
+ loaded_content2 = subject.load
156
122
 
157
- describe "#purge_exclusions" do
158
- let(:managed_dirs) { ['dir1', 'dir2'] }
123
+ expect(loaded_content2).to eq(loaded_content1)
124
+ end
159
125
 
160
- before(:each) do
161
- allow(subject).to receive(:managed_directories).and_return(managed_dirs)
126
+ it "returns nil if Puppetfile doesn't exist" do
127
+ path = '/rando/path/that/wont/exist'
128
+ subject = described_class.new(path, {})
129
+ expect(subject.load).to eq nil
130
+ end
162
131
  end
163
132
 
164
- it "includes managed_directories" do
165
- expect(subject.purge_exclusions).to match_array(managed_dirs)
166
- end
133
+ context 'using load!' do
134
+ it "returns the loaded content" do
135
+ path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
136
+ subject = described_class.new(path, {})
167
137
 
168
- context "when belonging to an environment" do
169
- let(:env_contents) { ['env1', 'env2' ] }
138
+ loaded_content = subject.load!
139
+ expect(loaded_content).to be_an_instance_of(Hash)
170
140
 
171
- before(:each) do
172
- mock_env = double(:environment, desired_contents: env_contents)
173
- allow(subject).to receive(:environment).and_return(mock_env)
141
+ has_some_data = loaded_content.values.none?(&:empty?)
142
+ expect(has_some_data).to be true
174
143
  end
175
144
 
176
- it "includes environment's desired_contents" do
177
- expect(subject.purge_exclusions).to match_array(managed_dirs + env_contents)
145
+ it "raises if Puppetfile doesn't exist" do
146
+ path = '/rando/path/that/wont/exist'
147
+ subject = described_class.new(path, {})
148
+ expect {
149
+ subject.load!
150
+ }.to raise_error(/No such file or directory.*\/rando\/path\/.*/)
178
151
  end
179
152
  end
180
153
  end
181
154
 
182
- describe '#managed_directories' do
183
- it 'returns an array of paths that can be purged' do
184
- allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.moduledir, hash_including(version: '1.2.3'), anything).and_call_original
155
+ describe 'default_branch_override' do
156
+ it 'is passed correctly to module loader init' do
157
+ # This path doesn't matter so long as it has a Puppetfile within it
158
+ path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
159
+ subject = described_class.new(path, {overrides: {environments: {default_branch_override: 'foo'}}})
185
160
 
186
- subject.add_module('puppet/test_module', '1.2.3')
187
- expect(subject.managed_directories).to match_array(["/some/nonexistent/basedir/modules"])
188
- end
161
+ repo = instance_double('R10K::Git::StatefulRepository')
162
+ allow(repo).to receive(:resolve).with('foo').and_return(true)
163
+ allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
189
164
 
190
- context 'with a module with install_path == \'\'' do
191
- it 'basedir isn\'t in the list of paths to purge' do
192
- module_opts = { install_path: '', git: 'git@example.com:puppet/test_module.git' }
165
+ allow(subject.loader).to receive(:puppetfile_content).and_return <<-EOPF
166
+ # Track control branch and fall-back to main if no matching branch.
167
+ mod 'hieradata',
168
+ :git => 'git@git.example.com:organization/hieradata.git',
169
+ :branch => :control_branch,
170
+ :default_branch => 'main'
171
+ EOPF
193
172
 
194
- allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.basedir, module_opts, anything).and_call_original
173
+ expect(subject.logger).not_to receive(:warn).
174
+ with(/Mismatch between passed and initialized.*preferring passed value/)
195
175
 
196
- subject.add_module('puppet/test_module', module_opts)
197
- expect(subject.managed_directories).to be_empty
198
- end
199
- end
200
- end
176
+ subject.load
201
177
 
202
- describe "evaluating a Puppetfile" do
203
- def expect_wrapped_error(orig, pf_path, wrapped_error)
204
- expect(orig).to be_a_kind_of(R10K::Error)
205
- expect(orig.message).to eq("Failed to evaluate #{pf_path}")
206
- expect(orig.original).to be_a_kind_of(wrapped_error)
178
+ loaded_module = subject.modules.first
179
+ expect(loaded_module.version).to eq('foo')
207
180
  end
208
181
 
209
- it "wraps and re-raises syntax errors" do
210
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'invalid-syntax')
211
- pf_path = File.join(path, 'Puppetfile')
212
- subject = described_class.new(path, {})
213
- expect {
214
- subject.load!
215
- }.to raise_error do |e|
216
- expect_wrapped_error(e, pf_path, SyntaxError)
217
- end
218
- end
182
+ it 'overrides module loader init if needed' do
183
+ # This path doesn't matter so long as it has a Puppetfile within it
184
+ path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
185
+ subject = described_class.new(path, {overrides: {environments: {default_branch_override: 'foo'}}})
219
186
 
220
- it "wraps and re-raises load errors" do
221
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'load-error')
222
- pf_path = File.join(path, 'Puppetfile')
223
- subject = described_class.new(path, {})
224
- expect {
225
- subject.load!
226
- }.to raise_error do |e|
227
- expect_wrapped_error(e, pf_path, LoadError)
228
- end
229
- end
187
+ repo = instance_double('R10K::Git::StatefulRepository')
188
+ allow(repo).to receive(:resolve).with('bar').and_return(true)
189
+ allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
230
190
 
231
- it "wraps and re-raises argument errors" do
232
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'argument-error')
233
- pf_path = File.join(path, 'Puppetfile')
234
- subject = described_class.new(path, {})
235
- expect {
236
- subject.load!
237
- }.to raise_error do |e|
238
- expect_wrapped_error(e, pf_path, ArgumentError)
239
- end
240
- end
191
+ allow(subject.loader).to receive(:puppetfile_content).and_return <<-EOPF
192
+ # Track control branch and fall-back to main if no matching branch.
193
+ mod 'hieradata',
194
+ :git => 'git@git.example.com:organization/hieradata.git',
195
+ :branch => :control_branch,
196
+ :default_branch => 'main'
197
+ EOPF
241
198
 
242
- it "rejects Puppetfiles with duplicate module names" do
243
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'duplicate-module-error')
244
- pf_path = File.join(path, 'Puppetfile')
245
- subject = described_class.new(path, {})
246
- expect {
247
- subject.load!
248
- }.to raise_error(R10K::Error, /Puppetfiles cannot contain duplicate module names/i)
249
- end
199
+ expect(subject.logger).to receive(:warn).
200
+ with(/Mismatch between passed and initialized.*preferring passed value/)
250
201
 
251
- it "wraps and re-raises name errors" do
252
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'name-error')
253
- pf_path = File.join(path, 'Puppetfile')
254
- subject = described_class.new(path, {})
255
- expect {
256
- subject.load!
257
- }.to raise_error do |e|
258
- expect_wrapped_error(e, pf_path, NameError)
259
- end
202
+ subject.load('bar')
203
+ loaded_module = subject.modules.first
204
+ expect(loaded_module.version).to eq('bar')
260
205
  end
261
206
 
262
- it "accepts a forge module with a version" do
207
+ it 'does not warn if passed and initialized default_branch_overrides match' do
208
+ # This path doesn't matter so long as it has a Puppetfile within it
263
209
  path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
264
- pf_path = File.join(path, 'Puppetfile')
265
- subject = described_class.new(path, {})
266
- expect { subject.load! }.not_to raise_error
267
- end
210
+ subject = described_class.new(path, {overrides: {environments: {default_branch_override: 'foo'}}})
268
211
 
269
- it "accepts a forge module without a version" do
270
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-without-version')
271
- pf_path = File.join(path, 'Puppetfile')
272
- subject = described_class.new(path, {})
273
- expect { subject.load! }.not_to raise_error
274
- end
212
+ repo = instance_double('R10K::Git::StatefulRepository')
213
+ allow(repo).to receive(:resolve).with('foo').and_return(true)
214
+ allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
275
215
 
276
- it "creates a git module and applies the default branch sepcified in the Puppetfile" do
277
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'default-branch-override')
278
- pf_path = File.join(path, 'Puppetfile')
279
- subject = described_class.new(path, {})
280
- expect { subject.load! }.not_to raise_error
281
- git_module = subject.modules[0]
282
- expect(git_module.default_ref).to eq 'here_lies_the_default_branch'
283
- end
216
+ allow(subject.loader).to receive(:puppetfile_content).and_return <<-EOPF
217
+ # Track control branch and fall-back to main if no matching branch.
218
+ mod 'hieradata',
219
+ :git => 'git@git.example.com:organization/hieradata.git',
220
+ :branch => :control_branch,
221
+ :default_branch => 'main'
222
+ EOPF
223
+
224
+ expect(subject.logger).not_to receive(:warn).
225
+ with(/Mismatch between passed and initialized.*preferring passed value/)
284
226
 
285
- it "creates a git module and applies the provided default_branch_override" do
286
- path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'default-branch-override')
287
- pf_path = File.join(path, 'Puppetfile')
288
- subject = described_class.new(path, {})
289
- default_branch_override = 'default_branch_override_name'
290
- expect { subject.load!(default_branch_override) }.not_to raise_error
291
- git_module = subject.modules[0]
292
- expect(git_module.default_override_ref).to eq default_branch_override
293
- expect(git_module.default_ref).to eq "here_lies_the_default_branch"
227
+ subject.load('foo')
228
+ loaded_module = subject.modules.first
229
+ expect(loaded_module.version).to eq('foo')
294
230
  end
295
231
  end
296
232
 
@@ -337,7 +273,7 @@ describe R10K::Puppetfile do
337
273
  expect(subject).to receive(:modules).and_return([mod1, mod2])
338
274
 
339
275
  expect(Thread).to receive(:new).exactly(pool_size).and_call_original
340
- expect(Queue).to receive(:new).and_call_original
276
+ expect(Queue).to receive(:new).and_call_original.twice
341
277
 
342
278
  subject.accept(visitor)
343
279
  end
@@ -90,11 +90,50 @@ describe R10K::Settings do
90
90
  end
91
91
  end
92
92
  end
93
+
94
+ describe "allow_puppetfile_override" do
95
+ it 'is false by default' do
96
+ expect(subject.evaluate({})[:allow_puppetfile_override]).to eq(false)
97
+ end
98
+
99
+ it 'can be set to true' do
100
+ expect(subject.evaluate({"allow_puppetfile_override" => true})[:allow_puppetfile_override]).to eq(true)
101
+ end
102
+
103
+ it "raises an error for non-boolean values" do
104
+ expect {
105
+ subject.evaluate({"allow_puppetfile_override" => 'invalid_string'})
106
+ }.to raise_error do |err|
107
+ expect(err.message).to match(/Validation failed for 'forge' settings group/)
108
+ expect(err.errors.size).to eq 1
109
+ expect(err.errors[:allow_puppetfile_override]).to be_a_kind_of(ArgumentError)
110
+ expect(err.errors[:allow_puppetfile_override].message).to match(/`allow_puppetfile_override` can only be a boolean value, not 'invalid_string'/)
111
+ end
112
+ end
113
+ end
93
114
  end
94
115
 
95
116
  describe "deploy settings" do
96
117
  subject { described_class.deploy_settings }
97
118
 
119
+ describe 'exclude_spec' do
120
+ it 'is false by default' do
121
+ expect(subject.evaluate({})[:exclude_spec]).to eq(false)
122
+ end
123
+ it 'can be set to true' do
124
+ expect(subject.evaluate({"exclude_spec" => true})[:exclude_spec]).to eq(true)
125
+ end
126
+ it "raises an error for non-boolean values" do
127
+ expect {
128
+ subject.evaluate({"exclude_spec" => 'invalid_string'})
129
+ }.to raise_error do |err|
130
+ expect(err.message).to match(/Validation failed for 'deploy' settings group/)
131
+ expect(err.errors.size).to eq 1
132
+ expect(err.errors[:exclude_spec]).to be_a_kind_of(ArgumentError)
133
+ expect(err.errors[:exclude_spec].message).to match(/`exclude_spec` can only be a boolean value, not 'invalid_string'/)
134
+ end
135
+ end
136
+ end
98
137
  describe "write_lock" do
99
138
  it "accepts a string with a reason for the write lock" do
100
139
  output = subject.evaluate("write_lock" => "No maintenance window active, code freeze till 2038-01-19")
@@ -250,8 +289,14 @@ describe R10K::Settings do
250
289
 
251
290
  describe "forge settings" do
252
291
  it "passes settings through to the forge settings" do
253
- output = subject.evaluate("forge" => {"baseurl" => "https://forge.tessier-ashpool.freeside", "proxy" => "https://proxy.tessier-ashpool.freesize:3128"})
254
- expect(output[:forge]).to eq(:baseurl => "https://forge.tessier-ashpool.freeside", :proxy => "https://proxy.tessier-ashpool.freesize:3128")
292
+ output = subject.evaluate("forge" => {"baseurl" => "https://forge.tessier-ashpool.freeside",
293
+ "proxy" => "https://proxy.tessier-ashpool.freesize:3128",
294
+ "authorization_token" => "faketoken",
295
+ "allow_puppetfile_override" => true})
296
+ expect(output[:forge]).to eq(:baseurl => "https://forge.tessier-ashpool.freeside",
297
+ :proxy => "https://proxy.tessier-ashpool.freesize:3128",
298
+ :authorization_token => "faketoken",
299
+ :allow_puppetfile_override => true)
255
300
  end
256
301
  end
257
302
  end