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,68 @@
1
+ require 'spec_helper'
2
+ require 'r10k/initializers'
3
+
4
+ describe R10K::Initializers::GitInitializer do
5
+ it "configures the Git provider" do
6
+ subject = described_class.new({:provider => :rugged})
7
+ expect(R10K::Git).to receive(:provider=).with(:rugged)
8
+ subject.call
9
+ end
10
+
11
+ it "configures the Git username" do
12
+ subject = described_class.new({:username => 'git'})
13
+ expect(R10K::Git.settings).to receive(:[]=).with(:username, 'git')
14
+ subject.call
15
+ end
16
+
17
+ it "configures the Git private key" do
18
+ subject = described_class.new({:private_key => '/etc/puppetlabs/r10k/id_rsa'})
19
+ expect(R10K::Git.settings).to receive(:[]=).with(:private_key, '/etc/puppetlabs/r10k/id_rsa')
20
+ subject.call
21
+ end
22
+ end
23
+
24
+ describe R10K::Initializers::ForgeInitializer do
25
+ it "sets the PuppetForge host" do
26
+ subject = described_class.new({:baseurl => 'https://my.site.forge'})
27
+ expect(PuppetForge).to receive(:host=).with('https://my.site.forge')
28
+ subject.call
29
+ end
30
+
31
+ it "configures PuppetForge connection proxy" do
32
+ subject = described_class.new({:proxy => 'http://my.site.proxy:3128'})
33
+ expect(PuppetForge::Connection).to receive(:proxy=).with('http://my.site.proxy:3128')
34
+ subject.call
35
+ end
36
+ end
37
+
38
+ describe R10K::Initializers::GlobalInitializer do
39
+ it "logs a warning if purgedirs was set" do
40
+ subject = described_class.new({:purgedirs => 'This setting has been deprecated for over two years :('})
41
+ expect(subject.logger).to receive(:warn).with('the purgedirs key in r10k.yaml is deprecated. it is currently ignored.')
42
+ subject.call
43
+ end
44
+
45
+ it "sets the Git cache_root" do
46
+ subject = described_class.new({:cachedir => '/var/cache/r10k'})
47
+ expect(R10K::Git::Cache.settings).to receive(:[]=).with(:cache_root, '/var/cache/r10k')
48
+ subject.call
49
+ end
50
+
51
+ it "delegates git settings to the Git initializer" do
52
+ git = instance_double('R10K::Initializers::GitInitializer')
53
+ expect(git).to receive(:call)
54
+ expect(R10K::Initializers::GitInitializer).to receive(:new).and_return(git)
55
+
56
+ subject = described_class.new({:git => {}})
57
+ subject.call
58
+ end
59
+
60
+ it "delegates forge settings to the Forge initializer" do
61
+ forge = instance_double('R10K::Initializers::ForgeInitializer')
62
+ expect(forge).to receive(:call)
63
+ expect(R10K::Initializers::ForgeInitializer).to receive(:new).and_return(forge)
64
+
65
+ subject = described_class.new({:forge => {}})
66
+ subject.call
67
+ end
68
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ require 'r10k/instance_cache'
4
+
5
+ describe R10K::InstanceCache do
6
+
7
+ describe "setting up a new instance cache" do
8
+ let(:klass) do
9
+ dubs = double('test class')
10
+ allow(dubs).to receive(:new) { |*args| args }
11
+ dubs
12
+ end
13
+
14
+ it "can create new objects" do
15
+ registry = described_class.new(klass)
16
+ expect(registry.generate).to eq []
17
+ end
18
+
19
+ describe "defining object arity" do
20
+
21
+ it "handles unary objects" do
22
+ expect(klass).to receive(:new).with(:foo)
23
+
24
+ registry = described_class.new(klass)
25
+ expect(registry.generate(:foo)).to eq [:foo]
26
+ end
27
+
28
+ it "handles ternary objects" do
29
+ expect(klass).to receive(:new).with(:foo, :bar, :baz)
30
+
31
+ registry = described_class.new(klass)
32
+ expect(registry.generate(:foo, :bar, :baz)).to eq [:foo, :bar, :baz]
33
+ end
34
+
35
+ it 'handles n-ary objects' do
36
+ args = %w[a bunch of arbitrary objects]
37
+ expect(klass).to receive(:new).with(*args)
38
+
39
+ registry = described_class.new(klass)
40
+ expect(registry.generate(*args)).to eq args
41
+ end
42
+
43
+ it 'fails when the required arguments are not matched' do
44
+ expect(klass).to receive(:new).and_raise ArgumentError, "not enough args"
45
+
46
+ registry = described_class.new(klass)
47
+ expect { registry.generate('arity is hard') }.to raise_error ArgumentError, "not enough args"
48
+ end
49
+ end
50
+
51
+ it "can specify the constructor method" do
52
+ expect(klass).to receive(:from_json).and_return "this is json, right?"
53
+
54
+ registry = described_class.new(klass, :from_json)
55
+ expect(registry.generate).to eq "this is json, right?"
56
+ end
57
+ end
58
+
59
+
60
+ it "returns a memoized object if it's been created before" do
61
+ registry = described_class.new(String)
62
+ first = registry.generate "bam!"
63
+ second = registry.generate "bam!"
64
+
65
+ expect(first.object_id).to eq second.object_id
66
+ end
67
+
68
+ it 'can clear registered objects' do
69
+ registry = described_class.new(String)
70
+
71
+ first = registry.generate "bam!"
72
+ registry.clear!
73
+ second = registry.generate "bam!"
74
+
75
+ expect(first.object_id).to_not eq second.object_id
76
+
77
+ end
78
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'r10k/keyed_factory'
3
+
4
+ describe R10K::KeyedFactory do
5
+
6
+ let(:registered) { Class.new }
7
+
8
+ describe "registering implementations" do
9
+ it "can register new implementations" do
10
+ subject.register(:klass, registered)
11
+ expect(subject.retrieve(:klass)).to eq registered
12
+ end
13
+
14
+ it "raises an error when a duplicate implementation is registered" do
15
+ subject.register(:klass, registered)
16
+
17
+ expect {
18
+ subject.register(:klass, registered)
19
+ }.to raise_error(R10K::KeyedFactory::DuplicateImplementationError)
20
+ end
21
+
22
+ it "can register classes with nil as a key" do
23
+ subject.register(nil, registered)
24
+ expect(subject.retrieve(nil)).to eq registered
25
+ end
26
+ end
27
+
28
+ describe "generating instances" do
29
+ before do
30
+ subject.register(:klass, registered)
31
+ end
32
+
33
+ it "generates an instance with the associated class" do
34
+ instance = subject.generate(:klass)
35
+ expect(instance).to be_a_kind_of registered
36
+ end
37
+
38
+ it "can generate a class with nil as a key" do
39
+ other = Class.new
40
+ subject.register(nil, other)
41
+ instance = subject.generate(nil)
42
+ expect(instance).to be_a_kind_of other
43
+ end
44
+
45
+ it "raises an error if no implementation was registered with the given key" do
46
+ expect {
47
+ subject.generate(:foo)
48
+ }.to raise_error(R10K::KeyedFactory::UnknownImplementationError)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+ require 'r10k/logging/terminaloutputter'
4
+
5
+ describe R10K::Logging::TerminalOutputter do
6
+
7
+ let(:stream) { StringIO.new }
8
+
9
+ let(:formatter) do
10
+ Class.new(Log4r::Formatter) do
11
+ def format(logevent)
12
+ logevent.data
13
+ end
14
+ end
15
+ end
16
+
17
+ subject do
18
+ described_class.new('test', stream, :level => 0, :formatter => formatter).tap do |o|
19
+ o.use_color = true
20
+ end
21
+ end
22
+
23
+ tests = [
24
+ [:debug2, :cyan],
25
+ [:debug1, :cyan],
26
+ [:debug, :green],
27
+ [:info, nil],
28
+ [:notice, nil],
29
+ [:warn, :yellow],
30
+ [:error, :red],
31
+ [:fatal, :red],
32
+ ]
33
+
34
+ tests.each_with_index do |(level, color), index|
35
+ # Note for the unwary - using a loop in this manner shows strange
36
+ # behavior with variable closure. The describe block is needed to retain
37
+ # the loop variables for each test; without this the let helpers are
38
+ # overwritten and the last set of helpers are used for all tests.
39
+ describe "at level #{level}" do
40
+ let(:message) { "level #{level}: #{color}" }
41
+
42
+ let(:event) do
43
+ Log4r::LogEvent.new(index + 1, Log4r::Logger.new('test::logger'), nil, message)
44
+ end
45
+
46
+ it "logs messages as #{color ? color : "uncolored"}" do
47
+ output = color.nil? ? message : message.send(color)
48
+ subject.send(level, event)
49
+ expect(stream.string).to eq output
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ require 'r10k/logging'
3
+
4
+ describe R10K::Logging do
5
+
6
+ describe "parsing a log level" do
7
+ it "parses 'true:TrueClass' as INFO" do
8
+ expect(described_class.parse_level(true)).to eq Log4r::INFO
9
+ end
10
+
11
+ it "parses 'true:String' as nil" do
12
+ expect(described_class.parse_level("true")).to be_nil
13
+ end
14
+
15
+ it "parses a numeric string as an integer" do
16
+ expect(described_class.parse_level('2')).to eq 2
17
+ end
18
+
19
+ it "parses a log level string as a log level" do
20
+ expect(described_class.parse_level('debug')).to eq Log4r::DEBUG
21
+ end
22
+
23
+ it "returns nil when given an invalid log level" do
24
+ expect(described_class.parse_level('deblag')).to be_nil
25
+ end
26
+ end
27
+
28
+ describe "setting the log level" do
29
+ after(:all) { R10K::Logging.level = 'warn' }
30
+
31
+ it "sets the outputter log level" do
32
+ expect(described_class.outputter).to receive(:level=).with(Log4r::DEBUG)
33
+ described_class.level = 'debug'
34
+ end
35
+
36
+ it "stores the new log level" do
37
+ allow(described_class.outputter).to receive(:level=)
38
+ described_class.level = 'debug'
39
+ expect(described_class.level).to eq(Log4r::DEBUG)
40
+ end
41
+
42
+ it "raises an exception when given an invalid log level" do
43
+ expect {
44
+ described_class.level = 'deblag'
45
+ }.to raise_error(ArgumentError, /Invalid log level/)
46
+ end
47
+
48
+ describe "switching the formatter" do
49
+ before do
50
+ allow(described_class.outputter).to receive(:level=)
51
+ end
52
+
53
+ it "switches to the debug formatter if the new log level is debug or greater" do
54
+ debug_formatter = double('debug formatter')
55
+ expect(described_class).to receive(:debug_formatter).and_return(debug_formatter)
56
+ expect(described_class.outputter).to receive(:formatter=).with(debug_formatter)
57
+ described_class.level = 'debug'
58
+ end
59
+
60
+ it "switches to the default formatter if the new log level is info or less" do
61
+ default_formatter = double('default formatter')
62
+ expect(described_class).to receive(:default_formatter).and_return(default_formatter)
63
+ expect(described_class.outputter).to receive(:formatter=).with(default_formatter)
64
+ described_class.level = 'info'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'r10k/module/base'
3
+
4
+ describe R10K::Module::Base do
5
+ describe "parsing the title" do
6
+ it "parses titles with no owner" do
7
+ m = described_class.new('eight_hundred', '/moduledir', [])
8
+ expect(m.name).to eq 'eight_hundred'
9
+ expect(m.owner).to be_nil
10
+ end
11
+
12
+ it "parses forward slash separated titles" do
13
+ m = described_class.new('branan/eight_hundred', '/moduledir', [])
14
+ expect(m.name).to eq 'eight_hundred'
15
+ expect(m.owner).to eq 'branan'
16
+ end
17
+
18
+ it "parses hyphen separated titles" do
19
+ m = described_class.new('branan-eight_hundred', '/moduledir', [])
20
+ expect(m.name).to eq 'eight_hundred'
21
+ expect(m.owner).to eq 'branan'
22
+ end
23
+
24
+ it "raises an error when the title is not correctly formatted" do
25
+ expect {
26
+ described_class.new('branan!eight_hundred', '/moduledir', [])
27
+ }.to raise_error(ArgumentError, "Module name (branan!eight_hundred) must match either 'modulename' or 'owner/modulename'")
28
+ end
29
+ end
30
+
31
+ describe "path variables" do
32
+ it "uses the module name as the name" do
33
+ m = described_class.new('eight_hundred', '/moduledir', [])
34
+ expect(m.dirname).to eq '/moduledir'
35
+ expect(m.path).to eq(Pathname.new('/moduledir/eight_hundred'))
36
+ end
37
+
38
+ it "does not include the owner in the path" do
39
+ m = described_class.new('branan/eight_hundred', '/moduledir', [])
40
+ expect(m.dirname).to eq '/moduledir'
41
+ expect(m.path).to eq(Pathname.new('/moduledir/eight_hundred'))
42
+ end
43
+ end
44
+
45
+ describe "with alternate variable names" do
46
+ subject do
47
+ described_class.new('branan/eight_hundred', '/moduledir', [])
48
+ end
49
+
50
+ it "aliases full_name to title" do
51
+ expect(subject.full_name).to eq 'branan-eight_hundred'
52
+ end
53
+
54
+ it "aliases author to owner" do
55
+ expect(subject.author).to eq 'branan'
56
+ end
57
+
58
+ it "aliases basedir to dirname" do
59
+ expect(subject.basedir).to eq '/moduledir'
60
+ end
61
+ end
62
+
63
+ describe "accepting a visitor" do
64
+ subject { described_class.new('branan-eight_hundred', '/moduledir', []) }
65
+
66
+ it "passes itself to the visitor" do
67
+ visitor = spy('visitor')
68
+ expect(visitor).to receive(:visit).with(:module, subject)
69
+ subject.accept(visitor)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,207 @@
1
+ require 'r10k/module/forge'
2
+ require 'spec_helper'
3
+
4
+ describe R10K::Module::Forge do
5
+ # TODO: make these *unit* tests not depend on a real module on the real Forge :(
6
+
7
+ include_context 'fail on execution'
8
+
9
+ let(:fixture_modulepath) { File.expand_path('spec/fixtures/module/forge', PROJECT_ROOT) }
10
+ let(:empty_modulepath) { File.expand_path('spec/fixtures/empty', PROJECT_ROOT) }
11
+
12
+ describe "implementing the Puppetfile spec" do
13
+ it "should implement 'branan/eight_hundred', '8.0.0'" do
14
+ expect(described_class).to be_implement('branan/eight_hundred', '8.0.0')
15
+ end
16
+
17
+ it "should implement 'branan-eight_hundred', '8.0.0'" do
18
+ expect(described_class).to be_implement('branan-eight_hundred', '8.0.0')
19
+ end
20
+
21
+ it "should fail with an invalid title" do
22
+ expect(described_class).to_not be_implement('branan!eight_hundred', '8.0.0')
23
+ end
24
+ end
25
+
26
+ describe "setting attributes" do
27
+ subject { described_class.new('branan/eight_hundred', '/moduledir', '8.0.0') }
28
+
29
+ it "sets the name" do
30
+ expect(subject.name).to eq 'eight_hundred'
31
+ end
32
+
33
+ it "sets the author" do
34
+ expect(subject.author).to eq 'branan'
35
+ end
36
+
37
+ it "sets the dirname" do
38
+ expect(subject.dirname).to eq '/moduledir'
39
+ end
40
+
41
+ it "sets the title" do
42
+ expect(subject.title).to eq 'branan-eight_hundred'
43
+ end
44
+ end
45
+
46
+ describe "properties" do
47
+ subject { described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0') }
48
+
49
+ it "sets the module type to :forge" do
50
+ expect(subject.properties).to include(:type => :forge)
51
+ end
52
+
53
+ it "sets the expected version" do
54
+ expect(subject.properties).to include(:expected => '8.0.0')
55
+ end
56
+
57
+ it "sets the actual version" do
58
+ expect(subject).to receive(:current_version).and_return('0.8.0')
59
+ expect(subject.properties).to include(:actual => '0.8.0')
60
+ end
61
+ end
62
+
63
+ context "when a module is deprecated" do
64
+ subject { described_class.new('puppetlabs/corosync', fixture_modulepath, :latest) }
65
+
66
+ it "warns on sync if module is not already insync" do
67
+ allow(subject).to receive(:status).and_return(:absent)
68
+
69
+ allow(R10K::Forge::ModuleRelease).to receive(:new).and_return(double('mod_release', install: true))
70
+
71
+ logger_dbl = double(Log4r::Logger)
72
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger_dbl)
73
+
74
+ expect(logger_dbl).to receive(:warn).with(/puppet forge module.*puppetlabs-corosync.*has been deprecated/i)
75
+
76
+ subject.sync
77
+ end
78
+
79
+ it "does not warn on sync if module is already insync" do
80
+ allow(subject).to receive(:status).and_return(:insync)
81
+
82
+ logger_dbl = double(Log4r::Logger)
83
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger_dbl)
84
+
85
+ expect(logger_dbl).to_not receive(:warn).with(/puppet forge module.*puppetlabs-corosync.*has been deprecated/i)
86
+
87
+ subject.sync
88
+ end
89
+ end
90
+
91
+ describe '#expected_version' do
92
+ it "returns an explicitly given expected version" do
93
+ subject = described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0')
94
+ expect(subject.expected_version).to eq '8.0.0'
95
+ end
96
+
97
+ it "uses the latest version from the forge when the version is :latest" do
98
+ subject = described_class.new('branan/eight_hundred', fixture_modulepath, :latest)
99
+ expect(subject.v3_module).to receive_message_chain(:current_release, :version).and_return('8.8.8')
100
+ expect(subject.expected_version).to eq '8.8.8'
101
+ end
102
+ end
103
+
104
+ describe "determining the status" do
105
+
106
+ subject { described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0') }
107
+
108
+ it "is :absent if the module directory is absent" do
109
+ allow(subject).to receive(:exist?).and_return false
110
+ expect(subject.status).to eq :absent
111
+ end
112
+
113
+ it "is :mismatched if there is no module metadata" do
114
+ allow(subject).to receive(:exist?).and_return true
115
+ allow(File).to receive(:exist?).and_return false
116
+
117
+ expect(subject.status).to eq :mismatched
118
+ end
119
+
120
+ it "is :mismatched if module was previously a git checkout" do
121
+ allow(File).to receive(:directory?).and_return true
122
+
123
+ expect(subject.status).to eq :mismatched
124
+ end
125
+
126
+ it "is :mismatched if the metadata author doesn't match the expected author" do
127
+ allow(subject).to receive(:exist?).and_return true
128
+
129
+ allow(subject.instance_variable_get(:@metadata_file)).to receive(:read).and_return subject.metadata
130
+ allow(subject.metadata).to receive(:full_module_name).and_return 'blargh-blargh'
131
+
132
+ expect(subject.status).to eq :mismatched
133
+ end
134
+
135
+ it "is :outdated if the metadata version doesn't match the expected version" do
136
+ allow(subject).to receive(:exist?).and_return true
137
+
138
+ allow(subject.instance_variable_get(:@metadata_file)).to receive(:read).and_return subject.metadata
139
+ allow(subject.metadata).to receive(:version).and_return '7.0.0'
140
+ expect(subject.status).to eq :outdated
141
+ end
142
+
143
+ it "is :insync if the version and the author are in sync" do
144
+ allow(subject).to receive(:exist?).and_return true
145
+
146
+ expect(subject.status).to eq :insync
147
+ end
148
+ end
149
+
150
+ describe "#sync" do
151
+ subject { described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0') }
152
+
153
+ it 'does nothing when the module is in sync' do
154
+ allow(subject).to receive(:status).and_return :insync
155
+
156
+ expect(subject).to receive(:install).never
157
+ expect(subject).to receive(:upgrade).never
158
+ expect(subject).to receive(:reinstall).never
159
+ subject.sync
160
+ end
161
+
162
+ it 'reinstalls the module when it is mismatched' do
163
+ allow(subject).to receive(:status).and_return :mismatched
164
+ expect(subject).to receive(:reinstall)
165
+ subject.sync
166
+ end
167
+
168
+ it 'upgrades the module when it is outdated' do
169
+ allow(subject).to receive(:status).and_return :outdated
170
+ expect(subject).to receive(:upgrade)
171
+ subject.sync
172
+ end
173
+
174
+ it 'installs the module when it is absent' do
175
+ allow(subject).to receive(:status).and_return :absent
176
+ expect(subject).to receive(:install)
177
+ subject.sync
178
+ end
179
+ end
180
+
181
+ describe '#install' do
182
+ it 'installs the module from the forge' do
183
+ subject = described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0')
184
+ release = instance_double('R10K::Forge::ModuleRelease')
185
+ expect(R10K::Forge::ModuleRelease).to receive(:new).with('branan-eight_hundred', '8.0.0').and_return(release)
186
+ expect(release).to receive(:install).with(subject.path)
187
+ subject.install
188
+ end
189
+ end
190
+
191
+ describe '#uninstall' do
192
+ it 'removes the module path' do
193
+ subject = described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0')
194
+ expect(FileUtils).to receive(:rm_rf).with(subject.path.to_s)
195
+ subject.uninstall
196
+ end
197
+ end
198
+
199
+ describe '#reinstall' do
200
+ it 'uninstalls and then installs the module' do
201
+ subject = described_class.new('branan/eight_hundred', fixture_modulepath, '8.0.0')
202
+ expect(subject).to receive(:uninstall)
203
+ expect(subject).to receive(:install)
204
+ subject.reinstall
205
+ end
206
+ end
207
+ end