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,36 @@
1
+ require 'colored2'
2
+ require 'r10k/logging'
3
+ require 'log4r/outputter/iooutputter'
4
+
5
+ module R10K
6
+ module Logging
7
+ class TerminalOutputter < Log4r::IOOutputter
8
+
9
+ COLORS = [
10
+ nil,
11
+ :cyan,
12
+ :cyan,
13
+ :green,
14
+ nil,
15
+ nil,
16
+ :yellow,
17
+ :red,
18
+ :red,
19
+ ]
20
+
21
+ attr_accessor :use_color
22
+
23
+ private
24
+
25
+ def format(logevent)
26
+ string = super
27
+ if @use_color
28
+ color = COLORS[logevent.level]
29
+ color ? string.send(color) : string
30
+ else
31
+ string
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require 'r10k'
2
+
3
+ module R10K::Module
4
+
5
+ # Register an module implementation for later generation
6
+ def self.register(klass)
7
+ @klasses ||= []
8
+ @klasses << klass
9
+ end
10
+
11
+ # Look up the implementing class and instantiate an object
12
+ #
13
+ # This method takes the arguments for normal object generation and checks all
14
+ # inheriting classes to see if they implement the behavior needed to create
15
+ # the requested object. It selects the first class that can implement an object
16
+ # with `name, args`, and generates an object of that class.
17
+ #
18
+ # @param [String] name The unique name of the module
19
+ # @param [String] basedir The root to install the module in
20
+ # @param [Object] args An arbitary value or set of values that specifies the implementation
21
+ # @param [R10K::Environment] environment Optional environment that this module is a part of
22
+ #
23
+ # @return [Object < R10K::Module] A member of the implementing subclass
24
+ def self.new(name, basedir, args, environment=nil)
25
+ if implementation = @klasses.find { |klass| klass.implement?(name, args) }
26
+ obj = implementation.new(name, basedir, args, environment)
27
+ obj
28
+ else
29
+ raise _("Module %{name} with args %{args} doesn't have an implementation. (Are you using the right arguments?)") % {name: name, args: args.inspect}
30
+ end
31
+ end
32
+
33
+ require 'r10k/module/base'
34
+ require 'r10k/module/git'
35
+ require 'r10k/module/svn'
36
+ require 'r10k/module/local'
37
+ require 'r10k/module/forge'
38
+ end
@@ -0,0 +1,113 @@
1
+ require 'r10k/module'
2
+ require 'puppet_forge'
3
+
4
+ # This class defines a common interface for module implementations.
5
+ class R10K::Module::Base
6
+
7
+ # @!attribute [r] title
8
+ # @return [String] The forward slash separated owner and name of the module
9
+ attr_reader :title
10
+
11
+ # @!attribute [r] name
12
+ # @return [String] The name of the module
13
+ attr_reader :name
14
+
15
+ # @param [r] dirname
16
+ # @return [String] The name of the directory containing this module
17
+ attr_reader :dirname
18
+
19
+ # @deprecated
20
+ alias :basedir :dirname
21
+
22
+ # @!attribute [r] owner
23
+ # @return [String, nil] The owner of the module if one is specified
24
+ attr_reader :owner
25
+
26
+ # @!attribute [r] path
27
+ # @return [Pathname] The full path of the module
28
+ attr_reader :path
29
+
30
+ # @!attribute [r] environment
31
+ # @return [R10K::Environment, nil] The parent environment of the module
32
+ attr_reader :environment
33
+
34
+ # @!attribute [rw] origin
35
+ # @return [String] Where the module was sourced from. E.g., "Puppetfile"
36
+ attr_accessor :origin
37
+
38
+ # There's been some churn over `author` vs `owner` and `full_name` over
39
+ # `title`, so in the short run it's easier to support both and deprecate one
40
+ # later.
41
+ alias :author :owner
42
+ alias :full_name :title
43
+
44
+ # @param title [String]
45
+ # @param dirname [String]
46
+ # @param args [Array]
47
+ def initialize(title, dirname, args, environment=nil)
48
+ @title = PuppetForge::V3.normalize_name(title)
49
+ @dirname = dirname
50
+ @args = args
51
+ @owner, @name = parse_title(@title)
52
+ @path = Pathname.new(File.join(@dirname, @name))
53
+ @environment = environment
54
+ @origin = 'external' # Expect Puppetfile or R10k::Environment to set this to a specific value
55
+ end
56
+
57
+ # @deprecated
58
+ # @return [String] The full filesystem path to the module.
59
+ def full_path
60
+ path.to_s
61
+ end
62
+
63
+ # Synchronize this module with the indicated state.
64
+ # @abstract
65
+ def sync(opts={})
66
+ raise NotImplementedError
67
+ end
68
+
69
+ # Return the desired version of this module
70
+ # @abstract
71
+ def version
72
+ raise NotImplementedError
73
+ end
74
+
75
+ # Return the status of the currently installed module.
76
+ #
77
+ # This can return the following values:
78
+ #
79
+ # * :absent - there is no module installed
80
+ # * :mismatched - there is a module installed but it must be removed and reinstalled
81
+ # * :outdated - the correct module is installed but it needs to be updated
82
+ # * :insync - the correct module is installed and up to date, or the module is actually a boy band.
83
+ #
84
+ # @return [Symbol]
85
+ # @abstract
86
+ def status
87
+ raise NotImplementedError
88
+ end
89
+
90
+ def accept(visitor)
91
+ visitor.visit(:module, self)
92
+ end
93
+
94
+ # Return the properties of the module
95
+ #
96
+ # @return [Hash]
97
+ # @abstract
98
+ def properties
99
+ raise NotImplementedError
100
+ end
101
+
102
+ private
103
+
104
+ def parse_title(title)
105
+ if (match = title.match(/\A(\w+)\Z/))
106
+ [nil, match[1]]
107
+ elsif (match = title.match(/\A(\w+)[-\/](\w+)\Z/))
108
+ [match[1], match[2]]
109
+ else
110
+ raise ArgumentError, _("Module name (%{title}) must match either 'modulename' or 'owner/modulename'") % {title: title}
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,177 @@
1
+ require 'r10k/module'
2
+ require 'r10k/errors'
3
+ require 'r10k/module/metadata_file'
4
+
5
+ require 'r10k/forge/module_release'
6
+
7
+ require 'pathname'
8
+ require 'fileutils'
9
+ require 'puppet_forge/util'
10
+
11
+ class R10K::Module::Forge < R10K::Module::Base
12
+
13
+ R10K::Module.register(self)
14
+
15
+ def self.implement?(name, args)
16
+ !!(name.match %r[\w+[/-]\w+]) && valid_version?(args)
17
+ end
18
+
19
+ def self.valid_version?(expected_version)
20
+ expected_version == :latest || expected_version.nil? || PuppetForge::Util.version_valid?(expected_version)
21
+ end
22
+
23
+ # @!attribute [r] metadata
24
+ # @api private
25
+ # @return [PuppetForge::Metadata]
26
+ attr_reader :metadata
27
+
28
+ # @!attribute [r] v3_module
29
+ # @api private
30
+ # @return [PuppetForge::V3::Module] The Puppet Forge module metadata
31
+ attr_reader :v3_module
32
+
33
+ include R10K::Logging
34
+
35
+ def initialize(title, dirname, expected_version, environment=nil)
36
+ super
37
+
38
+ @metadata_file = R10K::Module::MetadataFile.new(path + 'metadata.json')
39
+ @metadata = @metadata_file.read
40
+
41
+ @expected_version = expected_version || current_version || :latest
42
+ @v3_module = PuppetForge::V3::Module.new(:slug => @title)
43
+ end
44
+
45
+ def sync(opts={})
46
+ case status
47
+ when :absent
48
+ install
49
+ when :outdated
50
+ upgrade
51
+ when :mismatched
52
+ reinstall
53
+ end
54
+ end
55
+
56
+ def properties
57
+ {
58
+ :expected => expected_version,
59
+ :actual => current_version,
60
+ :type => :forge,
61
+ }
62
+ end
63
+
64
+ # @return [String] The expected version that the module
65
+ def expected_version
66
+ if @expected_version == :latest
67
+ begin
68
+ @expected_version = @v3_module.current_release.version
69
+ rescue Faraday::ResourceNotFound => e
70
+ raise PuppetForge::ReleaseNotFound, _("The module %{title} does not exist on %{url}.") % {title: @title, url: PuppetForge::V3::Release.conn.url_prefix}, e.backtrace
71
+ end
72
+ end
73
+ @expected_version
74
+ end
75
+
76
+ # @return [String] The version of the currently installed module
77
+ def current_version
78
+ if insync?
79
+ (@metadata ||= @metadata_file.read).nil? ? nil : @metadata.version
80
+ else
81
+ nil
82
+ end
83
+ end
84
+
85
+ alias version current_version
86
+
87
+ def exist?
88
+ path.exist?
89
+ end
90
+
91
+ def insync?
92
+ status == :insync
93
+ end
94
+
95
+ def deprecated?
96
+ begin
97
+ @v3_module.fetch && @v3_module.has_attribute?('deprecated_at') && !@v3_module.deprecated_at.nil?
98
+ rescue Faraday::ResourceNotFound => e
99
+ raise PuppetForge::ReleaseNotFound, _("The module %{title} does not exist on %{url}.") % {title: @title, url: PuppetForge::V3::Release.conn.url_prefix}, e.backtrace
100
+ end
101
+ end
102
+
103
+ # Determine the status of the forge module.
104
+ #
105
+ # @return [Symbol] :absent If the directory doesn't exist
106
+ # @return [Symbol] :mismatched If the module is not a forge module, or
107
+ # isn't the right forge module
108
+ # @return [Symbol] :mismatched If the module was previously a git checkout
109
+ # @return [Symbol] :outdated If the installed module is older than expected
110
+ # @return [Symbol] :insync If the module is in the desired state
111
+ def status
112
+ if not self.exist?
113
+ # The module is not installed
114
+ return :absent
115
+ elsif not File.exist?(@path + 'metadata.json')
116
+ # The directory exists but doesn't have a metadata file; it probably
117
+ # isn't a forge module.
118
+ return :mismatched
119
+ end
120
+
121
+ if File.directory?(@path + '.git')
122
+ return :mismatched
123
+ end
124
+
125
+ # The module is present and has a metadata file, read the metadata to
126
+ # determine the state of the module.
127
+ @metadata = @metadata_file.read(@path + 'metadata.json')
128
+
129
+ if not @title.tr('/','-') == @metadata.full_module_name.tr('/','-')
130
+
131
+ # This is a forge module but the installed module is a different author
132
+ # than the expected author.
133
+ return :mismatched
134
+ end
135
+
136
+ if expected_version && (expected_version != @metadata.version)
137
+ return :outdated
138
+ end
139
+
140
+ return :insync
141
+ end
142
+
143
+ def install
144
+ if deprecated?
145
+ logger.warn "Puppet Forge module '#{@v3_module.slug}' has been deprecated, visit https://forge.puppet.com/#{@v3_module.slug.tr('-','/')} for more information."
146
+ end
147
+
148
+ parent_path = @path.parent
149
+ if !parent_path.exist?
150
+ parent_path.mkpath
151
+ end
152
+ module_release = R10K::Forge::ModuleRelease.new(@title, expected_version)
153
+ module_release.install(@path)
154
+ end
155
+
156
+ alias upgrade install
157
+
158
+ def uninstall
159
+ FileUtils.rm_rf full_path
160
+ end
161
+
162
+ def reinstall
163
+ uninstall
164
+ install
165
+ end
166
+
167
+ private
168
+
169
+ # Override the base #parse_title to ensure we have a fully qualified name
170
+ def parse_title(title)
171
+ if (match = title.match(/\A(\w+)[-\/](\w+)\Z/))
172
+ [match[1], match[2]]
173
+ else
174
+ raise ArgumentError, _("Forge module names must match 'owner/modulename'")
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,109 @@
1
+ require 'r10k/module'
2
+ require 'r10k/git'
3
+ require 'r10k/git/stateful_repository'
4
+ require 'forwardable'
5
+
6
+ class R10K::Module::Git < R10K::Module::Base
7
+
8
+ R10K::Module.register(self)
9
+
10
+ def self.implement?(name, args)
11
+ args.is_a? Hash and args.has_key?(:git)
12
+ rescue
13
+ false
14
+ end
15
+
16
+ # @!attribute [r] repo
17
+ # @api private
18
+ # @return [R10K::Git::StatefulRepository]
19
+ attr_reader :repo
20
+
21
+ # @!attribute [r] desired_ref
22
+ # @api private
23
+ # @return [String]
24
+ attr_reader :desired_ref
25
+
26
+ # @!attribute [r] default_ref
27
+ # @api private
28
+ # @return [String]
29
+ attr_reader :default_ref
30
+
31
+ def initialize(title, dirname, args, environment=nil)
32
+ super
33
+
34
+ parse_options(@args)
35
+
36
+ @repo = R10K::Git::StatefulRepository.new(@remote, @dirname, @name)
37
+ end
38
+
39
+ def version
40
+ validate_ref(@desired_ref, @default_ref)
41
+ end
42
+
43
+ def properties
44
+ {
45
+ :expected => version,
46
+ :actual => (@repo.head || "(unresolvable)"),
47
+ :type => :git,
48
+ }
49
+ end
50
+
51
+ def sync(opts={})
52
+ force = opts && opts.fetch(:force, true)
53
+ @repo.sync(version, force)
54
+ end
55
+
56
+ def status
57
+ @repo.status(version)
58
+ end
59
+
60
+ private
61
+
62
+ def validate_ref(desired, default)
63
+ if desired && desired != :control_branch && @repo.resolve(desired)
64
+ return desired
65
+ elsif default && @repo.resolve(default)
66
+ return default
67
+ else
68
+ msg = ["Unable to manage Puppetfile content '%{name}':"]
69
+ vars = {name: @name}
70
+
71
+ if desired == :control_branch
72
+ msg << "Could not resolve control repo branch"
73
+ elsif desired
74
+ msg << "Could not resolve desired ref '%{desired}'"
75
+ vars[:desired] = desired
76
+ else
77
+ msg << "Could not determine desired ref"
78
+ end
79
+
80
+ if default
81
+ msg << "or resolve default ref '%{default}'"
82
+ vars[:default] = default
83
+ else
84
+ msg << "and no default provided"
85
+ end
86
+
87
+ raise ArgumentError, _(msg.join(' ')) % vars
88
+ end
89
+ end
90
+
91
+ def parse_options(options)
92
+ ref_opts = [:branch, :tag, :commit, :ref]
93
+ known_opts = [:git, :default_branch] + ref_opts
94
+
95
+ unhandled = options.keys - known_opts
96
+ unless unhandled.empty?
97
+ raise ArgumentError, _("Unhandled options %{unhandled} specified for %{class}") % {unhandled: unhandled, class: self.class}
98
+ end
99
+
100
+ @remote = options[:git]
101
+
102
+ @desired_ref = ref_opts.find { |key| break options[key] if options.has_key?(key) } || 'master'
103
+ @default_ref = options[:default_branch]
104
+
105
+ if @desired_ref == :control_branch && @environment && @environment.respond_to?(:ref)
106
+ @desired_ref = @environment.ref
107
+ end
108
+ end
109
+ end