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,51 @@
1
+ require 'r10k/util/subprocess'
2
+ require 'json'
3
+ require 'yaml'
4
+
5
+ class R10K::Source::Exec < R10K::Source::Hash
6
+ R10K::Source.register(:exec, self)
7
+
8
+ def initialize(name, basedir, options = {})
9
+ unless @command = options[:command]
10
+ raise ConfigError, _('Environment source %{name} missing required parameter: command') % {name: name}
11
+ end
12
+
13
+ # We haven't set the environments option yet. We will do that by
14
+ # overloading the #environments method.
15
+ super(name, basedir, options)
16
+ end
17
+
18
+ def environments_hash
19
+ @environments_hash ||= set_environments_hash(run_environments_command)
20
+ end
21
+
22
+ private
23
+
24
+ def run_environments_command
25
+ subproc = R10K::Util::Subprocess.new([@command])
26
+ subproc.raise_on_fail = true
27
+ subproc.logger = self.logger
28
+ procresult = subproc.execute
29
+
30
+ begin
31
+ environments = JSON.parse(procresult.stdout)
32
+ rescue JSON::ParserError => json_err
33
+ begin
34
+ environments = YAML.safe_load(procresult.stdout)
35
+ rescue Psych::SyntaxError => yaml_err
36
+ raise R10K::Error, _("Error parsing command output for exec source %{name}:\n" \
37
+ "Not valid JSON: %{j_msg}\n" \
38
+ "Not valid YAML: %{y_msg}\n" \
39
+ "Stdout:\n%{out}") % {name: name, j_msg: json_err.message, y_msg: yaml_err.message, out: procresult.stdout}
40
+ end
41
+ end
42
+
43
+ unless R10K::Source::Hash.valid_environments_hash?(environments)
44
+ raise R10K::Error, _("Environment source %{name} command %{cmd} did not return valid environment data.\n" \
45
+ 'Returned: %{data}') % {name: name, cmd: @command, data: environments}
46
+ end
47
+
48
+ # Return the resulting environments hash
49
+ environments
50
+ end
51
+ end
@@ -0,0 +1,142 @@
1
+ require 'r10k/git'
2
+ require 'r10k/environment'
3
+ require 'r10k/environment/name'
4
+
5
+ # This class implements a source for Git environments.
6
+ #
7
+ # A Git source generates environments by locally caching the given Git
8
+ # repository and enumerating the branches for the Git repository. Branches
9
+ # are mapped to environments without modification.
10
+ #
11
+ # @since 1.3.0
12
+ class R10K::Source::Git < R10K::Source::Base
13
+
14
+ include R10K::Logging
15
+
16
+ R10K::Source.register(:git, self)
17
+ # Register git as the default source
18
+ R10K::Source.register(nil, self)
19
+
20
+ # @!attribute [r] remote
21
+ # @return [String] The URL to the remote git repository
22
+ attr_reader :remote
23
+
24
+ # @!attribute [r] cache
25
+ # @api private
26
+ # @return [R10K::Git::Cache] The git cache associated with this source
27
+ attr_reader :cache
28
+
29
+ # @!attribute [r] settings
30
+ # @return [Hash<Symbol, Object>] Additional settings that configure how
31
+ # the source should behave.
32
+ attr_reader :settings
33
+
34
+ # @!attribute [r] invalid_branches
35
+ # @return [String] How Git branch names that cannot be cleanly mapped to
36
+ # Puppet environments will be handled.
37
+ attr_reader :invalid_branches
38
+
39
+ # @!attribute [r] ignore_branch_prefixes
40
+ # @return [Array<String>] Array of strings used to remove repository branches
41
+ # that will be deployed as environments.
42
+ attr_reader :ignore_branch_prefixes
43
+
44
+ # Initialize the given source.
45
+ #
46
+ # @param name [String] The identifier for this source.
47
+ # @param basedir [String] The base directory where the generated environments will be created.
48
+ # @param options [Hash] An additional set of options for this source.
49
+ #
50
+ # @option options [Boolean, String] :prefix If a String this becomes the prefix.
51
+ # If true, will use the source name as the prefix.
52
+ # Defaults to false for no environment prefix.
53
+ # @option options [String] :remote The URL to the base directory of the SVN repository
54
+ # @option options [Hash] :remote Additional settings that configure how the
55
+ # source should behave.
56
+ def initialize(name, basedir, options = {})
57
+ super
58
+
59
+ @environments = []
60
+
61
+ @remote = options[:remote]
62
+ @invalid_branches = (options[:invalid_branches] || 'correct_and_warn')
63
+ @ignore_branch_prefixes = options[:ignore_branch_prefixes]
64
+
65
+ @cache = R10K::Git.cache.generate(@remote)
66
+ end
67
+
68
+ # Update the git cache for this git source to get the latest list of environments.
69
+ #
70
+ # @return [void]
71
+ def preload!
72
+ logger.debug _("Fetching '%{remote}' to determine current branches.") % {remote: @remote}
73
+ @cache.sync
74
+ rescue => e
75
+ raise R10K::Error.wrap(e, _("Unable to determine current branches for Git source '%{name}' (%{basedir})") % {name: @name, basedir: @basedir})
76
+ end
77
+ alias fetch_remote preload!
78
+
79
+ # Load the git remote and create environments for each branch. If the cache
80
+ # has not been fetched, this will return an empty list.
81
+ #
82
+ # @return [Array<R10K::Environment::Git>]
83
+ def environments
84
+ if not @cache.cached?
85
+ []
86
+ elsif @environments.empty?
87
+ @environments = generate_environments()
88
+ else
89
+ @environments
90
+ end
91
+ end
92
+
93
+ def generate_environments
94
+ envs = []
95
+ branch_names.each do |bn|
96
+ if bn.valid?
97
+ envs << R10K::Environment::Git.new(bn.name, @basedir, bn.dirname,
98
+ {:remote => remote, :ref => bn.name, :puppetfile_name => puppetfile_name })
99
+ elsif bn.correct?
100
+ logger.warn _("Environment %{env_name} contained non-word characters, correcting name to %{corrected_env_name}") % {env_name: bn.name.inspect, corrected_env_name: bn.dirname}
101
+ envs << R10K::Environment::Git.new(bn.name, @basedir, bn.dirname,
102
+ {:remote => remote, :ref => bn.name, :puppetfile_name => puppetfile_name})
103
+ elsif bn.validate?
104
+ logger.error _("Environment %{env_name} contained non-word characters, ignoring it.") % {env_name: bn.name.inspect}
105
+ end
106
+ end
107
+
108
+ envs
109
+ end
110
+
111
+ # List all environments that should exist in the basedir for this source
112
+ # @note This is required by {R10K::Util::Basedir}
113
+ # @return [Array<String>]
114
+ def desired_contents
115
+ environments.map {|env| env.dirname }
116
+ end
117
+
118
+ def filter_branches(branches, ignore_prefixes)
119
+ filter = Regexp.new("^#{Regexp.union(ignore_prefixes)}")
120
+ branches = branches.reject do |branch|
121
+ result = filter.match(branch)
122
+ if result
123
+ logger.warn _("Branch %{branch} filtered out by ignore_branch_prefixes %{ibp}") % {branch: branch, ibp: @ignore_branch_prefixes}
124
+ end
125
+ result
126
+ end
127
+ branches
128
+ end
129
+
130
+ private
131
+
132
+ def branch_names
133
+ opts = {:prefix => @prefix, :invalid => @invalid_branches, :source => @name}
134
+ branches = @cache.branches
135
+ if @ignore_branch_prefixes && !@ignore_branch_prefixes.empty?
136
+ branches = filter_branches(branches, @ignore_branch_prefixes)
137
+ end
138
+ branches.map do |branch|
139
+ R10K::Environment::Name.new(branch, opts)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,182 @@
1
+ # This class implements an environment source based on recieving a hash of
2
+ # environments
3
+ #
4
+ # @since 3.4.0
5
+ #
6
+ # DESCRIPTION
7
+ #
8
+ # This class implements environments defined by a hash having the following
9
+ # schema:
10
+ #
11
+ # ---
12
+ # type: object
13
+ # additionalProperties:
14
+ # type: object
15
+ # properties:
16
+ # type:
17
+ # type: string
18
+ # basedir:
19
+ # type: string
20
+ # modules:
21
+ # type: object
22
+ # additionalProperties:
23
+ # type: object
24
+ # moduledir:
25
+ # type: string
26
+ # additionalProperties:
27
+ # type: string
28
+ #
29
+ # The top-level keys in the hash are environment names. Keys in individual
30
+ # environments should be the same as those which would be given to define a
31
+ # single source in r10k.yaml. Additionally, the "modules" key (and moduledir)
32
+ # can be used to designate module content for the environment, independent of
33
+ # the base source parameters.
34
+ #
35
+ # Example:
36
+ #
37
+ # ---
38
+ # production:
39
+ # type: git
40
+ # remote: 'https://github.com/reidmv/control-repo.git'
41
+ # ref: '1.0.0'
42
+ # modules:
43
+ # geoffwilliams-r_profile: '1.1.0'
44
+ # geoffwilliams-r_role: '2.0.0'
45
+ #
46
+ # development:
47
+ # type: git
48
+ # remote: 'https://github.com/reidmv/control-repo.git'
49
+ # ref: 'master'
50
+ # modules:
51
+ # geoffwilliams-r_profile: '1.1.0'
52
+ # geoffwilliams-r_role: '2.0.0'
53
+ #
54
+ # USAGE
55
+ #
56
+ # The following is an example implementation class showing how to use the
57
+ # R10K::Source::Hash abstract base class. Assume an r10k.yaml file such as:
58
+ #
59
+ # ---
60
+ # sources:
61
+ # proof-of-concept:
62
+ # type: demo
63
+ # basedir: '/etc/puppetlabs/code/environments'
64
+ #
65
+ # Class implementation:
66
+ #
67
+ # class R10K::Source::Demo < R10K::Source::Hash
68
+ # R10K::Source.register(:demo, self)
69
+ #
70
+ # def initialize(name, basedir, options = {})
71
+ # # This is just a demo class, so we hard-code an example :environments
72
+ # # hash here. In a real class, we might do something here such as
73
+ # # perform an API call to retrieve an :environments hash.
74
+ # options[:environments] = {
75
+ # 'production' => {
76
+ # 'remote' => 'https://git.example.com/puppet/control-repo.git',
77
+ # 'ref' => 'release-141',
78
+ # 'modules' => {
79
+ # 'puppetlabs-stdlib' => '6.1.0',
80
+ # 'puppetlabs-ntp' => '8.1.0',
81
+ # 'example-myapp1' => {
82
+ # 'git' => 'https://git.example.com/puppet/example-myapp1.git',
83
+ # 'ref' => 'v1.3.0',
84
+ # },
85
+ # },
86
+ # },
87
+ # 'development' => {
88
+ # 'remote' => 'https://git.example.com/puppet/control-repo.git',
89
+ # 'ref' => 'master',
90
+ # 'modules' => {
91
+ # 'puppetlabs-stdlib' => '6.1.0',
92
+ # 'puppetlabs-ntp' => '8.1.0',
93
+ # 'example-myapp1' => {
94
+ # 'git' => 'https://git.example.com/puppet/example-myapp1.git',
95
+ # 'ref' => 'v1.3.1',
96
+ # },
97
+ # },
98
+ # },
99
+ # }
100
+ #
101
+ # # All we need to do is supply options with the :environments hash.
102
+ # # The R10K::Source::Hash parent class takes care of the rest.
103
+ # super(name, basedir, options)
104
+ # end
105
+ # end
106
+ #
107
+ # Example output:
108
+ #
109
+ # [root@master:~] % r10k deploy environment production -pv
110
+ # INFO -> Using Puppetfile '/etc/puppetlabs/code/environments/production/Puppetfile'
111
+ # INFO -> Using Puppetfile '/etc/puppetlabs/code/environments/development/Puppetfile'
112
+ # INFO -> Deploying environment /etc/puppetlabs/code/environments/production
113
+ # INFO -> Environment production is now at 74ea2e05bba796918e4ff1803018c526337ef5f3
114
+ # INFO -> Deploying Environment content /etc/puppetlabs/code/environments/production/modules/stdlib
115
+ # INFO -> Deploying Environment content /etc/puppetlabs/code/environments/production/modules/ntp
116
+ # INFO -> Deploying Environment content /etc/puppetlabs/code/environments/production/modules/myapp1
117
+ # INFO -> Deploying Puppetfile content /etc/puppetlabs/code/environments/production/modules/ruby_task_helper
118
+ # INFO -> Deploying Puppetfile content /etc/puppetlabs/code/environments/production/modules/bolt_shim
119
+ # INFO -> Deploying Puppetfile content /etc/puppetlabs/code/environments/production/modules/apply_helpers
120
+ #
121
+ class R10K::Source::Hash < R10K::Source::Base
122
+
123
+ include R10K::Logging
124
+
125
+ # @param hash [Hash] A hash to validate.
126
+ # @return [Boolean] False if the hash is obviously invalid. A true return
127
+ # means _maybe_ it's valid.
128
+ def self.valid_environments_hash?(hash)
129
+ # TODO: more robust schema valiation
130
+ hash.is_a?(Hash)
131
+ end
132
+
133
+ # @param name [String] The identifier for this source.
134
+ # @param basedir [String] The base directory where the generated environments will be created.
135
+ # @param options [Hash] An additional set of options for this source. The
136
+ # semantics of this hash may depend on the source implementation.
137
+ #
138
+ # @option options [Boolean, String] :prefix If a String this becomes the prefix.
139
+ # If true, will use the source name as the prefix. All sources should respect this option.
140
+ # Defaults to false for no environment prefix.
141
+ # @option options [Hash] :environments The hash definition of environments
142
+ def initialize(name, basedir, options = {})
143
+ super(name, basedir, options)
144
+ end
145
+
146
+ # Set the environment hash for the source. The environment hash is what the
147
+ # source uses to generate enviroments.
148
+ # @param hash [Hash] The hash to sanitize and use as the source's environments.
149
+ # Should be formatted for use with R10K::Environment#from_hash.
150
+ def set_environments_hash(hash)
151
+ @environments_hash = hash.reduce({}) do |memo,(name,opts)|
152
+ R10K::Util::SymbolizeKeys.symbolize_keys!(opts)
153
+ memo.merge({
154
+ name => opts.merge({
155
+ :basedir => @basedir,
156
+ :dirname => R10K::Environment::Name.new(name, {prefix: @prefix, source: @name}).dirname
157
+ })
158
+ })
159
+ end
160
+ end
161
+
162
+ # Return the sanitized environments hash for this source. The environments
163
+ # hash should contain objects formatted for use with R10K::Environment#from_hash.
164
+ # If the hash does not exist it will be built based on @options.
165
+ def environments_hash
166
+ @environments_hash ||= set_environments_hash(@options.fetch(:environments, {}))
167
+ end
168
+
169
+ def environments
170
+ @environments ||= environments_hash.map do |name, hash|
171
+ R10K::Environment.from_hash(name, hash)
172
+ end
173
+ end
174
+
175
+ # List all environments that should exist in the basedir for this source
176
+ # @note This is required by {R10K::Util::Basedir}
177
+ # @return [Array<String>]
178
+ def desired_contents
179
+ environments.map {|env| env.dirname }
180
+ end
181
+
182
+ end
@@ -0,0 +1,136 @@
1
+ require 'r10k/svn'
2
+ require 'r10k/environment'
3
+ require 'r10k/environment/name'
4
+ require 'r10k/util/setopts'
5
+
6
+ # This class implements a source for SVN environments.
7
+ #
8
+ # An SVN source generates environments by enumerating the branches and trunk
9
+ # for a given SVN remote. SVN repositories must conform to the conventional
10
+ # SVN repository structure with the directories trunk/, branches/, and
11
+ # optionally tags/ in the root of the repository. The trunk/ directory is
12
+ # specifically mapped to the production environment, branches are created
13
+ # as environments with the name of the given branch.
14
+ #
15
+ # @see http://svnbook.red-bean.com/en/1.7/svn.branchmerge.maint.html
16
+ # @since 1.3.0
17
+ class R10K::Source::SVN < R10K::Source::Base
18
+
19
+ R10K::Source.register(:svn, self)
20
+
21
+ # @!attribute [r] remote
22
+ # @return [String] The URL to the base directory of the SVN repository
23
+ attr_reader :remote
24
+
25
+ # @!attribute [r] svn_remote
26
+ # @api private
27
+ # @return [R10K::SVN::Remote]
28
+ attr_reader :svn_remote
29
+
30
+ # @!attribute [r] username
31
+ # @return [String, nil] The SVN username to be passed to the underlying SVN commands
32
+ # @api private
33
+ attr_reader :username
34
+
35
+ # @!attribute [r] password
36
+ # @return [String, nil] The SVN password to be passed to the underlying SVN commands
37
+ # @api private
38
+ attr_reader :password
39
+
40
+ # @!attribute [r] ignore_branch_prefixes
41
+ # @return [Array<String>] Array of strings used to remove repository branches
42
+ # that will be deployed as environments.
43
+ attr_reader :ignore_branch_prefixes
44
+
45
+ include R10K::Util::Setopts
46
+
47
+ # Initialize the given source.
48
+ #
49
+ # @param name [String] The identifier for this source.
50
+ # @param basedir [String] The base directory where the generated environments will be created.
51
+ # @param options [Hash] An additional set of options for this source.
52
+ #
53
+ # @option options [Boolean] :prefix Whether to prefix the source name to the
54
+ # environment directory names. Defaults to false.
55
+ # @option options [String] :remote The URL to the base directory of the SVN repository
56
+ # @option options [String] :username The SVN username
57
+ # @option options [String] :password The SVN password
58
+ # @option options [String] :puppetfile_name The puppetfile name
59
+ def initialize(name, basedir, options = {})
60
+ super
61
+
62
+ setopts(options, {:remote => :self, :username => :self, :password => :self, :puppetfile_name => :self })
63
+ @environments = []
64
+ @svn_remote = R10K::SVN::Remote.new(@remote, :username => @username, :password => @password)
65
+ @ignore_branch_prefixes = options[:ignore_branch_prefixes]
66
+ end
67
+
68
+ # Enumerate the environments associated with this SVN source.
69
+ #
70
+ # @return [Array<R10K::Environment::SVN>] An array of environments created
71
+ # from this source.
72
+ def environments
73
+ if @environments.empty?
74
+ @environments = generate_environments()
75
+ end
76
+
77
+ @environments
78
+ end
79
+
80
+ # Generate a list of currently available SVN environments
81
+ #
82
+ # @todo respect environment name corrections
83
+ #
84
+ # @api protected
85
+ # @return [Array<R10K::Environment::SVN>] An array of environments created
86
+ # from this source.
87
+ def generate_environments
88
+ names_and_paths.map do |(branch, path)|
89
+ options = {
90
+ :remote => path,
91
+ :username => @username,
92
+ :password => @password,
93
+ :puppetfile_name => puppetfile_name
94
+ }
95
+ R10K::Environment::SVN.new(branch.name, @basedir, branch.dirname, options)
96
+ end
97
+ end
98
+
99
+ # List all environments that should exist in the basedir for this source
100
+ # @note This is required by {R10K::Util::Basedir}
101
+ # @return [Array<String>]
102
+ def desired_contents
103
+ @environments.map {|env| env.dirname }
104
+ end
105
+
106
+ include R10K::Logging
107
+
108
+ def filter_branches(branches, ignore_prefixes)
109
+ filter = Regexp.new("^(#{ignore_prefixes.join('|')})")
110
+ branches = branches.reject do |branch|
111
+ result = filter.match(branch)
112
+ if result
113
+ logger.warn _("Branch %{branch} filtered out by ignore_branch_prefixes %{ibp}") % {branch: branch, ibp: @ignore_branch_prefixes}
114
+ end
115
+ result
116
+ end
117
+ branches
118
+ end
119
+
120
+ private
121
+
122
+ def names_and_paths
123
+ branches = []
124
+ opts = {:prefix => @prefix, :correct => false, :validate => false, :source => @name}
125
+ branches << [R10K::Environment::Name.new('production', opts), "#{@remote}/trunk"]
126
+ additional_branch_names = @svn_remote.branches
127
+ if @ignore_branch_prefixes && !@ignore_branch_prefixes.empty?
128
+ additional_branch_names = filter_branches(additional_branch_names, @ignore_branch_prefixes)
129
+ end
130
+
131
+ additional_branch_names.each do |branch|
132
+ branches << [R10K::Environment::Name.new(branch, opts), "#{@remote}/branches/#{branch}"]
133
+ end
134
+ branches
135
+ end
136
+ end