r10k 3.15.0 → 3.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.mkd +9 -0
  3. data/CODEOWNERS +2 -2
  4. data/README.mkd +11 -0
  5. data/doc/dynamic-environments/configuration.mkd +65 -1
  6. data/lib/r10k/action/puppetfile/install.rb +2 -1
  7. data/lib/r10k/cli/puppetfile.rb +1 -0
  8. data/lib/r10k/module_loader/puppetfile.rb +10 -1
  9. data/lib/r10k/version.rb +1 -1
  10. data/r10k.gemspec +1 -1
  11. metadata +2 -151
  12. data/spec/fixtures/empty/.empty +0 -0
  13. data/spec/fixtures/integration/git/puppet-boolean-bare.tar +0 -0
  14. data/spec/fixtures/module/forge/bad_module/metadata.json +0 -1
  15. data/spec/fixtures/module/forge/eight_hundred/Modulefile +0 -8
  16. data/spec/fixtures/module/forge/eight_hundred/metadata.json +0 -19
  17. data/spec/fixtures/tarball/tarball.tar.gz +0 -0
  18. data/spec/fixtures/unit/action/r10k.yaml +0 -5
  19. data/spec/fixtures/unit/action/r10k_cachedir.yaml +0 -2
  20. data/spec/fixtures/unit/action/r10k_creds.yaml +0 -9
  21. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +0 -4
  22. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +0 -3
  23. data/spec/fixtures/unit/action/r10k_generate_types.yaml +0 -3
  24. data/spec/fixtures/unit/action/r10k_logging.yaml +0 -12
  25. data/spec/fixtures/unit/action/r10k_puppet_path.yaml +0 -3
  26. data/spec/fixtures/unit/puppetfile/argument-error/Puppetfile +0 -1
  27. data/spec/fixtures/unit/puppetfile/default-branch-override/Puppetfile +0 -5
  28. data/spec/fixtures/unit/puppetfile/duplicate-module-error/Puppetfile +0 -10
  29. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +0 -8
  30. data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +0 -1
  31. data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +0 -1
  32. data/spec/fixtures/unit/puppetfile/name-error/Puppetfile +0 -1
  33. data/spec/fixtures/unit/puppetfile/valid-forge-with-version/Puppetfile +0 -1
  34. data/spec/fixtures/unit/puppetfile/valid-forge-without-version/Puppetfile +0 -1
  35. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +0 -10
  36. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +0 -10
  37. data/spec/fixtures/unit/puppetfile/various-modules/modules/apt/.gitkeep +0 -1
  38. data/spec/fixtures/unit/puppetfile/various-modules/modules/baz/.gitkeep +0 -1
  39. data/spec/fixtures/unit/puppetfile/various-modules/modules/buzz/.gitkeep +0 -1
  40. data/spec/fixtures/unit/puppetfile/various-modules/modules/canary/.gitkeep +0 -1
  41. data/spec/fixtures/unit/puppetfile/various-modules/modules/fizz/.gitkeep +0 -1
  42. data/spec/fixtures/unit/puppetfile/various-modules/modules/rpm/.gitkeep +0 -1
  43. data/spec/fixtures/unit/util/purgeable/managed_one/expected_1 +0 -0
  44. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file +0 -1
  45. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_allowlisted_2/ignored_1 +0 -0
  46. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_expected_1 +0 -0
  47. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_unmanaged_1 +0 -0
  48. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/unmanaged_symlink_dir +0 -1
  49. data/spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir +0 -1
  50. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_1 +0 -0
  51. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_symlink_file +0 -1
  52. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  53. data/spec/fixtures/unit/util/purgeable/managed_two/expected_2 +0 -0
  54. data/spec/fixtures/unit/util/purgeable/managed_two/unmanaged_2 +0 -0
  55. data/spec/fixtures/unit/util/subprocess/runner/no-execute.sh +0 -3
  56. data/spec/integration/git/rugged/bare_repository_spec.rb +0 -13
  57. data/spec/integration/git/rugged/cache_spec.rb +0 -33
  58. data/spec/integration/git/rugged/thin_repository_spec.rb +0 -14
  59. data/spec/integration/git/rugged/working_repository_spec.rb +0 -48
  60. data/spec/integration/git/shellgit/bare_repository_spec.rb +0 -13
  61. data/spec/integration/git/shellgit/thin_repository_spec.rb +0 -14
  62. data/spec/integration/git/shellgit/working_repository_spec.rb +0 -13
  63. data/spec/integration/git/stateful_repository_spec.rb +0 -175
  64. data/spec/integration/util/purageable_spec.rb +0 -41
  65. data/spec/matchers/exit_with.rb +0 -28
  66. data/spec/matchers/match_realpath.rb +0 -18
  67. data/spec/r10k-mocks/mock_config.rb +0 -33
  68. data/spec/r10k-mocks/mock_env.rb +0 -18
  69. data/spec/r10k-mocks/mock_source.rb +0 -17
  70. data/spec/r10k-mocks.rb +0 -3
  71. data/spec/shared-contexts/git-fixtures.rb +0 -55
  72. data/spec/shared-contexts/tarball.rb +0 -32
  73. data/spec/shared-examples/deploy-actions.rb +0 -69
  74. data/spec/shared-examples/git/bare_repository.rb +0 -132
  75. data/spec/shared-examples/git/thin_repository.rb +0 -26
  76. data/spec/shared-examples/git/working_repository.rb +0 -207
  77. data/spec/shared-examples/git-repository.rb +0 -38
  78. data/spec/shared-examples/puppetfile-action.rb +0 -39
  79. data/spec/shared-examples/settings/ancestry.rb +0 -44
  80. data/spec/shared-examples/subprocess-runner.rb +0 -89
  81. data/spec/spec_helper.rb +0 -41
  82. data/spec/unit/action/cri_runner_spec.rb +0 -72
  83. data/spec/unit/action/deploy/deploy_helpers_spec.rb +0 -38
  84. data/spec/unit/action/deploy/display_spec.rb +0 -61
  85. data/spec/unit/action/deploy/environment_spec.rb +0 -640
  86. data/spec/unit/action/deploy/module_spec.rb +0 -476
  87. data/spec/unit/action/puppetfile/check_spec.rb +0 -53
  88. data/spec/unit/action/puppetfile/cri_runner_spec.rb +0 -47
  89. data/spec/unit/action/puppetfile/install_spec.rb +0 -112
  90. data/spec/unit/action/puppetfile/purge_spec.rb +0 -60
  91. data/spec/unit/action/runner_spec.rb +0 -407
  92. data/spec/unit/action/visitor_spec.rb +0 -39
  93. data/spec/unit/cli_spec.rb +0 -9
  94. data/spec/unit/deployment/config_spec.rb +0 -33
  95. data/spec/unit/deployment_spec.rb +0 -162
  96. data/spec/unit/environment/bare_spec.rb +0 -13
  97. data/spec/unit/environment/base_spec.rb +0 -122
  98. data/spec/unit/environment/git_spec.rb +0 -114
  99. data/spec/unit/environment/name_spec.rb +0 -181
  100. data/spec/unit/environment/plain_spec.rb +0 -8
  101. data/spec/unit/environment/svn_spec.rb +0 -146
  102. data/spec/unit/environment/tarball_spec.rb +0 -45
  103. data/spec/unit/environment/with_modules_spec.rb +0 -122
  104. data/spec/unit/errors/formatting_spec.rb +0 -84
  105. data/spec/unit/feature_spec.rb +0 -50
  106. data/spec/unit/forge/module_release_spec.rb +0 -213
  107. data/spec/unit/git/alternates_spec.rb +0 -116
  108. data/spec/unit/git/cache_spec.rb +0 -66
  109. data/spec/unit/git/rugged/cache_spec.rb +0 -48
  110. data/spec/unit/git/rugged/credentials_spec.rb +0 -215
  111. data/spec/unit/git/shellgit/cache_spec.rb +0 -27
  112. data/spec/unit/git/stateful_repository_spec.rb +0 -45
  113. data/spec/unit/git_spec.rb +0 -102
  114. data/spec/unit/initializers_spec.rb +0 -68
  115. data/spec/unit/instance_cache_spec.rb +0 -78
  116. data/spec/unit/keyed_factory_spec.rb +0 -51
  117. data/spec/unit/logging/terminaloutputter_spec.rb +0 -53
  118. data/spec/unit/logging_spec.rb +0 -68
  119. data/spec/unit/module/base_spec.rb +0 -118
  120. data/spec/unit/module/forge_spec.rb +0 -271
  121. data/spec/unit/module/git_spec.rb +0 -387
  122. data/spec/unit/module/metadata_file_spec.rb +0 -68
  123. data/spec/unit/module/svn_spec.rb +0 -208
  124. data/spec/unit/module/tarball_spec.rb +0 -70
  125. data/spec/unit/module_loader/puppetfile_spec.rb +0 -421
  126. data/spec/unit/module_spec.rb +0 -114
  127. data/spec/unit/puppetfile_spec.rb +0 -304
  128. data/spec/unit/settings/collection_spec.rb +0 -123
  129. data/spec/unit/settings/container_spec.rb +0 -92
  130. data/spec/unit/settings/definition_spec.rb +0 -79
  131. data/spec/unit/settings/enum_definition_spec.rb +0 -20
  132. data/spec/unit/settings/inheritance_spec.rb +0 -38
  133. data/spec/unit/settings/list_spec.rb +0 -88
  134. data/spec/unit/settings/loader_spec.rb +0 -110
  135. data/spec/unit/settings/uri_definition_spec.rb +0 -23
  136. data/spec/unit/settings_spec.rb +0 -303
  137. data/spec/unit/source/base_spec.rb +0 -31
  138. data/spec/unit/source/exec_spec.rb +0 -81
  139. data/spec/unit/source/git_spec.rb +0 -233
  140. data/spec/unit/source/hash_spec.rb +0 -54
  141. data/spec/unit/source/svn_spec.rb +0 -196
  142. data/spec/unit/source/yaml_spec.rb +0 -42
  143. data/spec/unit/source_spec.rb +0 -10
  144. data/spec/unit/svn/remote_spec.rb +0 -21
  145. data/spec/unit/svn/working_dir_spec.rb +0 -56
  146. data/spec/unit/tarball_spec.rb +0 -57
  147. data/spec/unit/util/attempt_spec.rb +0 -82
  148. data/spec/unit/util/cacheable_spec.rb +0 -23
  149. data/spec/unit/util/commands_spec.rb +0 -61
  150. data/spec/unit/util/downloader_spec.rb +0 -98
  151. data/spec/unit/util/exec_env_spec.rb +0 -56
  152. data/spec/unit/util/purgeable_spec.rb +0 -267
  153. data/spec/unit/util/setopts_spec.rb +0 -83
  154. data/spec/unit/util/subprocess/result_spec.rb +0 -36
  155. data/spec/unit/util/subprocess/runner/posix_spec.rb +0 -7
  156. data/spec/unit/util/subprocess/runner/pump_spec.rb +0 -79
  157. data/spec/unit/util/subprocess/runner/windows_spec.rb +0 -7
  158. data/spec/unit/util/subprocess/subprocess_error_spec.rb +0 -26
  159. data/spec/unit/util/subprocess_spec.rb +0 -65
  160. data/spec/unit/util/symbolize_keys_spec.rb +0 -67
@@ -1,82 +0,0 @@
1
- require 'spec_helper'
2
- require 'r10k/util/attempt'
3
-
4
- describe R10K::Util::Attempt do
5
-
6
- describe "with a single truthy value" do
7
- subject(:attempt) { described_class.new("hello") }
8
-
9
- it "invokes the next action with the value" do
10
- value = nil
11
- attempt.try { |inner| value = inner }
12
- attempt.run
13
- expect(attempt).to be_ok
14
- expect(value).to eq "hello"
15
- end
16
-
17
- it "returns the resulting value from the block" do
18
- attempt.try { |inner| inner + " world" }
19
- result = attempt.run
20
- expect(attempt).to be_ok
21
- expect(result).to eq "hello world"
22
- end
23
- end
24
-
25
- describe "with a false value" do
26
- subject(:attempt) { described_class.new(nil) }
27
-
28
- it "does not evaluate the block" do
29
- value = "outside of block"
30
- attempt.try { |inner| value = "ran block" }
31
- attempt.run
32
- expect(attempt).to be_ok
33
- expect(value).to eq "outside of block"
34
- end
35
-
36
- it "does not continue execution" do
37
- attempt.try { |_| "something" }.try { raise }
38
- expect(attempt.run).to be_nil
39
- end
40
- end
41
-
42
- describe "with an array" do
43
- subject(:attempt) { described_class.new([1, 2, 3, 4, 5]) }
44
-
45
- it "runs the block for each element in the array" do
46
- sum = 0
47
- attempt.try { |inner| sum += inner }
48
- attempt.run
49
- expect(attempt).to be_ok
50
- expect(sum).to eq 15
51
- end
52
-
53
- it "returns the result of the operation on each array member" do
54
- sum = 0
55
- attempt.try { |inner| sum += inner }
56
- result = attempt.run
57
- expect(result).to eq([1, 3, 6, 10, 15])
58
- end
59
- end
60
-
61
- describe "when an exception is raised" do
62
- subject(:attempt) { described_class.new("initial") }
63
-
64
- it "returns the exception" do
65
- attempt.try { |_| raise RuntimeError }
66
- result = attempt.run
67
- expect(attempt).to_not be_ok
68
- expect(result).to be_a_kind_of RuntimeError
69
- end
70
-
71
- it "does not continue execution" do
72
- attempt.try { |_| raise RuntimeError }.try { |_| "This should not be run" }
73
- result = attempt.run
74
- expect(result).to be_a_kind_of RuntimeError
75
- end
76
-
77
- it "only rescues descendants of StandardError" do
78
- attempt.try { |_| raise Exception }
79
- expect { attempt.run }.to raise_error(Exception)
80
- end
81
- end
82
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
- require 'r10k/util/cacheable'
3
-
4
- RSpec.describe R10K::Util::Cacheable do
5
-
6
- subject { Object.new.extend(R10K::Util::Cacheable) }
7
-
8
- describe "dirname sanitization" do
9
- let(:input) { 'https://some/git/remote' }
10
-
11
- it 'sanitizes URL to directory name' do
12
- expect(subject.sanitized_dirname(input)).to eq('https---some-git-remote')
13
- end
14
-
15
- context 'with username and password' do
16
- let(:input) { 'https://"user:pa$$w0rd:@authenticated/git/remote' }
17
-
18
- it 'sanitizes authenticated URL to directory name' do
19
- expect(subject.sanitized_dirname(input)).to eq('https---authenticated-git-remote')
20
- end
21
- end
22
- end
23
- end
@@ -1,61 +0,0 @@
1
- require 'r10k/util/commands'
2
- require 'r10k/util/exec_env'
3
-
4
- require 'tmpdir'
5
-
6
- describe R10K::Util::Commands do
7
- describe "#which" do
8
-
9
- before do
10
- allow(File).to receive(:executable?).and_return false
11
- allow(File).to receive(:file?).and_return false
12
- end
13
-
14
- def stub_executable(exe)
15
- allow(File).to receive(:executable?).with(exe).and_return true
16
- allow(File).to receive(:file?).with(exe).and_return true
17
- end
18
-
19
- describe "when ENV['PATHEXT'] is unset" do
20
- let(:path) { Dir.mktmpdir }
21
-
22
- around(:each) do |example|
23
- R10K::Util::ExecEnv.withenv('PATHEXT' => nil, 'PATH' => path) do
24
- example.run
25
- end
26
- end
27
-
28
- it "returns the first matching command in PATH" do
29
- exe = File.join(path, 'git')
30
- stub_executable(exe)
31
- expect(described_class.which("git")).to eq exe
32
- end
33
-
34
- it "returns nil if the command could not be found" do
35
- exe = File.join(path, 'git')
36
- expect(described_class.which("git")).to be_nil
37
- end
38
- end
39
-
40
- describe "when ENV['PATHEXT'] is set" do
41
- let(:path) { Dir.mktmpdir }
42
-
43
- around(:each) do |example|
44
- R10K::Util::ExecEnv.withenv('PATHEXT' => '.bat;.exe;.cmd', 'PATH' => path) do
45
- example.run
46
- end
47
- end
48
-
49
- it "returns the first matching command in PATH" do
50
- exe = File.join(path, 'git.exe')
51
- stub_executable(exe)
52
- expect(described_class.which("git")).to eq exe
53
- end
54
-
55
- it "returns nil if the command could not be found" do
56
- exe = File.join(path, 'git.exe')
57
- expect(described_class.which("git")).to be_nil
58
- end
59
- end
60
- end
61
- end
@@ -1,98 +0,0 @@
1
- require 'spec_helper'
2
- require 'r10k/util/downloader'
3
-
4
- describe R10K::Util::Downloader do
5
-
6
- subject(:downloader) do
7
- subj = Object.new
8
- subj.extend(R10K::Util::Downloader)
9
- subj.singleton_class.class_eval { public :download }
10
- subj.singleton_class.class_eval { public :http_get }
11
- subj.singleton_class.class_eval { public :file_digest }
12
- subj
13
- end
14
-
15
- let(:tmpdir) { Dir.mktmpdir }
16
- after(:each) { FileUtils.remove_entry_secure(tmpdir) }
17
-
18
- describe 'http_get' do
19
- let(:src_url) { 'https://example.com' }
20
- let(:dst_file) { File.join(tmpdir, 'test.out') }
21
- let(:tarball_uri) { URI('http://tarball.example.com/tarball.tar.gz') }
22
- let(:redirect_uri) { URI('http://redirect.example.com/redirect') }
23
- let(:proxy_uri) { URI('http://user:password@proxy.example.com') }
24
-
25
- it 'downloads a simple file' do
26
- mock_session = instance_double('Net::HTTP', active?: true)
27
- tarball_response = instance_double('Net::HTTPSuccess')
28
-
29
- expect(Net::HTTP).to receive(:new).with(tarball_uri.host, any_args).and_return(mock_session)
30
- expect(Net::HTTPSuccess).to receive(:===).with(tarball_response).and_return(true)
31
-
32
- expect(mock_session).to receive(:request_get).and_yield(tarball_response)
33
- expect(mock_session).to receive(:start).once
34
- expect(mock_session).to receive(:finish).once
35
-
36
- expect { |b| downloader.http_get(tarball_uri, &b) }.to yield_with_args(tarball_response)
37
- end
38
-
39
- it 'follows redirects' do
40
- mock_session_1 = instance_double('Net::HTTP', active?: false)
41
- mock_session_2 = instance_double('Net::HTTP', active?: true)
42
- redirect_response = instance_double('Net::HTTPRedirection')
43
- tarball_response = instance_double('Net::HTTPSuccess')
44
-
45
- expect(Net::HTTP).to receive(:new).with(redirect_uri.host, any_args).and_return(mock_session_1).once
46
- expect(Net::HTTP).to receive(:new).with(tarball_uri.host, any_args).and_return(mock_session_2).once
47
- expect(Net::HTTPRedirection).to receive(:===).with(redirect_response).and_return(true)
48
- expect(Net::HTTPSuccess).to receive(:===).with(tarball_response).and_return(true)
49
- allow(Net::HTTPRedirection).to receive(:===).and_call_original
50
-
51
- expect(mock_session_1).to receive(:request_get).and_yield(redirect_response)
52
- expect(mock_session_2).to receive(:request_get).and_yield(tarball_response)
53
-
54
- # The redirect response should be queried for the redirect location
55
- expect(redirect_response).to receive(:[]).with('location').and_return(tarball_uri.to_s)
56
-
57
- # Both sessions should start and finish cleanly
58
- expect(mock_session_1).to receive(:start).once
59
- expect(mock_session_1).to receive(:finish).once
60
- expect(mock_session_2).to receive(:start).once
61
- expect(mock_session_2).to receive(:finish).once
62
-
63
- expect { |b| downloader.http_get(redirect_uri, &b) }.to yield_with_args(tarball_response)
64
- end
65
-
66
- it 'can use a proxy' do
67
- mock_session = instance_double('Net::HTTP', active?: true)
68
-
69
- expect(Net::HTTP).to receive(:new)
70
- .with(tarball_uri.host,
71
- tarball_uri.port,
72
- proxy_uri.host,
73
- proxy_uri.port,
74
- proxy_uri.user,
75
- proxy_uri.password,
76
- any_args)
77
- .and_return(mock_session)
78
-
79
- expect(mock_session).to receive(:request_get).and_return(:not_yielded)
80
- expect(mock_session).to receive(:start).once
81
- expect(mock_session).to receive(:finish).once
82
-
83
- downloader.http_get(tarball_uri, proxy: proxy_uri)
84
- end
85
- end
86
-
87
- describe 'checksums' do
88
- let(:fixture_checksum) { '0bcea17aa0c5e868c18f0fa042feda770e47c1a4223229f82116ccb3ca33c6e3' }
89
- let(:fixture_tarball) do
90
- File.expand_path('spec/fixtures/integration/git/puppet-boolean-bare.tar', PROJECT_ROOT)
91
- end
92
-
93
- it 'checksums files' do
94
- expect(downloader.file_digest(fixture_tarball)).to eql(fixture_checksum)
95
- end
96
- end
97
- end
98
-
@@ -1,56 +0,0 @@
1
- require 'r10k/util/exec_env'
2
-
3
- describe R10K::Util::ExecEnv do
4
- describe "withenv" do
5
- it "adds the keys to the environment during the block" do
6
- val = nil
7
- described_class.withenv('VAL' => 'something') do
8
- val = ENV['VAL']
9
- end
10
- expect(val).to eq 'something'
11
- end
12
-
13
- it "doesn't modify values that were not modified by the passed hash" do
14
- origpath = ENV['PATH']
15
- path = nil
16
- described_class.withenv('VAL' => 'something') do
17
- path = ENV['PATH']
18
- end
19
- expect(path).to eq origpath
20
- end
21
-
22
- it "removes new values after the block" do
23
- val = nil
24
- described_class.withenv('VAL' => 'something') { }
25
- expect(ENV['VAL']).to be_nil
26
- end
27
-
28
- it "restores old values after the block" do
29
- path = ENV['PATH']
30
- described_class.withenv('PATH' => '/usr/bin') { }
31
- expect(ENV['PATH']).to eq path
32
- end
33
- end
34
-
35
- describe "reset" do
36
-
37
- after { ENV.delete('VAL') }
38
-
39
- it "replaces environment keys with the specified keys" do
40
- ENV['VAL'] = 'hi'
41
-
42
- newenv = ENV.to_hash
43
- newenv['VAL'] = 'bye'
44
-
45
- described_class.reset(newenv)
46
- expect(ENV['VAL']).to eq 'bye'
47
- end
48
-
49
- it "removes any keys that were not provided" do
50
- env = ENV.to_hash
51
- ENV['VAL'] = 'hi'
52
- described_class.reset(env)
53
- expect(ENV['VAL']).to be_nil
54
- end
55
- end
56
- end
@@ -1,267 +0,0 @@
1
- require 'spec_helper'
2
- require 'r10k/util/purgeable'
3
- require 'r10k/util/cleaner'
4
-
5
- RSpec.describe R10K::Util::Purgeable do
6
- let(:managed_directories) do
7
- [
8
- 'spec/fixtures/unit/util/purgeable/managed_one',
9
- 'spec/fixtures/unit/util/purgeable/managed_two',
10
- ]
11
- end
12
-
13
- let(:desired_contents) do
14
- [
15
- 'spec/fixtures/unit/util/purgeable/managed_one/expected_1',
16
- 'spec/fixtures/unit/util/purgeable/managed_one/new_1',
17
- 'spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1',
18
- 'spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir',
19
- 'spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_expected_1',
20
- 'spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_new_1',
21
- 'spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file',
22
- 'spec/fixtures/unit/util/purgeable/managed_two/expected_2',
23
- 'spec/fixtures/unit/util/purgeable/managed_two/new_2',
24
- 'spec/fixtures/unit/util/purgeable/managed_two/.hidden',
25
- ]
26
- end
27
-
28
- subject { R10K::Util::Cleaner.new(managed_directories, desired_contents) }
29
-
30
- context 'without recurse option' do
31
- let(:recurse) { false }
32
-
33
- describe '#current_contents' do
34
- it 'collects direct contents of all managed directories' do
35
- expect(subject.current_contents(recurse)).to contain_exactly(/\/expected_1/, /\/expected_2/, /\/unmanaged_1/, /\/unmanaged_2/,
36
- /\/managed_subdir_1/, /\/managed_symlink_dir/, /\/unmanaged_symlink_file/)
37
- end
38
- end
39
-
40
- describe '#pending_contents' do
41
- it 'collects desired_contents that do not yet exist' do
42
- expect(subject.pending_contents(recurse)).to include(/\/new_1/, /\/new_2/)
43
- end
44
- end
45
-
46
- describe '#stale_contents' do
47
- context 'with no whitelist or exclusions' do
48
- let(:exclusions) { [] }
49
- let(:whitelist) { [] }
50
-
51
- it 'collects current_contents that should not exist' do
52
- expect(subject.stale_contents(recurse, exclusions, whitelist)).to contain_exactly(/\/unmanaged_1/, /\/unmanaged_2/, /\/unmanaged_symlink_file/)
53
- end
54
- end
55
-
56
- context 'with whitelisted items' do
57
- let(:exclusions) { [] }
58
- let(:whitelist) { ['**/unmanaged_1'] }
59
-
60
- it 'collects current_contents that should not exist except whitelisted items' do
61
- expect(subject.logger).to receive(:debug).with(/unmanaged_1.*whitelist match/i)
62
- expect(subject.stale_contents(recurse, exclusions, whitelist)).to contain_exactly(/\/unmanaged_2/, /\/unmanaged_symlink_file/)
63
- end
64
- end
65
-
66
- context 'with excluded items' do
67
- let(:exclusions) { ['**/unmanaged_2'] }
68
- let(:whitelist) { [] }
69
-
70
- it 'collects current_contents that should not exist except excluded items' do
71
- expect(subject.logger).to receive(:debug2).with(/unmanaged_2.*internal exclusion match/i)
72
- expect(subject.stale_contents(recurse, exclusions, whitelist)).to contain_exactly(/\/unmanaged_1/, /\/unmanaged_symlink_file/)
73
- end
74
- end
75
- end
76
-
77
- describe '#purge!' do
78
- let(:exclusions) { [] }
79
- let(:whitelist) { [] }
80
- let(:purge_opts) { { recurse: recurse, whitelist: whitelist } }
81
-
82
- it 'does nothing when there is no stale_contents' do
83
- allow(subject).to receive(:stale_contents).and_return([])
84
-
85
- expect(FileUtils).to_not receive(:rm_rf)
86
-
87
- subject.purge!(purge_opts)
88
- end
89
-
90
- it 'recursively deletes all stale_contents' do
91
- subject.stale_contents(recurse, exclusions, whitelist).each do |stale|
92
- expect(FileUtils).to receive(:rm_r).with(stale, hash_including(secure: true))
93
- end
94
-
95
- subject.purge!(purge_opts)
96
- end
97
- end
98
- end
99
-
100
- context 'with recurse option' do
101
- let(:recurse) { true }
102
-
103
- describe '#current_contents' do
104
- it 'collects contents of all managed directories recursively' do
105
- expect(subject.current_contents(recurse)).
106
- to contain_exactly(/\/expected_1/, /\/expected_2/,
107
- /\/unmanaged_1/, /\/unmanaged_2/,
108
- /\/managed_symlink_dir/,
109
- /\/unmanaged_symlink_file/,
110
- /\/managed_subdir_1/,
111
- /\/subdir_expected_1/, /\/subdir_unmanaged_1/,
112
- /\/managed_symlink_file/,
113
- /\/unmanaged_symlink_dir/,
114
- /\/subdir_allowlisted_2/, /\/ignored_1/,
115
- /\/\.hidden/)
116
- end
117
- end
118
-
119
- describe '#pending_contents' do
120
- it 'collects desired_contents that do not yet exist recursively' do
121
- expect(subject.pending_contents(recurse)).to include(/\/new_1/, /\/new_2/, /\/subdir_new_1/)
122
- end
123
- end
124
-
125
- describe '#stale_contents' do
126
- context 'with no whitelist or exclusions' do
127
- let(:exclusions) { [] }
128
- let(:whitelist) { [] }
129
-
130
- it 'collects current_contents that should not exist recursively' do
131
- expect(subject.stale_contents(recurse, exclusions, whitelist)).
132
- to contain_exactly(/\/unmanaged_1/, /\/unmanaged_2/, /\/unmanaged_symlink_file/, /\/subdir_unmanaged_1/,
133
- /\/ignored_1/, /\/subdir_allowlisted_2/, /\/unmanaged_symlink_dir/)
134
- end
135
- end
136
-
137
- context 'with whitelisted items' do
138
- let(:exclusions) { [] }
139
- let(:whitelist) { ['**/unmanaged_1'] }
140
-
141
- it 'collects current_contents that should not exist except whitelisted items' do
142
- expect(subject.logger).to receive(:debug).with(/unmanaged_1.*whitelist match/i)
143
-
144
- expect(subject.stale_contents(recurse, exclusions, whitelist)).
145
- to contain_exactly(/\/unmanaged_2/, /\/subdir_unmanaged_1/, /\/unmanaged_symlink_file/, /\/ignored_1/,
146
- /\/subdir_allowlisted_2/, /\/unmanaged_symlink_dir/)
147
- end
148
-
149
- it 'does not collect contents that match recursive globbed whitelist items as intermediate values' do
150
- recursive_whitelist = ['**/managed_subdir_1/**/*']
151
- expect(subject.logger).not_to receive(:debug).with(/ignored_1/)
152
-
153
- expect(subject.stale_contents(recurse, exclusions, recursive_whitelist)).
154
- to contain_exactly(/\/unmanaged_2/, /\/managed_one\/unmanaged_1/, /\/managed_one\/unmanaged_symlink_file/)
155
- end
156
- end
157
-
158
- context 'with excluded items' do
159
- let(:exclusions) { ['**/unmanaged_2'] }
160
- let(:whitelist) { [] }
161
-
162
- it 'collects current_contents that should not exist except excluded items' do
163
- expect(subject.logger).to receive(:debug2).with(/unmanaged_2.*internal exclusion match/i)
164
-
165
- expect(subject.stale_contents(recurse, exclusions, whitelist)).
166
- to contain_exactly(/\/unmanaged_1/, /\/unmanaged_symlink_file/, /\/subdir_unmanaged_1/, /\/ignored_1/,
167
- /\/subdir_allowlisted_2/, /\/unmanaged_symlink_dir/)
168
- end
169
-
170
- it 'does not collect contents that match recursive globbed exclusion items as intermediate values' do
171
- recursive_exclusions = ['**/managed_subdir_1/**/*']
172
- expect(subject.logger).not_to receive(:debug).with(/ignored_1/)
173
-
174
- expect(subject.stale_contents(recurse, recursive_exclusions, whitelist)).
175
- to contain_exactly(/\/unmanaged_2/, /\/unmanaged_symlink_file/, /\/managed_one\/unmanaged_1/)
176
- end
177
- end
178
- end
179
-
180
- describe '#purge!' do
181
- let(:exclusions) { [] }
182
- let(:whitelist) { [] }
183
- let(:purge_opts) { { recurse: recurse, whitelist: whitelist } }
184
-
185
- it 'does nothing when there is no stale_contents' do
186
- allow(subject).to receive(:stale_contents).and_return([])
187
-
188
- expect(FileUtils).to_not receive(:rm_r)
189
-
190
- subject.purge!(purge_opts)
191
- end
192
-
193
- it 'recursively deletes all stale_contents' do
194
- subject.stale_contents(recurse, exclusions, whitelist).each do |stale|
195
- expect(FileUtils).to receive(:rm_r).with(stale, hash_including(secure: true))
196
- end
197
-
198
- subject.purge!(purge_opts)
199
- end
200
- end
201
- end
202
-
203
- describe "user whitelist functionality" do
204
- context "non-recursive whitelist glob" do
205
- let(:whitelist) { managed_directories.collect { |dir| File.join(dir, "*unmanaged*") } }
206
- let(:purge_opts) { { recurse: true, whitelist: whitelist } }
207
-
208
- describe '#purge!' do
209
- it 'does not purge items matching glob at root level' do
210
- allow(FileUtils).to receive(:rm_r)
211
- expect(FileUtils).to_not receive(:rm_r).with(/\/unmanaged_[12]/, anything)
212
- expect(FileUtils).to_not receive(:rm_r).with(/\/unmanaged_symlink_file/, anything)
213
- expect(subject.logger).to receive(:debug).with(/whitelist match/i).at_least(:once)
214
-
215
- subject.purge!(purge_opts)
216
- end
217
- end
218
- end
219
-
220
- context "recursive whitelist glob" do
221
- let(:whitelist) do
222
- managed_directories.flat_map do |dir|
223
- [File.join(dir, "**", "*unmanaged*"), File.join(dir, "**", "subdir_allowlisted_2")]
224
- end
225
- end
226
- let(:purge_opts) { { recurse: true, whitelist: whitelist } }
227
-
228
- describe '#purge!' do
229
- it 'does not purge items matching glob at any level' do
230
- expect(FileUtils).to_not receive(:rm_r)
231
- expect(subject.logger).to receive(:debug).with(/whitelist match/i).at_least(:once)
232
-
233
- subject.purge!(purge_opts)
234
- end
235
- end
236
- end
237
- end
238
-
239
- describe "internal exclusions functionality" do
240
- let(:purge_opts) { { recurse: true, whitelist: [] } }
241
- let(:exclusions) { [ File.join('**', 'unmanaged_1') ] }
242
-
243
- context "when class implements #purge_exclusions" do
244
- describe '#purge!' do
245
- it 'does not purge items matching exclusion glob' do
246
- expect(subject).to receive(:purge_exclusions).and_return(exclusions)
247
-
248
- allow(FileUtils).to receive(:rm_r)
249
- expect(FileUtils).to_not receive(:rm_r).with(/\/unmanaged_1/, anything)
250
- expect(subject.logger).to receive(:debug2).with(/unmanaged_1.*internal exclusion match/i)
251
-
252
- subject.purge!(purge_opts)
253
- end
254
- end
255
- end
256
-
257
- context "when class does not implement #purge_exclusions" do
258
- describe '#purge!' do
259
- it 'purges normally' do
260
- expect(FileUtils).to receive(:rm_r).at_least(4).times
261
-
262
- subject.purge!(purge_opts)
263
- end
264
- end
265
- end
266
- end
267
- end
@@ -1,83 +0,0 @@
1
- require 'spec_helper'
2
- require 'r10k/util/setopts'
3
-
4
- describe R10K::Util::Setopts do
5
- let(:klass) do
6
- Class.new do
7
- include R10K::Util::Setopts
8
-
9
- attr_reader :valid, :alsovalid, :truthyvalid
10
-
11
- def initialize(opts = {})
12
- setopts(opts, {
13
- :valid => :self,
14
- :duplicate => :valid,
15
- :alsovalid => :self,
16
- :truthyvalid => true,
17
- :validalias => :valid,
18
- :ignoreme => nil
19
- })
20
- end
21
- end
22
- end
23
-
24
- it "can handle an empty hash of options" do
25
- o = klass.new()
26
- expect(o.valid).to be_nil
27
- expect(o.alsovalid).to be_nil
28
- end
29
-
30
- it "can handle a single valid option" do
31
- o = klass.new(:valid => 'yep')
32
- expect(o.valid).to eq 'yep'
33
- expect(o.alsovalid).to be_nil
34
- end
35
-
36
- it "can handle multiple valid options" do
37
- o = klass.new(:valid => 'yep', :alsovalid => 'yarp')
38
- expect(o.valid).to eq 'yep'
39
- expect(o.alsovalid).to eq 'yarp'
40
- end
41
-
42
- it "can handle options marked with TrueClass" do
43
- o = klass.new(:truthyvalid => 'so truthy')
44
- expect(o.truthyvalid).to eq 'so truthy'
45
- end
46
-
47
- it "can handle aliases marked with :self" do
48
- o = klass.new(:validalias => 'yuuup')
49
- expect(o.valid).to eq 'yuuup'
50
- end
51
-
52
-
53
- it "raises an error when given an unhandled option" do
54
- expect {
55
- klass.new(:valid => 'yep', :notvalid => 'newp')
56
- }.to raise_error(ArgumentError, /cannot handle option 'notvalid'/)
57
- end
58
-
59
- it "warns when given an unhandled option and raise_on_unhandled=false" do
60
- test = Class.new { include R10K::Util::Setopts }.new
61
- allow(test).to receive(:logger).and_return(spy)
62
-
63
- test.send(:setopts, {valid: :value, invalid: :value},
64
- {valid: :self},
65
- raise_on_unhandled: false)
66
-
67
- expect(test.logger).to have_received(:warn).with(%r{cannot handle option 'invalid'})
68
- end
69
-
70
- it "ignores values that are marked as unhandled" do
71
- klass.new(:ignoreme => "IGNORE ME!")
72
- end
73
-
74
- it "warns when given conflicting options" do
75
- test = Class.new { include R10K::Util::Setopts }.new
76
- allow(test).to receive(:logger).and_return(spy)
77
-
78
- test.send(:setopts, {valid: :one, duplicate: :two},
79
- {valid: :arg, duplicate: :arg})
80
-
81
- expect(test.logger).to have_received(:warn).with(%r{valid.*duplicate.*conflict.*not both})
82
- end
83
- end