r10k 3.5.2

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 (358) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/pull_request_template.md +1 -0
  4. data/.github/workflows/docker.yml +56 -0
  5. data/.github/workflows/release.yml +36 -0
  6. data/.gitignore +9 -0
  7. data/.travis.yml +45 -0
  8. data/CHANGELOG.mkd +1759 -0
  9. data/CODEOWNERS +2 -0
  10. data/CONTRIBUTING.mkd +105 -0
  11. data/Gemfile +15 -0
  12. data/LICENSE +14 -0
  13. data/README.mkd +118 -0
  14. data/Rakefile +3 -0
  15. data/azure-pipelines.yml +86 -0
  16. data/bin/r10k +17 -0
  17. data/doc/common-patterns.mkd +44 -0
  18. data/doc/dynamic-environments.mkd +31 -0
  19. data/doc/dynamic-environments/configuration.mkd +669 -0
  20. data/doc/dynamic-environments/git-environments.mkd +75 -0
  21. data/doc/dynamic-environments/introduction.mkd +69 -0
  22. data/doc/dynamic-environments/master-configuration.mkd +40 -0
  23. data/doc/dynamic-environments/quickstart.mkd +201 -0
  24. data/doc/dynamic-environments/svn-environments.mkd +45 -0
  25. data/doc/dynamic-environments/usage.mkd +132 -0
  26. data/doc/dynamic-environments/workflow-guide.mkd +247 -0
  27. data/doc/faq.mkd +164 -0
  28. data/doc/git/cloning-and-mirroring.mkd +60 -0
  29. data/doc/git/providers.mkd +111 -0
  30. data/doc/puppetfile.mkd +309 -0
  31. data/doc/updating-your-puppetfile.mkd +38 -0
  32. data/docker/.gitignore +1 -0
  33. data/docker/.rspec +4 -0
  34. data/docker/Gemfile +11 -0
  35. data/docker/Makefile +89 -0
  36. data/docker/README.md +28 -0
  37. data/docker/r10k/Dockerfile +67 -0
  38. data/docker/r10k/adduser.sh +13 -0
  39. data/docker/r10k/docker-entrypoint.d/10-analytics.sh +30 -0
  40. data/docker/r10k/docker-entrypoint.sh +11 -0
  41. data/docker/r10k/release.Dockerfile +54 -0
  42. data/docker/spec/dockerfile_spec.rb +43 -0
  43. data/docker/spec/fixtures/Puppetfile +2 -0
  44. data/integration/Gemfile +19 -0
  45. data/integration/README.mkd +29 -0
  46. data/integration/Rakefile +77 -0
  47. data/integration/component/pre-suite/05_install_dev_r10k.rb +12 -0
  48. data/integration/files/README.mkd +4 -0
  49. data/integration/files/hiera.yaml +8 -0
  50. data/integration/files/modules/helloworld/manifests/init.pp +3 -0
  51. data/integration/files/modules/hieratest/manifests/init.pp +3 -0
  52. data/integration/files/modules/unicode/files/pretend_unicode +1 -0
  53. data/integration/files/modules/unicode/manifests/init.pp +6 -0
  54. data/integration/files/pre-suite/git_config.pp.erb +19 -0
  55. data/integration/files/pre-suite/prod_env.config +3 -0
  56. data/integration/files/r10k_conf.yaml.erb +9 -0
  57. data/integration/lib/README.mkd +4 -0
  58. data/integration/lib/git_utils.rb +205 -0
  59. data/integration/lib/master_manipulator.rb +205 -0
  60. data/integration/lib/r10k_utils.rb +222 -0
  61. data/integration/manifests/README.mkd +4 -0
  62. data/integration/pre-suite/00_pe_install.rb +6 -0
  63. data/integration/pre-suite/10_git_config.rb +48 -0
  64. data/integration/pre-suite/20_pe_r10k.rb +55 -0
  65. data/integration/pre-suite/README.mkd +5 -0
  66. data/integration/tests/Puppetfile/HTTP_PROXY_affects_forge_source.rb +72 -0
  67. data/integration/tests/Puppetfile/HTTP_PROXY_affects_git_source.rb +70 -0
  68. data/integration/tests/README.mkd +4 -0
  69. data/integration/tests/basic_functionality/install_pe_only_module_with_puppetfile.rb +83 -0
  70. data/integration/tests/basic_functionality/negative/neg_deploy_with_invalid_r10k_yaml.rb +51 -0
  71. data/integration/tests/basic_functionality/negative/neg_deploy_with_missing_r10k_yaml.rb +28 -0
  72. data/integration/tests/basic_functionality/negative/neg_invalid_git_provider.rb +45 -0
  73. data/integration/tests/basic_functionality/negative/negative_bad_proxy.rb +34 -0
  74. data/integration/tests/basic_functionality/proxy_specified_in_configuration.rb +103 -0
  75. data/integration/tests/basic_functionality/proxy_with_pe_only_module.rb +128 -0
  76. data/integration/tests/basic_functionality/proxy_with_puppetfile.rb +61 -0
  77. data/integration/tests/basic_functionality/rugged_git_provider_with_ssh.rb +109 -0
  78. data/integration/tests/basic_functionality/rugged_git_provider_without_ssh.rb +108 -0
  79. data/integration/tests/command_line/deploy_env_without_mod_update.rb +76 -0
  80. data/integration/tests/command_line/negative/neg_deploy_env_with_module_update.rb +77 -0
  81. data/integration/tests/command_line/negative/neg_invalid_cmd_line_arg.rb +23 -0
  82. data/integration/tests/git_source/HTTP_proxy_and_git_source.rb +70 -0
  83. data/integration/tests/git_source/git_source_git.rb +128 -0
  84. data/integration/tests/git_source/git_source_ssh.rb +87 -0
  85. data/integration/tests/git_source/git_source_submodule.rb +70 -0
  86. data/integration/tests/git_source/negative/neg_git_broken_remote.rb +38 -0
  87. data/integration/tests/git_source/negative/neg_git_unauthorized_https.rb +46 -0
  88. data/integration/tests/git_source/negative/neg_git_unauthorized_ssh.rb +73 -0
  89. data/integration/tests/git_source/negative/neg_git_unicode_branch.rb +35 -0
  90. data/integration/tests/i18n/deploy_module_with_unicode_in_file_name.rb +64 -0
  91. data/integration/tests/purging/content_not_purged_at_root.rb +89 -0
  92. data/integration/tests/purging/default_purging.rb +125 -0
  93. data/integration/tests/purging/does_not_purge_files_on_white_list.rb +93 -0
  94. data/integration/tests/purging/invalid_whitelist_types.rb +63 -0
  95. data/integration/tests/user_scenario/basic_workflow/multi_env_1000_branches.rb +66 -0
  96. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module.rb +111 -0
  97. data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb +117 -0
  98. data/integration/tests/user_scenario/basic_workflow/multi_env_hiera.rb +100 -0
  99. data/integration/tests/user_scenario/basic_workflow/multi_env_multi_source.rb +133 -0
  100. data/integration/tests/user_scenario/basic_workflow/multi_source_custom_forge_git_module.rb +161 -0
  101. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_basedir.rb +46 -0
  102. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_forge_module.rb +48 -0
  103. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module.rb +45 -0
  104. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module_ref.rb +43 -0
  105. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_remote.rb +45 -0
  106. data/integration/tests/user_scenario/basic_workflow/negative/neg_branch_name_collision.rb +64 -0
  107. data/integration/tests/user_scenario/basic_workflow/negative/neg_disk_full.rb +75 -0
  108. data/integration/tests/user_scenario/basic_workflow/negative/neg_duplicate_module_names.rb +44 -0
  109. data/integration/tests/user_scenario/basic_workflow/negative/neg_inaccessible_forge.rb +58 -0
  110. data/integration/tests/user_scenario/basic_workflow/negative/neg_invalid_env_name.rb +34 -0
  111. data/integration/tests/user_scenario/basic_workflow/negative/neg_invalid_puppet_file.rb +36 -0
  112. data/integration/tests/user_scenario/basic_workflow/negative/neg_module_specified_at_deleted_release.rb +49 -0
  113. data/integration/tests/user_scenario/basic_workflow/negative/neg_read_only.rb +58 -0
  114. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +51 -0
  115. data/integration/tests/user_scenario/basic_workflow/single_env_10000_files.rb +75 -0
  116. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_git_module.rb +104 -0
  117. data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_module.rb +81 -0
  118. data/integration/tests/user_scenario/basic_workflow/single_env_custom_module.rb +49 -0
  119. data/integration/tests/user_scenario/basic_workflow/single_env_large_files.rb +75 -0
  120. data/integration/tests/user_scenario/basic_workflow/single_env_module_already_installed.rb +82 -0
  121. data/integration/tests/user_scenario/basic_workflow/single_env_module_last_release_deleted.rb +68 -0
  122. data/integration/tests/user_scenario/basic_workflow/single_env_non-existent_base_dir.rb +94 -0
  123. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +93 -0
  124. data/integration/tests/user_scenario/basic_workflow/single_env_switch_forge_git_module.rb +117 -0
  125. data/integration/tests/user_scenario/basic_workflow/single_env_unicode_paths.rb +60 -0
  126. data/integration/tests/user_scenario/basic_workflow/single_env_upgrade_forge_mod_revert_change.rb +166 -0
  127. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +163 -0
  128. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +111 -0
  129. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +78 -0
  130. data/integration/tests/user_scenario/complex_workflow/single_env_git_module_update.rb +100 -0
  131. data/lib/r10k.rb +11 -0
  132. data/lib/r10k/action/base.rb +31 -0
  133. data/lib/r10k/action/cri_runner.rb +72 -0
  134. data/lib/r10k/action/deploy.rb +9 -0
  135. data/lib/r10k/action/deploy/deploy_helpers.rb +34 -0
  136. data/lib/r10k/action/deploy/display.rb +89 -0
  137. data/lib/r10k/action/deploy/environment.rb +196 -0
  138. data/lib/r10k/action/deploy/module.rb +84 -0
  139. data/lib/r10k/action/puppetfile.rb +10 -0
  140. data/lib/r10k/action/puppetfile/check.rb +31 -0
  141. data/lib/r10k/action/puppetfile/cri_runner.rb +26 -0
  142. data/lib/r10k/action/puppetfile/install.rb +45 -0
  143. data/lib/r10k/action/puppetfile/purge.rb +28 -0
  144. data/lib/r10k/action/runner.rb +96 -0
  145. data/lib/r10k/action/visitor.rb +31 -0
  146. data/lib/r10k/cli.rb +51 -0
  147. data/lib/r10k/cli/deploy.rb +114 -0
  148. data/lib/r10k/cli/ext/logging.rb +15 -0
  149. data/lib/r10k/cli/help.rb +7 -0
  150. data/lib/r10k/cli/puppetfile.rb +74 -0
  151. data/lib/r10k/cli/version.rb +31 -0
  152. data/lib/r10k/deployment.rb +132 -0
  153. data/lib/r10k/deployment/config.rb +56 -0
  154. data/lib/r10k/environment.rb +37 -0
  155. data/lib/r10k/environment/bare.rb +16 -0
  156. data/lib/r10k/environment/base.rb +150 -0
  157. data/lib/r10k/environment/git.rb +81 -0
  158. data/lib/r10k/environment/name.rb +86 -0
  159. data/lib/r10k/environment/svn.rb +91 -0
  160. data/lib/r10k/environment/with_modules.rb +139 -0
  161. data/lib/r10k/errors.rb +61 -0
  162. data/lib/r10k/errors/formatting.rb +28 -0
  163. data/lib/r10k/feature.rb +56 -0
  164. data/lib/r10k/feature/collection.rb +23 -0
  165. data/lib/r10k/features.rb +20 -0
  166. data/lib/r10k/forge/module_release.rb +228 -0
  167. data/lib/r10k/git.rb +196 -0
  168. data/lib/r10k/git/alternates.rb +63 -0
  169. data/lib/r10k/git/cache.rb +108 -0
  170. data/lib/r10k/git/errors.rb +34 -0
  171. data/lib/r10k/git/rugged.rb +17 -0
  172. data/lib/r10k/git/rugged/bare_repository.rb +85 -0
  173. data/lib/r10k/git/rugged/base_repository.rb +93 -0
  174. data/lib/r10k/git/rugged/cache.rb +11 -0
  175. data/lib/r10k/git/rugged/credentials.rb +91 -0
  176. data/lib/r10k/git/rugged/thin_repository.rb +89 -0
  177. data/lib/r10k/git/rugged/working_repository.rb +145 -0
  178. data/lib/r10k/git/shellgit.rb +9 -0
  179. data/lib/r10k/git/shellgit/bare_repository.rb +43 -0
  180. data/lib/r10k/git/shellgit/base_repository.rb +137 -0
  181. data/lib/r10k/git/shellgit/cache.rb +11 -0
  182. data/lib/r10k/git/shellgit/thin_repository.rb +69 -0
  183. data/lib/r10k/git/shellgit/working_repository.rb +111 -0
  184. data/lib/r10k/git/stateful_repository.rb +95 -0
  185. data/lib/r10k/initializers.rb +67 -0
  186. data/lib/r10k/instance_cache.rb +32 -0
  187. data/lib/r10k/keyed_factory.rb +39 -0
  188. data/lib/r10k/logging.rb +109 -0
  189. data/lib/r10k/logging/terminaloutputter.rb +36 -0
  190. data/lib/r10k/module.rb +38 -0
  191. data/lib/r10k/module/base.rb +113 -0
  192. data/lib/r10k/module/forge.rb +177 -0
  193. data/lib/r10k/module/git.rb +109 -0
  194. data/lib/r10k/module/local.rb +36 -0
  195. data/lib/r10k/module/metadata_file.rb +31 -0
  196. data/lib/r10k/module/svn.rb +112 -0
  197. data/lib/r10k/puppetfile.rb +286 -0
  198. data/lib/r10k/settings.rb +194 -0
  199. data/lib/r10k/settings/collection.rb +123 -0
  200. data/lib/r10k/settings/container.rb +97 -0
  201. data/lib/r10k/settings/definition.rb +124 -0
  202. data/lib/r10k/settings/enum_definition.rb +30 -0
  203. data/lib/r10k/settings/helpers.rb +38 -0
  204. data/lib/r10k/settings/list.rb +107 -0
  205. data/lib/r10k/settings/loader.rb +99 -0
  206. data/lib/r10k/settings/mixin.rb +54 -0
  207. data/lib/r10k/settings/uri_definition.rb +19 -0
  208. data/lib/r10k/source.rb +42 -0
  209. data/lib/r10k/source/base.rb +74 -0
  210. data/lib/r10k/source/exec.rb +51 -0
  211. data/lib/r10k/source/git.rb +142 -0
  212. data/lib/r10k/source/hash.rb +182 -0
  213. data/lib/r10k/source/svn.rb +136 -0
  214. data/lib/r10k/source/yaml.rb +20 -0
  215. data/lib/r10k/source/yamldir.rb +32 -0
  216. data/lib/r10k/svn.rb +6 -0
  217. data/lib/r10k/svn/remote.rb +68 -0
  218. data/lib/r10k/svn/working_dir.rb +125 -0
  219. data/lib/r10k/util/attempt.rb +84 -0
  220. data/lib/r10k/util/basedir.rb +65 -0
  221. data/lib/r10k/util/commands.rb +31 -0
  222. data/lib/r10k/util/exec_env.rb +36 -0
  223. data/lib/r10k/util/license.rb +24 -0
  224. data/lib/r10k/util/platform.rb +42 -0
  225. data/lib/r10k/util/purgeable.rb +88 -0
  226. data/lib/r10k/util/setopts.rb +55 -0
  227. data/lib/r10k/util/subprocess.rb +84 -0
  228. data/lib/r10k/util/subprocess/result.rb +56 -0
  229. data/lib/r10k/util/subprocess/runner.rb +26 -0
  230. data/lib/r10k/util/subprocess/runner/jruby.rb +23 -0
  231. data/lib/r10k/util/subprocess/runner/posix.rb +103 -0
  232. data/lib/r10k/util/subprocess/runner/pump.rb +59 -0
  233. data/lib/r10k/util/subprocess/runner/windows.rb +23 -0
  234. data/lib/r10k/util/subprocess/subprocess_error.rb +24 -0
  235. data/lib/r10k/util/symbolize_keys.rb +35 -0
  236. data/lib/r10k/version.rb +6 -0
  237. data/locales/config.yaml +21 -0
  238. data/locales/r10k.pot +545 -0
  239. data/r10k.gemspec +50 -0
  240. data/r10k.yaml.example +112 -0
  241. data/spec/fixtures/empty/.empty +0 -0
  242. data/spec/fixtures/integration/git/puppet-boolean-bare.tar +0 -0
  243. data/spec/fixtures/module/forge/bad_module/metadata.json +1 -0
  244. data/spec/fixtures/module/forge/eight_hundred/Modulefile +8 -0
  245. data/spec/fixtures/module/forge/eight_hundred/metadata.json +19 -0
  246. data/spec/fixtures/unit/action/r10k.yaml +5 -0
  247. data/spec/fixtures/unit/action/r10k_cachedir.yaml +2 -0
  248. data/spec/fixtures/unit/action/r10k_generate_types.yaml +3 -0
  249. data/spec/fixtures/unit/action/r10k_puppet_path.yaml +3 -0
  250. data/spec/fixtures/unit/puppetfile/argument-error/Puppetfile +1 -0
  251. data/spec/fixtures/unit/puppetfile/default-branch-override/Puppetfile +5 -0
  252. data/spec/fixtures/unit/puppetfile/duplicate-module-error/Puppetfile +10 -0
  253. data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +1 -0
  254. data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +1 -0
  255. data/spec/fixtures/unit/puppetfile/name-error/Puppetfile +1 -0
  256. data/spec/fixtures/unit/puppetfile/valid-forge-with-version/Puppetfile +1 -0
  257. data/spec/fixtures/unit/puppetfile/valid-forge-without-version/Puppetfile +1 -0
  258. data/spec/fixtures/unit/util/purgeable/managed_one/expected_1 +0 -0
  259. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_expected_1 +0 -0
  260. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/subdir_unmanaged_1 +0 -0
  261. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_1 +0 -0
  262. data/spec/fixtures/unit/util/purgeable/managed_two/expected_2 +0 -0
  263. data/spec/fixtures/unit/util/purgeable/managed_two/unmanaged_2 +0 -0
  264. data/spec/fixtures/unit/util/subprocess/runner/no-execute.sh +3 -0
  265. data/spec/integration/git/rugged/bare_repository_spec.rb +13 -0
  266. data/spec/integration/git/rugged/thin_repository_spec.rb +14 -0
  267. data/spec/integration/git/rugged/working_repository_spec.rb +48 -0
  268. data/spec/integration/git/shellgit/bare_repository_spec.rb +13 -0
  269. data/spec/integration/git/shellgit/thin_repository_spec.rb +14 -0
  270. data/spec/integration/git/shellgit/working_repository_spec.rb +13 -0
  271. data/spec/integration/git/stateful_repository_spec.rb +159 -0
  272. data/spec/matchers/exit_with.rb +28 -0
  273. data/spec/matchers/match_realpath.rb +18 -0
  274. data/spec/r10k-mocks.rb +3 -0
  275. data/spec/r10k-mocks/mock_config.rb +33 -0
  276. data/spec/r10k-mocks/mock_env.rb +15 -0
  277. data/spec/r10k-mocks/mock_source.rb +13 -0
  278. data/spec/shared-contexts/git-fixtures.rb +55 -0
  279. data/spec/shared-examples/deploy-actions.rb +69 -0
  280. data/spec/shared-examples/git-repository.rb +38 -0
  281. data/spec/shared-examples/git/bare_repository.rb +132 -0
  282. data/spec/shared-examples/git/thin_repository.rb +26 -0
  283. data/spec/shared-examples/git/working_repository.rb +207 -0
  284. data/spec/shared-examples/puppetfile-action.rb +39 -0
  285. data/spec/shared-examples/settings/ancestry.rb +44 -0
  286. data/spec/shared-examples/subprocess-runner.rb +83 -0
  287. data/spec/spec_helper.rb +40 -0
  288. data/spec/unit/action/cri_runner_spec.rb +72 -0
  289. data/spec/unit/action/deploy/deploy_helpers_spec.rb +38 -0
  290. data/spec/unit/action/deploy/display_spec.rb +31 -0
  291. data/spec/unit/action/deploy/environment_spec.rb +395 -0
  292. data/spec/unit/action/deploy/module_spec.rb +139 -0
  293. data/spec/unit/action/puppetfile/check_spec.rb +41 -0
  294. data/spec/unit/action/puppetfile/cri_runner_spec.rb +47 -0
  295. data/spec/unit/action/puppetfile/install_spec.rb +84 -0
  296. data/spec/unit/action/puppetfile/purge_spec.rb +42 -0
  297. data/spec/unit/action/runner_spec.rb +213 -0
  298. data/spec/unit/action/visitor_spec.rb +39 -0
  299. data/spec/unit/cli_spec.rb +9 -0
  300. data/spec/unit/deployment/config_spec.rb +33 -0
  301. data/spec/unit/deployment_spec.rb +162 -0
  302. data/spec/unit/environment/base_spec.rb +109 -0
  303. data/spec/unit/environment/git_spec.rb +97 -0
  304. data/spec/unit/environment/name_spec.rb +135 -0
  305. data/spec/unit/environment/svn_spec.rb +133 -0
  306. data/spec/unit/errors/formatting_spec.rb +84 -0
  307. data/spec/unit/feature_spec.rb +50 -0
  308. data/spec/unit/forge/module_release_spec.rb +213 -0
  309. data/spec/unit/git/alternates_spec.rb +116 -0
  310. data/spec/unit/git/cache_spec.rb +55 -0
  311. data/spec/unit/git/rugged/cache_spec.rb +29 -0
  312. data/spec/unit/git/rugged/credentials_spec.rb +109 -0
  313. data/spec/unit/git/shellgit/cache_spec.rb +27 -0
  314. data/spec/unit/git/stateful_repository_spec.rb +40 -0
  315. data/spec/unit/git_spec.rb +102 -0
  316. data/spec/unit/initializers_spec.rb +68 -0
  317. data/spec/unit/instance_cache_spec.rb +78 -0
  318. data/spec/unit/keyed_factory_spec.rb +51 -0
  319. data/spec/unit/logging/terminaloutputter_spec.rb +53 -0
  320. data/spec/unit/logging_spec.rb +68 -0
  321. data/spec/unit/module/base_spec.rb +72 -0
  322. data/spec/unit/module/forge_spec.rb +207 -0
  323. data/spec/unit/module/git_spec.rb +274 -0
  324. data/spec/unit/module/metadata_file_spec.rb +68 -0
  325. data/spec/unit/module/svn_spec.rb +178 -0
  326. data/spec/unit/module_spec.rb +29 -0
  327. data/spec/unit/puppetfile_spec.rb +300 -0
  328. data/spec/unit/settings/collection_spec.rb +123 -0
  329. data/spec/unit/settings/container_spec.rb +92 -0
  330. data/spec/unit/settings/definition_spec.rb +79 -0
  331. data/spec/unit/settings/enum_definition_spec.rb +20 -0
  332. data/spec/unit/settings/inheritance_spec.rb +38 -0
  333. data/spec/unit/settings/list_spec.rb +88 -0
  334. data/spec/unit/settings/loader_spec.rb +110 -0
  335. data/spec/unit/settings/uri_definition_spec.rb +23 -0
  336. data/spec/unit/settings_spec.rb +246 -0
  337. data/spec/unit/source/base_spec.rb +31 -0
  338. data/spec/unit/source/exec_spec.rb +81 -0
  339. data/spec/unit/source/git_spec.rb +185 -0
  340. data/spec/unit/source/hash_spec.rb +54 -0
  341. data/spec/unit/source/svn_spec.rb +196 -0
  342. data/spec/unit/source/yaml_spec.rb +42 -0
  343. data/spec/unit/source_spec.rb +10 -0
  344. data/spec/unit/svn/remote_spec.rb +21 -0
  345. data/spec/unit/svn/working_dir_spec.rb +56 -0
  346. data/spec/unit/util/attempt_spec.rb +82 -0
  347. data/spec/unit/util/commands_spec.rb +61 -0
  348. data/spec/unit/util/exec_env_spec.rb +56 -0
  349. data/spec/unit/util/purgeable_spec.rb +230 -0
  350. data/spec/unit/util/setopts_spec.rb +59 -0
  351. data/spec/unit/util/subprocess/result_spec.rb +36 -0
  352. data/spec/unit/util/subprocess/runner/posix_spec.rb +7 -0
  353. data/spec/unit/util/subprocess/runner/pump_spec.rb +79 -0
  354. data/spec/unit/util/subprocess/runner/windows_spec.rb +7 -0
  355. data/spec/unit/util/subprocess/subprocess_error_spec.rb +26 -0
  356. data/spec/unit/util/subprocess_spec.rb +65 -0
  357. data/spec/unit/util/symbolize_keys_spec.rb +67 -0
  358. metadata +582 -0
@@ -0,0 +1,246 @@
1
+ require 'spec_helper'
2
+ require 'r10k/settings'
3
+ require 'r10k/util/exec_env'
4
+
5
+ describe R10K::Settings do
6
+ describe "git settings" do
7
+ subject { described_class.git_settings }
8
+
9
+ describe "provider" do
10
+ it "normalizes valid values to a symbol" do
11
+ output = subject.evaluate("provider" => "rugged")
12
+ expect(output[:provider]).to eq(:rugged)
13
+ end
14
+ end
15
+
16
+ describe "username" do
17
+ it "defaults to the current user" do
18
+ expect(Etc).to receive(:getlogin).and_return("puppet")
19
+ output = subject.evaluate({})
20
+ expect(output[:username]).to eq("puppet")
21
+ end
22
+
23
+ it "passes values through unchanged" do
24
+ output = subject.evaluate("username" => "git")
25
+ expect(output[:username]).to eq("git")
26
+ end
27
+ end
28
+
29
+ describe "private_key" do
30
+ it "passes values through unchanged" do
31
+ output = subject.evaluate("private_key" => "/etc/puppetlabs/r10k/id_rsa")
32
+ expect(output[:private_key]).to eq("/etc/puppetlabs/r10k/id_rsa")
33
+ end
34
+ end
35
+
36
+ describe "proxy" do
37
+ it "accepts valid URIs" do
38
+ output = subject.evaluate("proxy" => "http://proxy.tessier-ashpool.freeside:3128")
39
+ expect(output[:proxy]).to eq "http://proxy.tessier-ashpool.freeside:3128"
40
+ end
41
+
42
+ it "rejects invalid URIs" do
43
+ expect {
44
+ subject.evaluate("proxy" => "that's no proxy!")
45
+ }.to raise_error do |err|
46
+ expect(err.message).to match(/Validation failed for 'git' settings group/)
47
+ expect(err.errors.size).to eq 1
48
+ expect(err.errors[:proxy]).to be_a_kind_of(ArgumentError)
49
+ expect(err.errors[:proxy].message).to match(/could not be parsed as a URL/)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "forge settings" do
56
+ subject { described_class.forge_settings }
57
+
58
+ describe "proxy" do
59
+ it "accepts valid URIs" do
60
+ output = subject.evaluate("proxy" => "http://proxy.tessier-ashpool.freeside:3128")
61
+ expect(output[:proxy]).to eq "http://proxy.tessier-ashpool.freeside:3128"
62
+ end
63
+
64
+ it "rejects invalid URIs" do
65
+ expect {
66
+ subject.evaluate("proxy" => "that's no proxy!")
67
+ }.to raise_error do |err|
68
+ expect(err.message).to match(/Validation failed for 'forge' settings group/)
69
+ expect(err.errors.size).to eq 1
70
+ expect(err.errors[:proxy]).to be_a_kind_of(ArgumentError)
71
+ expect(err.errors[:proxy].message).to match(/could not be parsed as a URL/)
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "baseurl" do
77
+ it "accepts valid URIs" do
78
+ output = subject.evaluate("baseurl" => "https://forge.tessier-ashpool.freeside")
79
+ expect(output[:baseurl]).to eq "https://forge.tessier-ashpool.freeside"
80
+ end
81
+
82
+ it "rejects invalid URIs" do
83
+ expect {
84
+ subject.evaluate("baseurl" => "that's no forge!")
85
+ }.to raise_error do |err|
86
+ expect(err.message).to match(/Validation failed for 'forge' settings group/)
87
+ expect(err.errors.size).to eq 1
88
+ expect(err.errors[:baseurl]).to be_a_kind_of(ArgumentError)
89
+ expect(err.errors[:baseurl].message).to match(/could not be parsed as a URL/)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "deploy settings" do
96
+ subject { described_class.deploy_settings }
97
+
98
+ describe "write_lock" do
99
+ it "accepts a string with a reason for the write lock" do
100
+ output = subject.evaluate("write_lock" => "No maintenance window active, code freeze till 2038-01-19")
101
+ expect(output[:write_lock]).to eq("No maintenance window active, code freeze till 2038-01-19")
102
+ end
103
+
104
+ it "accepts false and null values for the write lock" do
105
+ output = subject.evaluate("write_lock" => false)
106
+ expect(output[:write_lock]).to eq false
107
+ end
108
+
109
+ it "rejects non-string truthy values for the write lock" do
110
+ expect {
111
+ subject.evaluate("write_lock" => %w[list of reasons why deploys are locked])
112
+ }.to raise_error do |err|
113
+ expect(err.message).to match(/Validation failed for 'deploy' settings group/)
114
+ expect(err.errors.size).to eq 1
115
+ expect(err.errors[:write_lock]).to be_a_kind_of(ArgumentError)
116
+ expect(err.errors[:write_lock].message).to match(/should be a string containing the reason/)
117
+ end
118
+ end
119
+ end
120
+
121
+ describe 'puppet_path' do
122
+ it 'when executable raises no error' do
123
+ expect(File).to receive(:executable?).with('/nonexistent').and_return(true)
124
+ expect { subject.evaluate('puppet_path' => '/nonexistent') }.not_to raise_error
125
+ end
126
+
127
+ it 'when not executable raises error' do
128
+ expect(File).to receive(:executable?).with('/nonexistent')
129
+ expect { subject.evaluate('puppet_path' => '/nonexistent') }.to raise_error(R10K::Settings::Collection::ValidationError)
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "global settings" do
135
+ subject { described_class.global_settings }
136
+ describe "sources" do
137
+ it "passes values through unchanged" do
138
+ output = subject.evaluate("sources" => {"puppet" => {"remote" => "https://git.tessier-ashpool.freeside"}})
139
+ expect(output[:sources]).to eq({"puppet" => {"remote" => "https://git.tessier-ashpool.freeside"}})
140
+ end
141
+ end
142
+
143
+ describe "cachedir" do
144
+ it "passes values through unchanged" do
145
+ output = subject.evaluate("cachedir" => "/srv/r10k/git")
146
+ expect(output[:cachedir]).to eq("/srv/r10k/git")
147
+ end
148
+ end
149
+
150
+ describe "postrun" do
151
+ it "accepts an argument vector" do
152
+ output = subject.evaluate("postrun" => ["curl", "-F", "deploy=done", "http://reporting.tessier-ashpool.freeside/r10k"])
153
+ expect(output[:postrun]).to eq(["curl", "-F", "deploy=done", "http://reporting.tessier-ashpool.freeside/r10k"])
154
+ end
155
+
156
+ it "rejects a string command" do
157
+ expect {
158
+ subject.evaluate("postrun" => "curl -F 'deploy=done' https://reporting.tessier-ashpool.freeside/r10k")
159
+ }.to raise_error do |err|
160
+ expect(err.message).to match(/Validation failed for 'global' settings group/)
161
+ expect(err.errors.size).to eq 1
162
+ expect(err.errors[:postrun]).to be_a_kind_of(ArgumentError)
163
+ expect(err.errors[:postrun].message).to eq("The postrun setting should be an array of strings, not a String")
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "pool_size" do
169
+ it "accepts integers greater than zero" do
170
+ output = subject.evaluate("pool_size" => 5)
171
+ expect(output[:pool_size]).to eq 5
172
+ end
173
+
174
+ it "rejects non integer values" do
175
+ expect {
176
+ subject.evaluate("pool_size" => "5")
177
+ }.to raise_error do |err|
178
+ expect(err.errors.size).to eq 1
179
+ expect(err.errors[:pool_size]).to be_a_kind_of(ArgumentError)
180
+ expect(err.errors[:pool_size].message).to match(/The pool_size setting should be an integer/)
181
+ end
182
+ end
183
+
184
+ it "rejects integers smaller than one" do
185
+ expect {
186
+ subject.evaluate("pool_size" => 0)
187
+ }.to raise_error do |err|
188
+ expect(err.errors.size).to eq 1
189
+ expect(err.errors[:pool_size]).to be_a_kind_of(ArgumentError)
190
+ expect(err.errors[:pool_size].message).to match(/The pool_size setting should be greater than zero/)
191
+ end
192
+
193
+ expect {
194
+ subject.evaluate("pool_size" => -3)
195
+ }.to raise_error do |err|
196
+ expect(err.errors.size).to eq 1
197
+ expect(err.errors[:pool_size]).to be_a_kind_of(ArgumentError)
198
+ expect(err.errors[:pool_size].message).to match(/The pool_size setting should be greater than zero/)
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "proxy" do
204
+ it "accepts valid URIs" do
205
+ output = subject.evaluate("proxy" => "http://proxy.tessier-ashpool.freeside:3128")
206
+ expect(output[:proxy]).to eq "http://proxy.tessier-ashpool.freeside:3128"
207
+ end
208
+
209
+ it "rejects invalid URIs" do
210
+ expect {
211
+ subject.evaluate("proxy" => "that's no proxy!")
212
+ }.to raise_error do |err|
213
+ expect(err.message).to match(/Validation failed for 'global' settings group/)
214
+ expect(err.errors.size).to eq 1
215
+ expect(err.errors[:proxy]).to be_a_kind_of(ArgumentError)
216
+ expect(err.errors[:proxy].message).to match(/could not be parsed as a URL/)
217
+ end
218
+ end
219
+
220
+ describe "setting a default value" do
221
+ %w[HTTPS_PROXY https_proxy HTTP_PROXY http_proxy].each do |env_var|
222
+ it "respects the #{env_var} environment variable" do
223
+ R10K::Util::ExecEnv.withenv(env_var => "http://proxy.value/#{env_var}") do
224
+ output = subject.evaluate({})
225
+ expect(output[:proxy]).to eq("http://proxy.value/#{env_var}")
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ describe "git settings" do
233
+ it "passes settings through to the git settings" do
234
+ output = subject.evaluate("git" => {"provider" => "shellgit", "username" => "git"})
235
+ expect(output[:git]).to include(:provider => :shellgit, :username => "git")
236
+ end
237
+ end
238
+
239
+ describe "forge settings" do
240
+ it "passes settings through to the forge settings" do
241
+ output = subject.evaluate("forge" => {"baseurl" => "https://forge.tessier-ashpool.freeside", "proxy" => "https://proxy.tessier-ashpool.freesize:3128"})
242
+ expect(output[:forge]).to eq(:baseurl => "https://forge.tessier-ashpool.freeside", :proxy => "https://proxy.tessier-ashpool.freesize:3128")
243
+ end
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'r10k/source'
3
+
4
+ describe R10K::Source::Base do
5
+ subject { described_class.new('base', '/some/nonexistent/path') }
6
+
7
+ describe "accepting a visitor" do
8
+ it "passes itself to the visitor" do
9
+ visitor = spy('visitor')
10
+ expect(visitor).to receive(:visit).with(:source, subject)
11
+ subject.accept(visitor)
12
+ end
13
+
14
+ it "passes the visitor to each environment if the visitor yields" do
15
+ visitor = spy('visitor')
16
+ expect(visitor).to receive(:visit) do |type, other, &block|
17
+ expect(type).to eq :source
18
+ expect(other).to eq subject
19
+ block.call
20
+ end
21
+
22
+ env1 = spy('environment')
23
+ expect(env1).to receive(:accept).with(visitor)
24
+ env2 = spy('environment')
25
+ expect(env2).to receive(:accept).with(visitor)
26
+
27
+ expect(subject).to receive(:environments).and_return([env1, env2])
28
+ subject.accept(visitor)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'r10k/source'
3
+ require 'json'
4
+ require 'yaml'
5
+
6
+ describe R10K::Source::Exec do
7
+
8
+ let(:environments_hash) do
9
+ {
10
+ 'production' => {
11
+ 'remote' => 'https://git.example.com/puppet/control-repo.git',
12
+ 'ref' => 'release-141',
13
+ 'modules' => {
14
+ 'puppetlabs-stdlib' => '6.1.0',
15
+ 'puppetlabs-ntp' => '8.1.0',
16
+ 'example-myapp1' => {
17
+ 'git' => 'https://git.example.com/puppet/example-myapp1.git',
18
+ 'ref' => 'v1.3.0'
19
+ }
20
+ }
21
+ },
22
+ 'development' => {
23
+ 'remote' => 'https://git.example.com/puppet/control-repo.git',
24
+ 'ref' => 'master',
25
+ 'modules' => {
26
+ 'puppetlabs-stdlib' => '6.1.0',
27
+ 'puppetlabs-ntp' => '8.1.0',
28
+ 'example-myapp1' => {
29
+ 'git' => 'https://git.example.com/puppet/example-myapp1.git',
30
+ 'ref' => 'v1.3.1'
31
+ }
32
+ }
33
+ }
34
+ }
35
+ end
36
+
37
+ describe 'initialize' do
38
+ context 'with a valid command' do
39
+ context 'that produces valid output' do
40
+ it 'accepts json' do
41
+ allow_any_instance_of(R10K::Util::Subprocess)
42
+ .to receive(:execute)
43
+ .and_return(double('result', stdout: environments_hash.to_json))
44
+
45
+ source = described_class.new('execsource', '/some/nonexistent/dir', command: '/path/to/command')
46
+ expect(source.environments.map(&:name)).to contain_exactly('production', 'development')
47
+ end
48
+
49
+ it 'accepts yaml' do
50
+ allow_any_instance_of(R10K::Util::Subprocess)
51
+ .to receive(:execute)
52
+ .and_return(double('result', stdout: environments_hash.to_yaml))
53
+
54
+ source = described_class.new('execsource', '/some/nonexistent/dir', command: '/path/to/command')
55
+ expect(source.environments.map(&:name)).to contain_exactly('production', 'development')
56
+ end
57
+
58
+ end
59
+
60
+ context 'that produces invalid output' do
61
+ it 'raises an error for non-json, non-yaml data' do
62
+ allow_any_instance_of(R10K::Util::Subprocess)
63
+ .to receive(:execute)
64
+ .and_return(double('result', stdout: "one:\ntwo\n"))
65
+
66
+ source = described_class.new('execsource', '/some/nonexistent/dir', command: '/path/to/command')
67
+ expect { source.environments }.to raise_error(/Error parsing command output/)
68
+ end
69
+
70
+ it 'raises an error for yaml data that is not a hash' do
71
+ allow_any_instance_of(R10K::Util::Subprocess)
72
+ .to receive(:execute)
73
+ .and_return(double('result', stdout: "[one, two]"))
74
+
75
+ source = described_class.new('execsource', '/some/nonexistent/dir', command: '/path/to/command')
76
+ expect { source.environments }.to raise_error(R10K::Error, /Environment source execsource.*did not return valid environment data.*one.*two.*/m)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+ require 'r10k/source'
3
+
4
+ describe R10K::Source::Git do
5
+
6
+ subject do
7
+ described_class.new('mysource', '/some/nonexistent/dir',
8
+ {:remote => 'https://git-server/repo.git'})
9
+ end
10
+
11
+ it "stores the name" do
12
+ expect(subject.name).to eq 'mysource'
13
+ end
14
+
15
+ it "stores the basedir" do
16
+ expect(subject.basedir).to eq '/some/nonexistent/dir'
17
+ end
18
+
19
+ describe "preloading" do
20
+ it "fetches the git cache" do
21
+ expect(subject.cache).to receive(:sync)
22
+ subject.preload!
23
+ end
24
+ end
25
+
26
+ describe "lazily generating environments" do
27
+ it "returns an empty list of environments when the cache has not been created" do
28
+ allow(subject.cache).to receive(:cached?).and_return false
29
+ expect(subject.environments).to be_empty
30
+ end
31
+
32
+ it "generates environments when the cache is present and environments have not been loaded" do
33
+ allow(subject.cache).to receive(:cached?).and_return true
34
+ allow(subject).to receive(:generate_environments).and_return %w[hi]
35
+ expect(subject.environments.size).to eq(1)
36
+ end
37
+
38
+ it "doesn't recreate environments if they have already been loaded" do
39
+ allow(subject.cache).to receive(:cached?).and_return true
40
+ allow(subject).to receive(:generate_environments).once.and_return %w[hi]
41
+ expect(subject.environments.size).to eq(1)
42
+ expect(subject.environments.size).to eq(1)
43
+ end
44
+ end
45
+
46
+ describe "eagerly generating environments" do
47
+ before do
48
+ allow(subject.cache).to receive(:branches).and_return %w[master]
49
+ end
50
+
51
+ let(:master_env) { subject.generate_environments.first }
52
+
53
+ it "creates an environment for each branch" do
54
+ expect(subject.generate_environments.size).to eq(1)
55
+ end
56
+
57
+ it "copies the source remote to the environment" do
58
+ expect(master_env.remote).to eq subject.remote
59
+ end
60
+
61
+ it "uses the branch name as the directory by default" do
62
+ expect(master_env.dirname).to eq 'master'
63
+ end
64
+ end
65
+
66
+ describe "generate_environments respects ignore_branch_prefixes setting" do
67
+ before do
68
+ allow(subject.cache).to receive(:branches).and_return ['master', 'development', 'production', 'not_dev_test_me', 'dev_test', 'dev', 'test_2']
69
+ subject.instance_variable_set(:@ignore_branch_prefixes, ['dev', 'test'])
70
+ end
71
+
72
+ let(:environments) { subject.generate_environments }
73
+
74
+ it "creates an environment for each branch not in ignore_branch_prefixes" do
75
+ expect(subject.generate_environments.size).to eq(3)
76
+ end
77
+
78
+ it "copies the source remote to the environment" do
79
+ expect(environments[0].remote).to eq subject.remote
80
+ expect(environments[1].remote).to eq subject.remote
81
+ expect(environments[2].remote).to eq subject.remote
82
+ end
83
+
84
+ it "uses the branch name as the directory by default" do
85
+ expect(environments[0].dirname).to eq 'master'
86
+ expect(environments[1].dirname).to eq 'production'
87
+ expect(environments[2].dirname).to eq 'not_dev_test_me'
88
+ end
89
+ end
90
+
91
+ describe "filtering branches with ignore prefixes" do
92
+ let(:branches) { ['master', 'development', 'production', 'not_dev_test_me', 'dev_test', 'dev', 'test_2'] }
93
+ let(:ignore_prefixes) { ['dev', 'test'] }
94
+
95
+ it "filters branches" do
96
+ expect(subject.filter_branches(branches, ignore_prefixes)).to eq(['master', 'production', 'not_dev_test_me'])
97
+ end
98
+ end
99
+ end
100
+
101
+ describe R10K::Source::Git, "handling invalid branch names" do
102
+ %w[correct_and_warn correct].each do |setting|
103
+ describe "when invalid is #{setting}" do
104
+ subject do
105
+ described_class.new('/some/nonexistent/dir', 'mysource', {
106
+ :remote => 'https://git-server/repo.git',
107
+ :invalid_branches => setting
108
+ })
109
+ end
110
+
111
+ before do
112
+ allow(subject.cache).to receive(:branches).and_return ['master', 'invalid-branch']
113
+ end
114
+
115
+ it "creates an environment for each branch" do
116
+ expect(subject.generate_environments.size).to eq(2)
117
+ end
118
+
119
+ it "removes invalid characters from branch names" do
120
+ invalid_env = subject.generate_environments.last
121
+ expect(invalid_env.dirname).to eq 'invalid_branch'
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "when invalid is 'error'" do
127
+ subject do
128
+ described_class.new('/some/nonexistent/dir', 'mysource', {
129
+ :remote => 'https://git-server/repo.git',
130
+ :invalid_branches => 'error',
131
+ })
132
+ end
133
+
134
+ before do
135
+ allow(subject.cache).to receive(:branches).and_return ['master', 'invalid-branch']
136
+ end
137
+
138
+ it "only creates an environment for valid branches" do
139
+ expect(subject.generate_environments.size).to eq(1)
140
+ end
141
+ end
142
+ end
143
+
144
+ # Since prefixing is an immutable property of a source, it's easier to create
145
+ # a new context and duplicate stubs in a single location rather than packing a
146
+ # single test with all the stubs that entirely recreate the source.
147
+ describe R10K::Source::Git, 'when prefixing is enabled' do
148
+ subject do
149
+ described_class.new(
150
+ 'prefixed',
151
+ '/some/nonexistent/dir',
152
+ {
153
+ :prefix => true,
154
+ :remote => 'https://git-server/repo.git',
155
+ })
156
+ end
157
+
158
+ describe "generating prefixed environments" do
159
+ before do
160
+ allow(subject.cache).to receive(:cached?).and_return true
161
+ allow(subject.cache).to receive(:branches).and_return %w[master other]
162
+ end
163
+
164
+ let(:environments) { subject.environments }
165
+
166
+ it "creates an environment for each branch" do
167
+ expect(subject.environments.size).to eq(2)
168
+ end
169
+
170
+ it "prefixes the source name to environments when prefixing is enabled" do
171
+ expect(environments[0].dirname).to eq 'prefixed_master'
172
+ expect(environments[1].dirname).to eq 'prefixed_other'
173
+ end
174
+ end
175
+ end
176
+
177
+ describe R10K::Source::Git, 'registering as a source' do
178
+ it "registers with the :git key" do
179
+ expect(R10K::Source.retrieve(:git)).to eq described_class
180
+ end
181
+
182
+ it "registers with the nil key" do
183
+ expect(R10K::Source.retrieve(nil)).to eq described_class
184
+ end
185
+ end