r10k 3.14.1 → 5.0.1

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.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +17 -0
  3. data/.github/workflows/docker.yml +9 -4
  4. data/.github/workflows/release.yml +3 -2
  5. data/.github/workflows/rspec_tests.yml +8 -10
  6. data/CHANGELOG.mkd +100 -0
  7. data/CODEOWNERS +1 -2
  8. data/Gemfile +2 -2
  9. data/README.mkd +18 -19
  10. data/doc/common-patterns.mkd +1 -2
  11. data/doc/dynamic-environments/configuration.mkd +91 -12
  12. data/doc/dynamic-environments/usage.mkd +4 -0
  13. data/doc/dynamic-environments/workflow-guide.mkd +3 -3
  14. data/doc/faq.mkd +1 -1
  15. data/doc/puppetfile.mkd +9 -3
  16. data/integration/Gemfile +3 -4
  17. data/integration/Rakefile +58 -23
  18. data/integration/files/pre-suite/git_config.pp.erb +1 -1
  19. data/integration/pre-suite/00_pe_install.rb +3 -0
  20. data/integration/pre-suite/10_git_config.rb +1 -3
  21. data/integration/tests/Puppetfile/HTTP_PROXY_affects_git_source.rb +5 -4
  22. data/integration/tests/basic_functionality/negative/negative_bad_proxy.rb +1 -1
  23. data/integration/tests/basic_functionality/proxy_specified_in_configuration.rb +2 -2
  24. data/integration/tests/basic_functionality/proxy_with_puppetfile.rb +2 -2
  25. data/integration/tests/basic_functionality/rugged_git_provider_with_ssh.rb +3 -3
  26. data/integration/tests/basic_functionality/rugged_git_provider_without_ssh.rb +3 -3
  27. data/integration/tests/command_line/deploy_env_without_mod_update.rb +0 -3
  28. data/integration/tests/command_line/negative/neg_deploy_env_with_module_update.rb +0 -3
  29. data/integration/tests/git_source/HTTP_proxy_and_git_source.rb +5 -10
  30. data/integration/tests/git_source/git_source_git.rb +1 -4
  31. data/integration/tests/git_source/git_source_repeated_remote.rb +2 -5
  32. data/integration/tests/git_source/git_source_submodule.rb +1 -1
  33. data/integration/tests/git_source/negative/neg_git_unauthorized_ssh.rb +1 -1
  34. data/integration/tests/purging/content_not_purged_at_root.rb +2 -5
  35. data/integration/tests/purging/default_purging.rb +0 -3
  36. data/integration/tests/purging/{does_not_purge_files_on_white_list.rb → does_not_purge_files_on_allowlist.rb} +2 -5
  37. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module.rb +1 -4
  38. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb +1 -4
  39. data/integration/tests/user_scenario/basic_workflow/multi_source_custom_forge_git_module.rb +1 -4
  40. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_forge_module.rb +0 -3
  41. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module.rb +1 -1
  42. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module_ref.rb +1 -1
  43. data/integration/tests/user_scenario/basic_workflow/negative/neg_disk_full.rb +1 -1
  44. data/integration/tests/user_scenario/basic_workflow/negative/neg_duplicate_module_names.rb +0 -3
  45. data/integration/tests/user_scenario/basic_workflow/negative/neg_inaccessible_forge.rb +3 -2
  46. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +1 -5
  47. data/integration/tests/user_scenario/basic_workflow/single_env_10000_files.rb +1 -1
  48. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_git_module.rb +1 -4
  49. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_module.rb +0 -3
  50. data/integration/tests/user_scenario/basic_workflow/single_env_large_files.rb +1 -1
  51. data/integration/tests/user_scenario/basic_workflow/single_env_module_already_installed.rb +0 -3
  52. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +0 -3
  53. data/integration/tests/user_scenario/basic_workflow/single_env_switch_forge_git_module.rb +1 -4
  54. data/integration/tests/user_scenario/basic_workflow/single_env_upgrade_forge_mod_revert_change.rb +0 -3
  55. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +0 -3
  56. data/lib/r10k/action/deploy/environment.rb +2 -19
  57. data/lib/r10k/action/deploy/module.rb +1 -0
  58. data/lib/r10k/action/puppetfile/check.rb +7 -0
  59. data/lib/r10k/action/puppetfile/install.rb +3 -1
  60. data/lib/r10k/cli/deploy.rb +15 -1
  61. data/lib/r10k/cli/puppetfile.rb +1 -0
  62. data/lib/r10k/content_synchronizer.rb +7 -2
  63. data/lib/r10k/environment/with_modules.rb +24 -1
  64. data/lib/r10k/environment.rb +0 -1
  65. data/lib/r10k/git/rugged/bare_repository.rb +5 -4
  66. data/lib/r10k/git/rugged/thin_repository.rb +7 -0
  67. data/lib/r10k/git/rugged/working_repository.rb +13 -7
  68. data/lib/r10k/git/shellgit/thin_repository.rb +5 -1
  69. data/lib/r10k/git/shellgit/working_repository.rb +5 -4
  70. data/lib/r10k/git/stateful_repository.rb +4 -4
  71. data/lib/r10k/module/base.rb +3 -3
  72. data/lib/r10k/module/git.rb +19 -5
  73. data/lib/r10k/module_loader/puppetfile/dsl.rb +4 -0
  74. data/lib/r10k/module_loader/puppetfile.rb +22 -14
  75. data/lib/r10k/puppetfile.rb +1 -1
  76. data/lib/r10k/settings/container.rb +1 -0
  77. data/lib/r10k/settings.rb +6 -7
  78. data/lib/r10k/tarball.rb +1 -1
  79. data/lib/r10k/version.rb +1 -1
  80. data/locales/r10k.pot +34 -82
  81. data/r10k.gemspec +8 -18
  82. metadata +40 -213
  83. data/.github/workflows/stale.yml +0 -21
  84. data/.travis.yml +0 -42
  85. data/docker/.gitignore +0 -1
  86. data/docker/.rspec +0 -4
  87. data/docker/Gemfile +0 -11
  88. data/docker/Makefile +0 -92
  89. data/docker/README.md +0 -28
  90. data/docker/docker-compose.yml +0 -18
  91. data/docker/r10k/Dockerfile +0 -68
  92. data/docker/r10k/adduser.sh +0 -13
  93. data/docker/r10k/docker-entrypoint.d/10-analytics.sh +0 -30
  94. data/docker/r10k/docker-entrypoint.sh +0 -10
  95. data/docker/r10k/release.Dockerfile +0 -55
  96. data/docker/spec/dockerfile_spec.rb +0 -37
  97. data/docker/spec/fixtures/Puppetfile +0 -2
  98. data/integration/tests/basic_functionality/install_pe_only_module_with_puppetfile.rb +0 -83
  99. data/integration/tests/basic_functionality/proxy_with_pe_only_module.rb +0 -128
  100. data/integration/tests/purging/invalid_whitelist_types.rb +0 -63
  101. data/integration/tests/user_scenario/basic_workflow/negative/neg_module_specified_at_deleted_release.rb +0 -49
  102. data/integration/tests/user_scenario/basic_workflow/single_env_module_last_release_deleted.rb +0 -68
  103. data/lib/r10k/environment/bare.rb +0 -13
  104. data/spec/fixtures/empty/.empty +0 -0
  105. data/spec/fixtures/integration/git/puppet-boolean-bare.tar +0 -0
  106. data/spec/fixtures/module/forge/bad_module/metadata.json +0 -1
  107. data/spec/fixtures/module/forge/eight_hundred/Modulefile +0 -8
  108. data/spec/fixtures/module/forge/eight_hundred/metadata.json +0 -19
  109. data/spec/fixtures/tarball/tarball.tar.gz +0 -0
  110. data/spec/fixtures/unit/action/r10k.yaml +0 -5
  111. data/spec/fixtures/unit/action/r10k_cachedir.yaml +0 -2
  112. data/spec/fixtures/unit/action/r10k_creds.yaml +0 -9
  113. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +0 -4
  114. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +0 -3
  115. data/spec/fixtures/unit/action/r10k_generate_types.yaml +0 -3
  116. data/spec/fixtures/unit/action/r10k_logging.yaml +0 -12
  117. data/spec/fixtures/unit/action/r10k_puppet_path.yaml +0 -3
  118. data/spec/fixtures/unit/puppetfile/argument-error/Puppetfile +0 -1
  119. data/spec/fixtures/unit/puppetfile/default-branch-override/Puppetfile +0 -5
  120. data/spec/fixtures/unit/puppetfile/duplicate-module-error/Puppetfile +0 -10
  121. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +0 -8
  122. data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +0 -1
  123. data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +0 -1
  124. data/spec/fixtures/unit/puppetfile/name-error/Puppetfile +0 -1
  125. data/spec/fixtures/unit/puppetfile/valid-forge-with-version/Puppetfile +0 -1
  126. data/spec/fixtures/unit/puppetfile/valid-forge-without-version/Puppetfile +0 -1
  127. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +0 -10
  128. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +0 -10
  129. data/spec/fixtures/unit/util/purgeable/managed_one/expected_1 +0 -0
  130. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file +0 -1
  131. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_allowlisted_2/ignored_1 +0 -0
  132. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_expected_1 +0 -0
  133. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_unmanaged_1 +0 -0
  134. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/unmanaged_symlink_dir +0 -1
  135. data/spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir +0 -1
  136. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_1 +0 -0
  137. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_symlink_file +0 -1
  138. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  139. data/spec/fixtures/unit/util/purgeable/managed_two/expected_2 +0 -0
  140. data/spec/fixtures/unit/util/purgeable/managed_two/unmanaged_2 +0 -0
  141. data/spec/fixtures/unit/util/subprocess/runner/no-execute.sh +0 -3
  142. data/spec/integration/git/rugged/bare_repository_spec.rb +0 -13
  143. data/spec/integration/git/rugged/cache_spec.rb +0 -33
  144. data/spec/integration/git/rugged/thin_repository_spec.rb +0 -14
  145. data/spec/integration/git/rugged/working_repository_spec.rb +0 -48
  146. data/spec/integration/git/shellgit/bare_repository_spec.rb +0 -13
  147. data/spec/integration/git/shellgit/thin_repository_spec.rb +0 -14
  148. data/spec/integration/git/shellgit/working_repository_spec.rb +0 -13
  149. data/spec/integration/git/stateful_repository_spec.rb +0 -159
  150. data/spec/integration/util/purageable_spec.rb +0 -41
  151. data/spec/matchers/exit_with.rb +0 -28
  152. data/spec/matchers/match_realpath.rb +0 -18
  153. data/spec/r10k-mocks/mock_config.rb +0 -33
  154. data/spec/r10k-mocks/mock_env.rb +0 -18
  155. data/spec/r10k-mocks/mock_source.rb +0 -17
  156. data/spec/r10k-mocks.rb +0 -3
  157. data/spec/shared-contexts/git-fixtures.rb +0 -55
  158. data/spec/shared-contexts/tarball.rb +0 -32
  159. data/spec/shared-examples/deploy-actions.rb +0 -69
  160. data/spec/shared-examples/git/bare_repository.rb +0 -132
  161. data/spec/shared-examples/git/thin_repository.rb +0 -26
  162. data/spec/shared-examples/git/working_repository.rb +0 -207
  163. data/spec/shared-examples/git-repository.rb +0 -38
  164. data/spec/shared-examples/puppetfile-action.rb +0 -39
  165. data/spec/shared-examples/settings/ancestry.rb +0 -44
  166. data/spec/shared-examples/subprocess-runner.rb +0 -89
  167. data/spec/spec_helper.rb +0 -41
  168. data/spec/unit/action/cri_runner_spec.rb +0 -72
  169. data/spec/unit/action/deploy/deploy_helpers_spec.rb +0 -38
  170. data/spec/unit/action/deploy/display_spec.rb +0 -61
  171. data/spec/unit/action/deploy/environment_spec.rb +0 -640
  172. data/spec/unit/action/deploy/module_spec.rb +0 -476
  173. data/spec/unit/action/puppetfile/check_spec.rb +0 -53
  174. data/spec/unit/action/puppetfile/cri_runner_spec.rb +0 -47
  175. data/spec/unit/action/puppetfile/install_spec.rb +0 -112
  176. data/spec/unit/action/puppetfile/purge_spec.rb +0 -60
  177. data/spec/unit/action/runner_spec.rb +0 -407
  178. data/spec/unit/action/visitor_spec.rb +0 -39
  179. data/spec/unit/cli_spec.rb +0 -9
  180. data/spec/unit/deployment/config_spec.rb +0 -33
  181. data/spec/unit/deployment_spec.rb +0 -162
  182. data/spec/unit/environment/bare_spec.rb +0 -13
  183. data/spec/unit/environment/base_spec.rb +0 -122
  184. data/spec/unit/environment/git_spec.rb +0 -114
  185. data/spec/unit/environment/name_spec.rb +0 -181
  186. data/spec/unit/environment/plain_spec.rb +0 -8
  187. data/spec/unit/environment/svn_spec.rb +0 -146
  188. data/spec/unit/environment/tarball_spec.rb +0 -45
  189. data/spec/unit/environment/with_modules_spec.rb +0 -75
  190. data/spec/unit/errors/formatting_spec.rb +0 -84
  191. data/spec/unit/feature_spec.rb +0 -50
  192. data/spec/unit/forge/module_release_spec.rb +0 -213
  193. data/spec/unit/git/alternates_spec.rb +0 -116
  194. data/spec/unit/git/cache_spec.rb +0 -66
  195. data/spec/unit/git/rugged/cache_spec.rb +0 -48
  196. data/spec/unit/git/rugged/credentials_spec.rb +0 -215
  197. data/spec/unit/git/shellgit/cache_spec.rb +0 -27
  198. data/spec/unit/git/stateful_repository_spec.rb +0 -45
  199. data/spec/unit/git_spec.rb +0 -102
  200. data/spec/unit/initializers_spec.rb +0 -68
  201. data/spec/unit/instance_cache_spec.rb +0 -78
  202. data/spec/unit/keyed_factory_spec.rb +0 -51
  203. data/spec/unit/logging/terminaloutputter_spec.rb +0 -53
  204. data/spec/unit/logging_spec.rb +0 -68
  205. data/spec/unit/module/base_spec.rb +0 -118
  206. data/spec/unit/module/forge_spec.rb +0 -271
  207. data/spec/unit/module/git_spec.rb +0 -387
  208. data/spec/unit/module/metadata_file_spec.rb +0 -68
  209. data/spec/unit/module/svn_spec.rb +0 -208
  210. data/spec/unit/module/tarball_spec.rb +0 -70
  211. data/spec/unit/module_loader/puppetfile_spec.rb +0 -421
  212. data/spec/unit/module_spec.rb +0 -114
  213. data/spec/unit/puppetfile_spec.rb +0 -304
  214. data/spec/unit/settings/collection_spec.rb +0 -123
  215. data/spec/unit/settings/container_spec.rb +0 -92
  216. data/spec/unit/settings/definition_spec.rb +0 -79
  217. data/spec/unit/settings/enum_definition_spec.rb +0 -20
  218. data/spec/unit/settings/inheritance_spec.rb +0 -38
  219. data/spec/unit/settings/list_spec.rb +0 -88
  220. data/spec/unit/settings/loader_spec.rb +0 -110
  221. data/spec/unit/settings/uri_definition_spec.rb +0 -23
  222. data/spec/unit/settings_spec.rb +0 -303
  223. data/spec/unit/source/base_spec.rb +0 -31
  224. data/spec/unit/source/exec_spec.rb +0 -81
  225. data/spec/unit/source/git_spec.rb +0 -233
  226. data/spec/unit/source/hash_spec.rb +0 -54
  227. data/spec/unit/source/svn_spec.rb +0 -196
  228. data/spec/unit/source/yaml_spec.rb +0 -42
  229. data/spec/unit/source_spec.rb +0 -10
  230. data/spec/unit/svn/remote_spec.rb +0 -21
  231. data/spec/unit/svn/working_dir_spec.rb +0 -56
  232. data/spec/unit/tarball_spec.rb +0 -57
  233. data/spec/unit/util/attempt_spec.rb +0 -82
  234. data/spec/unit/util/cacheable_spec.rb +0 -23
  235. data/spec/unit/util/commands_spec.rb +0 -61
  236. data/spec/unit/util/downloader_spec.rb +0 -98
  237. data/spec/unit/util/exec_env_spec.rb +0 -56
  238. data/spec/unit/util/purgeable_spec.rb +0 -267
  239. data/spec/unit/util/setopts_spec.rb +0 -83
  240. data/spec/unit/util/subprocess/result_spec.rb +0 -36
  241. data/spec/unit/util/subprocess/runner/posix_spec.rb +0 -7
  242. data/spec/unit/util/subprocess/runner/pump_spec.rb +0 -79
  243. data/spec/unit/util/subprocess/runner/windows_spec.rb +0 -7
  244. data/spec/unit/util/subprocess/subprocess_error_spec.rb +0 -26
  245. data/spec/unit/util/subprocess_spec.rb +0 -65
  246. 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) { 'git://some/git/remote' }
10
-
11
- it 'sanitizes URL to directory name' do
12
- expect(subject.sanitized_dirname(input)).to eq('git---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