r10k 3.10.0 → 3.11.0
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 +4 -4
- data/.travis.yml +0 -10
- data/CHANGELOG.mkd +9 -0
- data/README.mkd +6 -0
- data/doc/dynamic-environments/configuration.mkd +14 -0
- data/doc/puppetfile.mkd +15 -1
- data/integration/Rakefile +2 -0
- data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +15 -13
- data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
- data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
- data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
- data/lib/r10k/action/deploy/environment.rb +6 -1
- data/lib/r10k/action/deploy/module.rb +31 -5
- data/lib/r10k/action/runner.rb +34 -4
- data/lib/r10k/cli/deploy.rb +4 -0
- data/lib/r10k/git.rb +3 -0
- data/lib/r10k/git/rugged/credentials.rb +77 -0
- data/lib/r10k/git/stateful_repository.rb +1 -0
- data/lib/r10k/initializers.rb +3 -0
- data/lib/r10k/module/base.rb +37 -0
- data/lib/r10k/module/forge.rb +1 -0
- data/lib/r10k/module/git.rb +1 -0
- data/lib/r10k/module/svn.rb +1 -0
- data/lib/r10k/module_loader/puppetfile.rb +15 -4
- data/lib/r10k/puppetfile.rb +10 -11
- data/lib/r10k/settings.rb +44 -2
- data/lib/r10k/settings/definition.rb +1 -1
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +106 -38
- data/r10k.gemspec +2 -0
- data/spec/unit/action/deploy/environment_spec.rb +16 -0
- data/spec/unit/action/deploy/module_spec.rb +178 -0
- data/spec/unit/action/runner_spec.rb +80 -0
- data/spec/unit/git/rugged/credentials_spec.rb +29 -0
- data/spec/unit/git/stateful_repository_spec.rb +5 -0
- data/spec/unit/module/base_spec.rb +46 -0
- data/spec/unit/module/forge_spec.rb +19 -0
- data/spec/unit/module/git_spec.rb +17 -0
- data/spec/unit/module/svn_spec.rb +18 -0
- data/spec/unit/module_loader/puppetfile_spec.rb +16 -3
- data/spec/unit/module_spec.rb +12 -1
- data/spec/unit/puppetfile_spec.rb +31 -1
- data/spec/unit/settings_spec.rb +18 -0
- metadata +16 -2
data/r10k.gemspec
CHANGED
@@ -36,6 +36,8 @@ Gem::Specification.new do |s|
|
|
36
36
|
s.add_dependency 'fast_gettext', '~> 1.1.0'
|
37
37
|
s.add_dependency 'gettext', ['>= 3.0.2', '< 3.3.0']
|
38
38
|
|
39
|
+
s.add_dependency 'jwt', '~> 2.2.3'
|
40
|
+
|
39
41
|
s.add_development_dependency 'rspec', '~> 3.1'
|
40
42
|
|
41
43
|
s.add_development_dependency 'rake'
|
@@ -47,6 +47,22 @@ describe R10K::Action::Deploy::Environment do
|
|
47
47
|
described_class.new({ 'oauth-token': '/nonexistent' }, [], {})
|
48
48
|
end
|
49
49
|
|
50
|
+
it 'can accept an app id option' do
|
51
|
+
described_class.new({ 'github-app-id': '/nonexistent' }, [], {})
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can accept a ttl option' do
|
55
|
+
described_class.new({ 'github-app-ttl': '/nonexistent' }, [], {})
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'can accept a ssl private key option' do
|
59
|
+
described_class.new({ 'github-app-key': '/nonexistent' }, [], {})
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'can accept a exclude-spec option' do
|
63
|
+
described_class.new({ :'exclude-spec' => true }, [], {})
|
64
|
+
end
|
65
|
+
|
50
66
|
describe "initializing errors" do
|
51
67
|
let (:settings) { { deploy: { purge_levels: [:environment],
|
52
68
|
purge_whitelist: ['coolfile', 'coolfile2'],
|
@@ -41,6 +41,22 @@ describe R10K::Action::Deploy::Module do
|
|
41
41
|
it 'can accept a token option' do
|
42
42
|
described_class.new({ 'oauth-token': '/nonexistent' }, [], {})
|
43
43
|
end
|
44
|
+
|
45
|
+
it 'can accept an app id option' do
|
46
|
+
described_class.new({ 'github-app-id': '/nonexistent' }, [], {})
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can accept a ttl option' do
|
50
|
+
described_class.new({ 'github-app-ttl': '/nonexistent' }, [], {})
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'can accept a ssl private key option' do
|
54
|
+
described_class.new({ 'github-app-key': '/nonexistent' }, [], {})
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can accept a exclude-spec option' do
|
58
|
+
described_class.new({ :'exclude-spec' => true }, [], {})
|
59
|
+
end
|
44
60
|
end
|
45
61
|
|
46
62
|
describe "with no-force" do
|
@@ -177,6 +193,33 @@ describe R10K::Action::Deploy::Module do
|
|
177
193
|
end
|
178
194
|
end
|
179
195
|
|
196
|
+
describe 'with github-app-id' do
|
197
|
+
|
198
|
+
subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-id': '/nonexistent' }, [], {}) }
|
199
|
+
|
200
|
+
it 'sets github-app-id' do
|
201
|
+
expect(subject.instance_variable_get(:@github_app_id)).to eq('/nonexistent')
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe 'with github-app-key' do
|
206
|
+
|
207
|
+
subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-key': '/nonexistent' }, [], {}) }
|
208
|
+
|
209
|
+
it 'sets github-app-key' do
|
210
|
+
expect(subject.instance_variable_get(:@github_app_key)).to eq('/nonexistent')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'with github-app-ttl' do
|
215
|
+
|
216
|
+
subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-ttl': '/nonexistent' }, [], {}) }
|
217
|
+
|
218
|
+
it 'sets github-app-ttl' do
|
219
|
+
expect(subject.instance_variable_get(:@github_app_ttl)).to eq('/nonexistent')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
180
223
|
describe 'with modules' do
|
181
224
|
|
182
225
|
subject { described_class.new({ config: '/some/nonexistent/path' }, ['mod1', 'mod2'], {}) }
|
@@ -306,5 +349,140 @@ describe R10K::Action::Deploy::Module do
|
|
306
349
|
subject.call
|
307
350
|
end
|
308
351
|
end
|
352
|
+
|
353
|
+
|
354
|
+
describe "postrun" do
|
355
|
+
let(:mock_config) do
|
356
|
+
R10K::Deployment::MockConfig.new(
|
357
|
+
:sources => {
|
358
|
+
:control => {
|
359
|
+
:type => :mock,
|
360
|
+
:basedir => '/some/nonexistent/path/control',
|
361
|
+
:environments => %w[first second third],
|
362
|
+
}
|
363
|
+
}
|
364
|
+
)
|
365
|
+
end
|
366
|
+
|
367
|
+
context "basic postrun hook" do
|
368
|
+
let(:settings) { { postrun: ["/path/to/executable", "arg1", "arg2"] } }
|
369
|
+
let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
|
370
|
+
|
371
|
+
before do
|
372
|
+
expect(R10K::Deployment).to receive(:new).and_return(deployment)
|
373
|
+
end
|
374
|
+
|
375
|
+
subject do
|
376
|
+
described_class.new({config: "/some/nonexistent/path" },
|
377
|
+
['mod1'], settings)
|
378
|
+
end
|
379
|
+
|
380
|
+
it "is passed to Subprocess" do
|
381
|
+
mock_subprocess = double
|
382
|
+
allow(mock_subprocess).to receive(:logger=)
|
383
|
+
expect(mock_subprocess).to receive(:execute)
|
384
|
+
|
385
|
+
expect(R10K::Util::Subprocess).to receive(:new).
|
386
|
+
with(["/path/to/executable", "arg1", "arg2"]).
|
387
|
+
and_return(mock_subprocess)
|
388
|
+
|
389
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
390
|
+
modified = subject.instance_variable_get(:@modified_envs) << environment
|
391
|
+
subject.instance_variable_set(:modified_envs, modified)
|
392
|
+
end.exactly(3).times
|
393
|
+
|
394
|
+
subject.call
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context "supports environments" do
|
399
|
+
context "with one environment" do
|
400
|
+
let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
|
401
|
+
let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
|
402
|
+
|
403
|
+
before do
|
404
|
+
expect(R10K::Deployment).to receive(:new).and_return(deployment)
|
405
|
+
end
|
406
|
+
|
407
|
+
subject do
|
408
|
+
described_class.new({ config: '/some/nonexistent/path',
|
409
|
+
environment: 'first' },
|
410
|
+
['mod1'], settings)
|
411
|
+
end
|
412
|
+
|
413
|
+
it "properly substitutes the environment" do
|
414
|
+
mock_subprocess = double
|
415
|
+
allow(mock_subprocess).to receive(:logger=)
|
416
|
+
expect(mock_subprocess).to receive(:execute)
|
417
|
+
|
418
|
+
mock_mod = double('mock_mod', name: 'mod1')
|
419
|
+
|
420
|
+
expect(R10K::Util::Subprocess).to receive(:new).
|
421
|
+
with(["/generate/types/wrapper", "first"]).
|
422
|
+
and_return(mock_subprocess)
|
423
|
+
|
424
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
425
|
+
if environment.name == 'first'
|
426
|
+
expect(environment).to receive(:deploy).and_return(true)
|
427
|
+
expect(environment).to receive(:modules).and_return([mock_mod])
|
428
|
+
end
|
429
|
+
original.call(environment, &block)
|
430
|
+
end.exactly(3).times
|
431
|
+
|
432
|
+
subject.call
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "with all environments" do
|
437
|
+
let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
|
438
|
+
let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
|
439
|
+
|
440
|
+
before do
|
441
|
+
expect(R10K::Deployment).to receive(:new).and_return(deployment)
|
442
|
+
end
|
443
|
+
|
444
|
+
subject do
|
445
|
+
described_class.new({ config: '/some/nonexistent/path' },
|
446
|
+
['mod1'], settings)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "properly substitutes the environment where modules were deployed" do
|
450
|
+
mock_subprocess = double
|
451
|
+
allow(mock_subprocess).to receive(:logger=)
|
452
|
+
expect(mock_subprocess).to receive(:execute)
|
453
|
+
|
454
|
+
expect(R10K::Util::Subprocess).to receive(:new).
|
455
|
+
with(["/generate/types/wrapper", "first third"]).
|
456
|
+
and_return(mock_subprocess)
|
457
|
+
|
458
|
+
mock_mod = double('mock_mod', name: 'mod1')
|
459
|
+
|
460
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
461
|
+
expect(environment).to receive(:deploy).and_return(true)
|
462
|
+
if ['first', 'third'].include?(environment.name)
|
463
|
+
expect(environment).to receive(:modules).and_return([mock_mod])
|
464
|
+
end
|
465
|
+
original.call(environment, &block)
|
466
|
+
end.exactly(3).times
|
467
|
+
|
468
|
+
subject.call
|
469
|
+
end
|
470
|
+
|
471
|
+
it "does not execute the command if no envs had the module" do
|
472
|
+
expect(R10K::Util::Subprocess).not_to receive(:new)
|
473
|
+
|
474
|
+
mock_mod2 = double('mock_mod', name: 'mod2')
|
475
|
+
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])
|
479
|
+
original.call(environment, &block)
|
480
|
+
end.exactly(3).times
|
481
|
+
|
482
|
+
subject.call
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
309
487
|
end
|
310
488
|
|
@@ -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',
|
@@ -79,6 +79,35 @@ describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby?
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
describe "generating github app tokens" do
|
83
|
+
it 'errors if app id has invalid characters' do
|
84
|
+
expect { subject.github_app_token("123A567890", "fake", "300")
|
85
|
+
}.to raise_error(R10K::Git::GitError, /App id contains invalid characters/)
|
86
|
+
end
|
87
|
+
it 'errors if app ttl has invalid characters' do
|
88
|
+
expect { subject.github_app_token("123456", "fake", "abc")
|
89
|
+
}.to raise_error(R10K::Git::GitError, /Github App token ttl contains/)
|
90
|
+
end
|
91
|
+
it 'errors if private file does not exist' do
|
92
|
+
R10K::Git.settings[:github_app_key] = "/missing/token/file"
|
93
|
+
expect(File).to receive(:readable?).with(R10K::Git.settings[:github_app_key]).and_return false
|
94
|
+
expect {
|
95
|
+
subject.github_app_token("123456", R10K::Git.settings[:github_app_key], "300")
|
96
|
+
}.to raise_error(R10K::Git::GitError, /App key is missing or unreadable/)
|
97
|
+
end
|
98
|
+
it 'errors if file is not a valid SSL key' do
|
99
|
+
token_file = Tempfile.new('token')
|
100
|
+
token_file.write('my_token')
|
101
|
+
token_file.close
|
102
|
+
R10K::Git.settings[:github_app_key] = token_file.path
|
103
|
+
expect(File).to receive(:readable?).with(token_file.path).and_return true
|
104
|
+
expect {
|
105
|
+
subject.github_app_token("123456", R10K::Git.settings[:github_app_key], "300")
|
106
|
+
}.to raise_error(R10K::Git::GitError, /App key is not a valid SSL key/)
|
107
|
+
token_file.unlink
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
82
111
|
describe "generating token credentials" do
|
83
112
|
it 'errors if token file does not exist' do
|
84
113
|
R10K::Git.settings[:oauth_token] = "/missing/token/file"
|
@@ -19,6 +19,11 @@ describe R10K::Git::StatefulRepository do
|
|
19
19
|
expect(subject.sync_cache?(ref)).to eq true
|
20
20
|
end
|
21
21
|
|
22
|
+
it "is true if the ref is HEAD" do
|
23
|
+
expect(cache).to receive(:exist?).and_return true
|
24
|
+
expect(subject.sync_cache?('HEAD')).to eq true
|
25
|
+
end
|
26
|
+
|
22
27
|
it "is true if the ref is unresolvable" do
|
23
28
|
expect(cache).to receive(:exist?).and_return true
|
24
29
|
expect(cache).to receive(:ref_type).with('0.9.x').and_return(:unknown)
|
@@ -28,6 +28,52 @@ describe R10K::Module::Base do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
describe 'deleting the spec dir' do
|
32
|
+
let(:module_org) { "coolorg" }
|
33
|
+
let(:module_name) { "coolmod" }
|
34
|
+
let(:title) { "#{module_org}-#{module_name}" }
|
35
|
+
let(:dirname) { Pathname.new(Dir.mktmpdir) }
|
36
|
+
let(:spec_path) { dirname + module_name + 'spec' }
|
37
|
+
|
38
|
+
before(:each) do
|
39
|
+
logger = double("logger")
|
40
|
+
allow_any_instance_of(described_class).to receive(:logger).and_return(logger)
|
41
|
+
allow(logger).to receive(:debug2).with(any_args)
|
42
|
+
allow(logger).to receive(:info).with(any_args)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does not remove the spec directory by default' do
|
46
|
+
FileUtils.mkdir_p(spec_path)
|
47
|
+
m = described_class.new(title, dirname, {})
|
48
|
+
m.maybe_delete_spec_dir
|
49
|
+
expect(Dir.exist?(spec_path)).to eq true
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'detects a symlink and deletes the target' do
|
53
|
+
Dir.mkdir(dirname + module_name)
|
54
|
+
target_dir = Dir.mktmpdir
|
55
|
+
FileUtils.ln_s(target_dir, spec_path)
|
56
|
+
m = described_class.new(title, dirname, {exclude_spec: true})
|
57
|
+
m.maybe_delete_spec_dir
|
58
|
+
expect(Dir.exist?(target_dir)).to eq false
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'removes the spec directory if exclude_spec is set' do
|
62
|
+
FileUtils.mkdir_p(spec_path)
|
63
|
+
m = described_class.new(title, dirname, {exclude_spec: true})
|
64
|
+
m.maybe_delete_spec_dir
|
65
|
+
expect(Dir.exist?(spec_path)).to eq false
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'does not remove the spec directory if spec_deletable is false' do
|
69
|
+
FileUtils.mkdir_p(spec_path)
|
70
|
+
m = described_class.new(title, dirname, {})
|
71
|
+
m.spec_deletable = false
|
72
|
+
m.maybe_delete_spec_dir
|
73
|
+
expect(Dir.exist?(spec_path)).to eq true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
31
77
|
describe "path variables" do
|
32
78
|
it "uses the module name as the name" do
|
33
79
|
m = described_class.new('eight_hundred', '/moduledir', [])
|
@@ -78,6 +78,7 @@ describe R10K::Module::Forge do
|
|
78
78
|
allow_any_instance_of(described_class).to receive(:logger).and_return(logger_dbl)
|
79
79
|
|
80
80
|
allow(logger_dbl).to receive(:info).with(/Deploying module to.*/)
|
81
|
+
allow(logger_dbl).to receive(:debug2).with(/No spec dir detected/)
|
81
82
|
expect(logger_dbl).to receive(:warn).with(/puppet forge module.*puppetlabs-corosync.*has been deprecated/i)
|
82
83
|
|
83
84
|
subject.sync
|
@@ -90,6 +91,7 @@ describe R10K::Module::Forge do
|
|
90
91
|
allow_any_instance_of(described_class).to receive(:logger).and_return(logger_dbl)
|
91
92
|
|
92
93
|
allow(logger_dbl).to receive(:info).with(/Deploying module to.*/)
|
94
|
+
allow(logger_dbl).to receive(:debug2).with(/No spec dir detected/)
|
93
95
|
expect(logger_dbl).to_not receive(:warn).with(/puppet forge module.*puppetlabs-corosync.*has been deprecated/i)
|
94
96
|
|
95
97
|
subject.sync
|
@@ -165,6 +167,23 @@ describe R10K::Module::Forge do
|
|
165
167
|
describe "#sync" do
|
166
168
|
subject { described_class.new('branan/eight_hundred', fixture_modulepath, { version: '8.0.0' }) }
|
167
169
|
|
170
|
+
context "syncing the repo" do
|
171
|
+
let(:module_org) { "coolorg" }
|
172
|
+
let(:module_name) { "coolmod" }
|
173
|
+
let(:title) { "#{module_org}-#{module_name}" }
|
174
|
+
let(:dirname) { Pathname.new(Dir.mktmpdir) }
|
175
|
+
let(:spec_path) { dirname + module_name + 'spec' }
|
176
|
+
subject { described_class.new(title, dirname, {}) }
|
177
|
+
|
178
|
+
it 'defaults to keeping the spec dir' do
|
179
|
+
FileUtils.mkdir_p(spec_path)
|
180
|
+
expect(subject).to receive(:status).and_return(:absent)
|
181
|
+
expect(subject).to receive(:install)
|
182
|
+
subject.sync
|
183
|
+
expect(Dir.exist?(spec_path)).to eq true
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
168
187
|
it 'does nothing when the module is in sync' do
|
169
188
|
allow(subject).to receive(:status).and_return :insync
|
170
189
|
|