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,63 @@
1
+ require 'pathname'
2
+
3
+ # Manage `$GIT_DIR/objects/info/alternates`
4
+ #
5
+ # @see man gitrepository-layout(5)
6
+ class R10K::Git::Alternates
7
+
8
+ # @attribute [r] file
9
+ # @return [Pathname] The alternates file
10
+ attr_reader :file
11
+
12
+ # @param git_dir [Pathname] The path to the git repository
13
+ def initialize(git_dir)
14
+ @file = git_dir + File.join('objects', 'info', 'alternates')
15
+ @entries = []
16
+ end
17
+
18
+ def add(path)
19
+ write(to_a << path)
20
+ end
21
+ alias << add
22
+
23
+ # Conditionally add path to the alternates file
24
+ #
25
+ # @param path [String] The file path to add to the file if not already present
26
+ # @return [true, false] If the entry was added.
27
+ def add?(path)
28
+ paths = read()
29
+
30
+ add_entry = !paths.include?(path)
31
+
32
+ if add_entry
33
+ paths << path
34
+ write(paths)
35
+ end
36
+
37
+ add_entry
38
+ end
39
+
40
+ def include?(path)
41
+ to_a.include?(path)
42
+ end
43
+
44
+ def write(entries)
45
+ if ! @file.parent.directory?
46
+ raise R10K::Git::GitError, _("Cannot write %{file}; parent directory does not exist") % {file: @file}
47
+ end
48
+ @file.open("w") do |fh|
49
+ entries.each do |entry|
50
+ fh.puts(entry)
51
+ end
52
+ end
53
+ end
54
+
55
+ def read
56
+ entries = []
57
+ if @file.file?
58
+ entries = @file.readlines.map(&:chomp)
59
+ end
60
+ entries
61
+ end
62
+ alias to_a read
63
+ end
@@ -0,0 +1,108 @@
1
+ require 'r10k/git'
2
+
3
+ require 'r10k/settings'
4
+ require 'r10k/instance_cache'
5
+ require 'forwardable'
6
+
7
+ # Cache Git repository mirrors for object database reuse.
8
+ #
9
+ # This implements most of the behavior needed for Git repo caching, but needs
10
+ # to have a specific Git bare repository provided. Subclasses should implement
11
+ # the {bare_repository} method.
12
+ #
13
+ # @abstract
14
+ # @see man git-clone(1)
15
+ class R10K::Git::Cache
16
+
17
+ include R10K::Settings::Mixin
18
+
19
+ def_setting_attr :cache_root, File.expand_path(ENV['HOME'] ? '~/.r10k/git': '/root/.r10k/git')
20
+
21
+ @instance_cache = R10K::InstanceCache.new(self)
22
+
23
+ # @api private
24
+ def self.instance_cache
25
+ @instance_cache
26
+ end
27
+
28
+ # Generate a new instance with the given remote or return an existing object
29
+ # with the given remote. This should be used over R10K::Git::Cache.new.
30
+ #
31
+ # @api public
32
+ # @param remote [String] The git remote to cache
33
+ # @return [R10K::Git::Cache] The requested cache object.
34
+ def self.generate(remote)
35
+ instance_cache.generate(remote)
36
+ end
37
+
38
+ # @abstract
39
+ # @return [Object] The concrete bare repository implementation to use for
40
+ # interacting with the cached Git repository.
41
+ def self.bare_repository
42
+ raise NotImplementedError
43
+ end
44
+
45
+ include R10K::Logging
46
+
47
+ extend Forwardable
48
+
49
+ def_delegators :@repo, :git_dir, :objects_dir, :branches, :tags, :exist?, :resolve, :ref_type
50
+
51
+ # @!attribute [r] path
52
+ # @deprecated
53
+ # @return [String] The path to the git cache repository
54
+ def path
55
+ logger.warn _("%{class}#path is deprecated; use #git_dir") % {class: self.class}
56
+ git_dir
57
+ end
58
+
59
+ # @!attribute [r] repo
60
+ # @api private
61
+ attr_reader :repo
62
+
63
+ # @param remote [String] The URL of the Git remote URL to cache.
64
+ def initialize(remote)
65
+ @remote = remote
66
+ @repo = self.class.bare_repository.new(settings[:cache_root], sanitized_dirname)
67
+ end
68
+
69
+ def sync
70
+ if !@synced
71
+ sync!
72
+ @synced = true
73
+ end
74
+ end
75
+
76
+ def synced?
77
+ @synced
78
+ end
79
+
80
+ def sync!
81
+ if cached?
82
+ @repo.fetch
83
+ else
84
+ logger.debug1 _("Creating new git cache for %{remote}") % {remote: @remote.inspect}
85
+
86
+ # TODO extract this to an initialization step
87
+ if !File.exist?(settings[:cache_root])
88
+ FileUtils.mkdir_p settings[:cache_root]
89
+ end
90
+
91
+ @repo.clone(@remote)
92
+ end
93
+ end
94
+
95
+ # @api private
96
+ def reset!
97
+ @synced = false
98
+ end
99
+
100
+ alias cached? exist?
101
+
102
+ private
103
+
104
+ # Reformat the remote name into something that can be used as a directory
105
+ def sanitized_dirname
106
+ @remote.gsub(/[^@\w\.-]/, '-')
107
+ end
108
+ end
@@ -0,0 +1,34 @@
1
+ require 'r10k/errors'
2
+
3
+ module R10K
4
+ module Git
5
+
6
+ class GitError < R10K::Error
7
+ attr_reader :git_dir
8
+
9
+ def initialize(mesg, options = {})
10
+ super
11
+ @git_dir = @options[:git_dir]
12
+ end
13
+
14
+ def message
15
+ msg = super
16
+ if @git_dir
17
+ msg << " at #{@git_dir}"
18
+ end
19
+ msg
20
+ end
21
+ end
22
+
23
+
24
+ class UnresolvableRefError < GitError
25
+
26
+ attr_reader :ref
27
+
28
+ def initialize(mesg, options = {})
29
+ super
30
+ @ref = @options[:ref]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ require 'r10k/git'
2
+
3
+ begin
4
+ require 'rugged'
5
+ rescue LoadError
6
+ end
7
+
8
+ module R10K
9
+ module Git
10
+ module Rugged
11
+ require 'r10k/git/rugged/bare_repository'
12
+ require 'r10k/git/rugged/working_repository'
13
+ require 'r10k/git/rugged/cache'
14
+ require 'r10k/git/rugged/thin_repository'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,85 @@
1
+ require 'r10k/git/rugged'
2
+ require 'r10k/git/rugged/base_repository'
3
+ require 'r10k/git/errors'
4
+
5
+ class R10K::Git::Rugged::BareRepository < R10K::Git::Rugged::BaseRepository
6
+
7
+ # @param basedir [String] The base directory of the Git repository
8
+ # @param dirname [String] The directory name of the Git repository
9
+ def initialize(basedir, dirname)
10
+ @path = Pathname.new(File.join(basedir, dirname))
11
+
12
+ if exist?
13
+ @_rugged_repo = ::Rugged::Repository.bare(@path.to_s)
14
+ end
15
+ end
16
+
17
+ # @return [Pathname] The path to this Git repository
18
+ def git_dir
19
+ @path
20
+ end
21
+
22
+ # @return [Pathname] The path to the objects directory in this Git repository
23
+ def objects_dir
24
+ @path + "objects"
25
+ end
26
+
27
+ # Clone the given remote.
28
+ #
29
+ # This should only be called if the repository does not exist.
30
+ #
31
+ # @param remote [String] The URL of the Git remote to clone.
32
+ # @return [void]
33
+ def clone(remote)
34
+ logger.debug1 { _("Cloning '%{remote}' into %{path}") % {remote: remote, path: @path} }
35
+
36
+ @_rugged_repo = ::Rugged::Repository.init_at(@path.to_s, true).tap do |repo|
37
+ config = repo.config
38
+ config['remote.origin.url'] = remote
39
+ config['remote.origin.fetch'] = '+refs/*:refs/*'
40
+ config['remote.origin.mirror'] = 'true'
41
+ end
42
+
43
+ fetch('origin')
44
+ rescue Rugged::SshError, Rugged::NetworkError => e
45
+ raise R10K::Git::GitError.new(e.message, :git_dir => git_dir, :backtrace => e.backtrace)
46
+ end
47
+
48
+ # Fetch refs and objects from the origin remote
49
+ #
50
+ # @return [void]
51
+ def fetch(remote_name='origin')
52
+ logger.debug1 { _("Fetching remote '%{remote_name}' at %{path}") % {remote_name: remote_name, path: @path } }
53
+
54
+ # Check to see if we have a version of Rugged that supports "fetch --prune" and warn if not
55
+ if defined?(Rugged::Version) && !Gem::Dependency.new('rugged', '>= 0.24.0').match?('rugged', Rugged::Version)
56
+ logger.warn { _("Rugged versions prior to 0.24.0 do not support pruning stale branches during fetch, please upgrade your \'rugged\' gem. (Current version is: %{version})") % {version: Rugged::Version} }
57
+ end
58
+
59
+ options = {:credentials => credentials, :prune => true}
60
+ refspecs = ['+refs/*:refs/*']
61
+
62
+ remote = remotes[remote_name]
63
+ proxy = R10K::Git.get_proxy_for_remote(remote)
64
+ results = nil
65
+
66
+ R10K::Git.with_proxy(proxy) do
67
+ results = with_repo { |repo| repo.fetch(remote_name, refspecs, options) }
68
+ end
69
+
70
+ report_transfer(results, remote_name)
71
+ rescue Rugged::SshError, Rugged::NetworkError => e
72
+ if e.message =~ /Unsupported proxy scheme for/
73
+ message = e.message + "As of curl ver 7.50.2, unsupported proxy schemes no longer fall back to HTTP."
74
+ else
75
+ message = e.message
76
+ end
77
+ raise R10K::Git::GitError.new(message, :git_dir => git_dir, :backtrace => e.backtrace)
78
+ rescue
79
+ raise
80
+ end
81
+
82
+ def exist?
83
+ @path.exist?
84
+ end
85
+ end
@@ -0,0 +1,93 @@
1
+ require 'r10k/git/rugged'
2
+ require 'r10k/git/rugged/credentials'
3
+ require 'r10k/logging'
4
+
5
+ class R10K::Git::Rugged::BaseRepository
6
+
7
+ include R10K::Logging
8
+
9
+ # @return [Pathname] The path to this repository.
10
+ # @note The `@path` instance variable must be set by inheriting classes on instantiation.
11
+ attr_reader :path
12
+
13
+ def resolve(pattern)
14
+ object = with_repo { |repo| repo.rev_parse(pattern) }
15
+ case object
16
+ when NilClass
17
+ nil
18
+ when ::Rugged::Tag, ::Rugged::Tag::Annotation
19
+ object.target.oid
20
+ else
21
+ object.oid
22
+ end
23
+ rescue ::Rugged::ReferenceError
24
+ nil
25
+ end
26
+
27
+ def branches
28
+ with_repo { |repo| repo.branches.each_name(:local).to_a }
29
+ end
30
+
31
+ def tags
32
+ with_repo { |repo| repo.tags.each_name.to_a }
33
+ end
34
+
35
+ # @return [Symbol] The type of the given ref, one of :branch, :tag, :commit, or :unknown
36
+ def ref_type(pattern)
37
+ # Try to match and resolve SHA refs as quickly as possible.
38
+ if pattern =~ /^[0-9a-f]{5,40}$/i && @_rugged_repo.include?(pattern)
39
+ :commit
40
+ elsif @_rugged_repo.tags[pattern]
41
+ :tag
42
+ elsif @_rugged_repo.branches[pattern]
43
+ :branch
44
+ elsif resolve(pattern)
45
+ :commit
46
+ else
47
+ :unknown
48
+ end
49
+ end
50
+
51
+ def remotes
52
+ remotes_hash = {}
53
+
54
+ if @_rugged_repo
55
+ @_rugged_repo.remotes.each do |remote|
56
+ remotes_hash[remote.name] = remote.url
57
+ end
58
+ end
59
+
60
+ remotes_hash
61
+ end
62
+
63
+ private
64
+
65
+ def with_repo(opts={})
66
+ if @_rugged_repo
67
+ yield @_rugged_repo
68
+ end
69
+ ensure
70
+ @_rugged_repo.close if @_rugged_repo
71
+ end
72
+
73
+
74
+ # Generate a lambda that can create a credentials object for the
75
+ # authentication type in question.
76
+ #
77
+ # @note The Rugged API expects an object that responds to #call; the
78
+ # Credentials subclasses implement #call returning self so that
79
+ # the Credentials object can be used, or a Proc that returns a
80
+ # Credentials object can be used.
81
+ #
82
+ # @api private
83
+ #
84
+ # @return [Proc]
85
+ def credentials
86
+ R10K::Git::Rugged::Credentials.new(self)
87
+ end
88
+
89
+ def report_transfer(results, remote)
90
+ logger.debug2 { "Transferred #{results[:total_objects]} objects (#{results[:received_bytes]} bytes) from '#{remote}' into #{git_dir}'" }
91
+ nil
92
+ end
93
+ end
@@ -0,0 +1,11 @@
1
+ require 'r10k/git/rugged'
2
+ require 'r10k/git/cache'
3
+
4
+ class R10K::Git::Rugged::Cache < R10K::Git::Cache
5
+
6
+ @instance_cache = R10K::InstanceCache.new(self)
7
+
8
+ def self.bare_repository
9
+ R10K::Git::Rugged::BareRepository
10
+ end
11
+ end
@@ -0,0 +1,91 @@
1
+ require 'r10k/git/rugged'
2
+ require 'r10k/git/errors'
3
+ require 'r10k/logging'
4
+
5
+ # Generate credentials for secured remote connections.
6
+ #
7
+ # @api private
8
+ class R10K::Git::Rugged::Credentials
9
+
10
+ include R10K::Logging
11
+
12
+ # @param repository [R10K::Git::Rugged::BaseRepository]
13
+ def initialize(repository)
14
+ @repository = repository
15
+ @called = 0
16
+ end
17
+
18
+ def call(url, username_from_url, allowed_types)
19
+ @called += 1
20
+
21
+ # Break out of infinite HTTP auth retry loop introduced in libgit2/rugged 0.24.0, libssh
22
+ # auth seems to already abort after ~50 attempts.
23
+ if @called > 50
24
+ raise R10K::Git::GitError.new(_("Authentication failed for Git remote %{url}.") % {url: url.inspect} )
25
+ end
26
+
27
+ if allowed_types.include?(:ssh_key)
28
+ get_ssh_key_credentials(url, username_from_url)
29
+ elsif allowed_types.include?(:plaintext)
30
+ get_plaintext_credentials(url, username_from_url)
31
+ else
32
+ get_default_credentials(url, username_from_url)
33
+ end
34
+ end
35
+
36
+ def get_ssh_key_credentials(url, username_from_url)
37
+ user = get_git_username(url, username_from_url)
38
+
39
+ per_repo_private_key = nil
40
+ if per_repo_settings = R10K::Git.get_repo_settings(url)
41
+ per_repo_private_key = per_repo_settings[:private_key]
42
+ end
43
+
44
+ global_private_key = R10K::Git.settings[:private_key]
45
+
46
+ if per_repo_private_key
47
+ private_key = per_repo_private_key
48
+ logger.debug2 _("Using per-repository private key %{key} for URL %{url}") % {key: private_key, url: url.inspect}
49
+ elsif global_private_key
50
+ private_key = global_private_key
51
+ logger.debug2 _("URL %{url} has no per-repository private key using '%{key}'." ) % {key: private_key, url: url.inspect}
52
+ else
53
+ raise R10K::Git::GitError.new(_("Git remote %{url} uses the SSH protocol but no private key was given") % {url: url.inspect}, :git_dir => @repository.path.to_s)
54
+ end
55
+
56
+ if !File.readable?(private_key)
57
+ raise R10K::Git::GitError.new(_("Unable to use SSH key auth for %{url}: private key %{private_key} is missing or unreadable") % {url: url.inspect, private_key: private_key.inspect}, :git_dir => @repository.path.to_s)
58
+ end
59
+
60
+ Rugged::Credentials::SshKey.new(:username => user, :privatekey => private_key)
61
+ end
62
+
63
+ def get_plaintext_credentials(url, username_from_url)
64
+ user = get_git_username(url, username_from_url)
65
+ password = URI.parse(url).password || ''
66
+ Rugged::Credentials::UserPassword.new(username: user, password: password)
67
+ end
68
+
69
+ def get_default_credentials(url, username_from_url)
70
+ Rugged::Credentials::Default.new
71
+ end
72
+
73
+ def get_git_username(url, username_from_url)
74
+ git_user = R10K::Git.settings[:username]
75
+
76
+ user = nil
77
+
78
+ if !username_from_url.nil?
79
+ user = username_from_url
80
+ logger.debug2 _("URL %{url} includes the username %{username}, using that user for authentication.") % {url: url.inspect, username: username_from_url}
81
+ elsif git_user
82
+ user = git_user
83
+ logger.debug2 _("URL %{url} did not specify a user, using %{user} from configuration") % {url: url.inspect, user: user.inspect}
84
+ else
85
+ user = Etc.getlogin
86
+ logger.debug2 _("URL %{url} did not specify a user, using current user %{user}") % {url: url.inspect, user: user.inspect}
87
+ end
88
+
89
+ user
90
+ end
91
+ end