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,89 @@
1
+ require 'r10k/git'
2
+ require 'r10k/git/rugged/working_repository'
3
+ require 'r10k/git/rugged/cache'
4
+
5
+ class R10K::Git::Rugged::ThinRepository < R10K::Git::Rugged::WorkingRepository
6
+ def initialize(basedir, dirname, cache_repo)
7
+ @cache_repo = cache_repo
8
+
9
+ super(basedir, dirname)
10
+ end
11
+
12
+ # Clone this git repository
13
+ #
14
+ # @param remote [String] The Git remote to clone
15
+ # @param opts [Hash]
16
+ #
17
+ # @options opts [String] :ref The git ref to check out on clone
18
+ #
19
+ # @return [void]
20
+ def clone(remote, opts = {})
21
+ logger.debug1 { "Cloning '#{remote}' into #{@path}" }
22
+ @cache_repo.sync
23
+
24
+ cache_objects_dir = @cache_repo.objects_dir.to_s
25
+
26
+ # {Rugged::Repository.clone_at} doesn't support :alternates, which
27
+ # completely breaks how thin repositories need to work. To circumvent
28
+ # this we manually create a Git repository, set up git remotes, and
29
+ # update 'objects/info/alternates' with the path. We don't actually
30
+ # fetch any objects because we don't need them, and we don't actually
31
+ # use any refs in this repository so we skip all those steps.
32
+ ::Rugged::Repository.init_at(@path.to_s, false)
33
+ @_rugged_repo = ::Rugged::Repository.new(@path.to_s, :alternates => [cache_objects_dir])
34
+ alternates << cache_objects_dir
35
+
36
+ with_repo do |repo|
37
+ config = repo.config
38
+ config['remote.origin.url'] = remote
39
+ config['remote.origin.fetch'] = '+refs/heads/*:refs/remotes/origin/*'
40
+ config['remote.cache.url'] = @cache_repo.git_dir.to_s
41
+ config['remote.cache.fetch'] = '+refs/heads/*:refs/remotes/cache/*'
42
+ end
43
+
44
+ checkout(opts.fetch(:ref, 'HEAD'))
45
+ end
46
+
47
+ def checkout(ref, opts = {})
48
+ super(@cache_repo.resolve(ref), opts)
49
+ end
50
+
51
+ # Fetch refs and objects from one of the Git remotes
52
+ #
53
+ # @param remote [String] The remote to fetch, defaults to 'cache'
54
+ # @return [void]
55
+ def fetch(remote = 'cache')
56
+ super(remote)
57
+ end
58
+
59
+ # @return [String] The cache remote URL
60
+ def cache
61
+ with_repo { |repo| repo.config['remote.cache.url'] }
62
+ end
63
+
64
+ def tracked_paths(ref="HEAD")
65
+ with_repo do |repo|
66
+ commit = repo.rev_parse(ref)
67
+
68
+ unless commit && commit.tree
69
+ raise R10K::Error.new("Unable to resolve '#{ref}' to a valid commit in repo #{@path}")
70
+ end
71
+
72
+ commit.tree.walk(:postorder).collect do |root, entry|
73
+ root.empty? ? entry[:name] : File.join(root, entry[:name])
74
+ end
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ # Override the parent class repo setup so that we can make sure the alternates file is up to date
81
+ # before we create the Rugged::Repository object, which reads from the alternates file.
82
+ def setup_rugged_repo
83
+ entry_added = alternates.add?(@cache_repo.objects_dir.to_s)
84
+ if entry_added
85
+ logger.debug2 { _("Updated repo %{path} to include alternate object db path %{objects_dir}") % {path: @path, objects_dir: @cache_repo.objects_dir} }
86
+ end
87
+ super
88
+ end
89
+ end
@@ -0,0 +1,145 @@
1
+ require 'r10k/git/rugged'
2
+ require 'r10k/git/rugged/base_repository'
3
+ require 'r10k/git/errors'
4
+
5
+ class R10K::Git::Rugged::WorkingRepository < R10K::Git::Rugged::BaseRepository
6
+
7
+ # @return [Pathname] The path to the Git repository inside of this directory
8
+ def git_dir
9
+ @path + '.git'
10
+ end
11
+
12
+ # @param basedir [String] The base directory of the Git repository
13
+ # @param dirname [String] The directory name of the Git repository
14
+ def initialize(basedir, dirname)
15
+ @path = Pathname.new(File.join(basedir, dirname))
16
+ end
17
+
18
+ # Clone this git repository
19
+ #
20
+ # @param remote [String] The Git remote to clone
21
+ # @param opts [Hash]
22
+ #
23
+ # @options opts [String] :ref The git ref to check out on clone
24
+ # @options opts [String] :reference A Git repository to use as an alternate object database
25
+ #
26
+ # @return [void]
27
+ def clone(remote, opts = {})
28
+ logger.debug1 { _("Cloning '%{remote}' into %{path}") % {remote: remote, path: @path } }
29
+
30
+ # libgit2/rugged doesn't support cloning a repository and providing an
31
+ # alternate object database, making the handling of :alternates a noop.
32
+ # Unfortunately this means that this method can't really use alternates
33
+ # and running the clone will duplicate all objects in the specified
34
+ # repository. However alternate databases can be handled when an existing
35
+ # repository is loaded, so loading a cloned repo will correctly use
36
+ # alternate object database.
37
+ options = {:credentials => credentials}
38
+ options.merge!(:alternates => [File.join(opts[:reference], 'objects')]) if opts[:reference]
39
+
40
+ proxy = R10K::Git.get_proxy_for_remote(remote)
41
+
42
+ R10K::Git.with_proxy(proxy) do
43
+ @_rugged_repo = ::Rugged::Repository.clone_at(remote, @path.to_s, options)
44
+ end
45
+
46
+ if opts[:reference]
47
+ alternates << File.join(opts[:reference], 'objects')
48
+ end
49
+
50
+ if opts[:ref]
51
+ # todo: always check out something; since we're fetching a repository we
52
+ # won't populate the working directory.
53
+ checkout(opts[:ref])
54
+ end
55
+ rescue Rugged::SshError, Rugged::NetworkError => e
56
+ raise R10K::Git::GitError.new(e.message, :git_dir => git_dir, :backtrace => e.backtrace)
57
+ end
58
+
59
+ # Check out the given Git ref
60
+ #
61
+ # @param ref [String] The git reference to check out
62
+ # @return [void]
63
+ def checkout(ref, opts = {})
64
+ sha = resolve(ref)
65
+
66
+ if sha
67
+ logger.debug2 { _("Checking out ref '%{ref}' (resolved to SHA '%{sha}') in repository %{path}") % {ref: ref, sha: sha, path: @path} }
68
+ else
69
+ raise R10K::Git::GitError.new("Unable to check out unresolvable ref '#{ref}'", git_dir: git_dir)
70
+ end
71
+
72
+ # :force defaults to true
73
+ force = !opts.has_key?(:force) || opts[:force]
74
+
75
+ with_repo do |repo|
76
+ # rugged/libgit2 will not update (at least) the execute bit a file if the SHA is already at
77
+ # the value being reset to, so this is now changed to an if ... else
78
+ if force
79
+ repo.reset(sha, :hard)
80
+ else
81
+ repo.checkout(sha)
82
+ end
83
+ end
84
+ end
85
+
86
+ def fetch(remote_name = 'origin')
87
+ logger.debug1 { _("Fetching remote '%{remote}' at %{path}") % {remote: remote_name, path: @path} }
88
+ options = {:credentials => credentials}
89
+ refspecs = ["+refs/heads/*:refs/remotes/#{remote_name}/*"]
90
+
91
+ remote = remotes[remote_name]
92
+ proxy = R10K::Git.get_proxy_for_remote(remote)
93
+ results = nil
94
+
95
+ R10K::Git.with_proxy(proxy) do
96
+ results = with_repo { |repo| repo.fetch(remote_name, refspecs, options) }
97
+ end
98
+
99
+ report_transfer(results, remote)
100
+ rescue Rugged::SshError, Rugged::NetworkError => e
101
+ raise R10K::Git::GitError.new(e.message, :git_dir => git_dir, :backtrace => e.backtrace)
102
+ end
103
+
104
+ def exist?
105
+ @path.exist?
106
+ end
107
+
108
+ def head
109
+ resolve('HEAD')
110
+ end
111
+
112
+ def alternates
113
+ R10K::Git::Alternates.new(git_dir)
114
+ end
115
+
116
+ def origin
117
+ with_repo { |repo| repo.config['remote.origin.url'] }
118
+ end
119
+
120
+ def dirty?
121
+ with_repo do |repo|
122
+ diff = repo.diff_workdir('HEAD')
123
+
124
+ diff.each_patch do |p|
125
+ logger.debug(_("Found local modifications in %{file_path}" % {file_path: File.join(@path, p.delta.old_file[:path])}))
126
+ logger.debug1(p.to_s)
127
+ end
128
+
129
+ return diff.size > 0
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ def with_repo
136
+ if @_rugged_repo.nil? && git_dir.exist?
137
+ setup_rugged_repo
138
+ end
139
+ super
140
+ end
141
+
142
+ def setup_rugged_repo
143
+ @_rugged_repo = ::Rugged::Repository.new(@path.to_s, :alternates => alternates.to_a)
144
+ end
145
+ end
@@ -0,0 +1,9 @@
1
+ module R10K
2
+ module Git
3
+ module ShellGit
4
+ require 'r10k/git/shellgit/bare_repository'
5
+ require 'r10k/git/shellgit/working_repository'
6
+ require 'r10k/git/shellgit/thin_repository'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ require 'r10k/git/shellgit'
2
+ require 'r10k/git/shellgit/base_repository'
3
+
4
+ # Create and manage Git bare repositories.
5
+ class R10K::Git::ShellGit::BareRepository < R10K::Git::ShellGit::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
+ end
12
+
13
+ # @return [Pathname] The path to this Git repository
14
+ def git_dir
15
+ @path
16
+ end
17
+
18
+ # @return [Pathname] The path to the objects directory in this Git repository
19
+ def objects_dir
20
+ @path + "objects"
21
+ end
22
+
23
+ def clone(remote)
24
+ proxy = R10K::Git.get_proxy_for_remote(remote)
25
+
26
+ R10K::Git.with_proxy(proxy) do
27
+ git ['clone', '--mirror', remote, git_dir.to_s]
28
+ end
29
+ end
30
+
31
+ def fetch(remote_name='origin')
32
+ remote = remotes[remote_name]
33
+ proxy = R10K::Git.get_proxy_for_remote(remote)
34
+
35
+ R10K::Git.with_proxy(proxy) do
36
+ git ['fetch', remote_name, '--prune'], :git_dir => git_dir.to_s
37
+ end
38
+ end
39
+
40
+ def exist?
41
+ @path.exist?
42
+ end
43
+ end
@@ -0,0 +1,137 @@
1
+ require 'r10k/git/shellgit'
2
+ require 'r10k/util/subprocess'
3
+ require 'r10k/logging'
4
+
5
+ class R10K::Git::ShellGit::BaseRepository
6
+
7
+ # @abstract
8
+ # @return [Pathname] The path to the Git directory
9
+ def git_dir
10
+ raise NotImplementedError
11
+ end
12
+
13
+ # Resolve the given Git ref to a commit
14
+ #
15
+ # @param pattern [String] The git ref to resolve
16
+ # @return [String, nil] The commit SHA if the ref could be resolved, nil otherwise.
17
+ def resolve(pattern)
18
+ result = git ['rev-parse', "#{pattern}^{commit}"], :git_dir => git_dir.to_s, :raise_on_fail => false
19
+ if result.success?
20
+ result.stdout
21
+ end
22
+ end
23
+
24
+ # For compatibility with R10K::Git::Ref
25
+ # @todo remove alias
26
+ alias rev_parse resolve
27
+
28
+ # @return [Array<String>] All local branches in this repository
29
+ def branches
30
+ for_each_ref('refs/heads')
31
+ end
32
+
33
+ def is_branch?(pattern)
34
+ result = git ['rev-parse', '-q', '--verify', "refs/heads/#{pattern}"], :git_dir => git_dir.to_s, :raise_on_fail => false
35
+
36
+ result.success?
37
+ end
38
+
39
+ # @return [Array<String>] All tags in this repository
40
+ def tags
41
+ for_each_ref('refs/tags')
42
+ end
43
+
44
+ def is_tag?(pattern)
45
+ result = git ['rev-parse', '-q', '--verify', "refs/tags/#{pattern}"], :git_dir => git_dir.to_s, :raise_on_fail => false
46
+
47
+ result.success?
48
+ end
49
+
50
+ # @return [Symbol] The type of the given ref, one of :branch, :tag, :commit, or :unknown
51
+ def ref_type(pattern)
52
+ @_ref_type_cache ||= {}
53
+
54
+ @_ref_type_cache[pattern] ||= begin
55
+ # Try to match and resolve SHA refs as quickly as possible.
56
+ if pattern =~ /^[0-9a-f]{5,40}$/i && resolve(pattern)
57
+ :commit
58
+ elsif is_tag? pattern
59
+ :tag
60
+ elsif is_branch? pattern
61
+ :branch
62
+ elsif resolve(pattern)
63
+ :commit
64
+ else
65
+ :unknown
66
+ end
67
+ end
68
+ end
69
+
70
+ # @return [Hash] Collection of remotes for this repo, keys are the remote name and values are the remote URL.
71
+ def remotes
72
+ result = git ['config', '--local', '--get-regexp', '^remote\..*\.url$'], :git_dir => git_dir.to_s, :raise_on_fail => false
73
+
74
+ if result.success?
75
+ Hash[
76
+ result.stdout.split("\n").collect do |remote|
77
+ matches = /^remote\.(.*)\.url (.*)$/.match(remote)
78
+
79
+ [matches[1], matches[2]]
80
+ end
81
+ ]
82
+ else
83
+ {}
84
+ end
85
+ end
86
+
87
+ include R10K::Logging
88
+
89
+ private
90
+
91
+ # @param pattern [String]
92
+ def for_each_ref(pattern)
93
+ matcher = %r[#{pattern}/(.*)$]
94
+ output = git ['for-each-ref', pattern, '--format', '%(refname)'], :git_dir => git_dir.to_s
95
+ output.stdout.scan(matcher).flatten
96
+ end
97
+
98
+ # Wrap git commands
99
+ #
100
+ # @param cmd [Array<String>] cmd The arguments for the git prompt
101
+ # @param opts [Hash] opts
102
+ #
103
+ # @option opts [String] :path
104
+ # @option opts [String] :git_dir
105
+ # @option opts [String] :work_tree
106
+ # @option opts [String] :raise_on_fail
107
+ #
108
+ # @raise [R10K::ExecutionFailure] If the executed command exited with a
109
+ # nonzero exit code.
110
+ #
111
+ # @return [String] The git command output
112
+ def git(cmd, opts = {})
113
+ raise_on_fail = opts.fetch(:raise_on_fail, true)
114
+
115
+ argv = %w{git}
116
+
117
+ if opts[:path]
118
+ argv << "--git-dir" << File.join(opts[:path], '.git')
119
+ argv << "--work-tree" << opts[:path]
120
+ else
121
+ if opts[:git_dir]
122
+ argv << "--git-dir" << opts[:git_dir]
123
+ end
124
+ if opts[:work_tree]
125
+ argv << "--work-tree" << opts[:work_tree]
126
+ end
127
+ end
128
+
129
+ argv.concat(cmd)
130
+
131
+ subproc = R10K::Util::Subprocess.new(argv)
132
+ subproc.raise_on_fail = raise_on_fail
133
+ subproc.logger = self.logger
134
+
135
+ subproc.execute
136
+ end
137
+ end
@@ -0,0 +1,11 @@
1
+ require 'r10k/git/shellgit'
2
+ require 'r10k/git/cache'
3
+
4
+ class R10K::Git::ShellGit::Cache < R10K::Git::Cache
5
+
6
+ @instance_cache = R10K::InstanceCache.new(self)
7
+
8
+ def self.bare_repository
9
+ R10K::Git::ShellGit::BareRepository
10
+ end
11
+ end
@@ -0,0 +1,69 @@
1
+ require 'r10k/git/shellgit'
2
+ require 'r10k/git/shellgit/cache'
3
+ require 'r10k/git/shellgit/working_repository'
4
+
5
+ # Manage a Git working repository backed with cached bare repositories. Instead
6
+ # of duplicating all objects for new clones and updates, this uses Git
7
+ # alternate object databases to reuse objects from an existing repository,
8
+ # making new clones very lightweight.
9
+ class R10K::Git::ShellGit::ThinRepository < R10K::Git::ShellGit::WorkingRepository
10
+
11
+ def initialize(basedir, dirname, cache_repo)
12
+ @cache_repo = cache_repo
13
+ super(basedir, dirname)
14
+ end
15
+
16
+ # Clone this git repository
17
+ #
18
+ # @param remote [String] The Git remote to clone
19
+ # @param opts [Hash]
20
+ #
21
+ # @options opts [String] :ref The git ref to check out on clone
22
+ #
23
+ # @return [void]
24
+ def clone(remote, opts = {})
25
+ # todo check if opts[:reference] is set
26
+ @cache_repo.sync
27
+
28
+ super(remote, opts.merge(:reference => @cache_repo.git_dir.to_s))
29
+ setup_cache_remote
30
+ end
31
+
32
+ # Fetch refs from the backing bare Git repository.
33
+ def fetch(remote = 'cache')
34
+ git ['fetch', remote], :path => @path.to_s
35
+ end
36
+
37
+ # @return [String] The origin remote URL
38
+ def cache
39
+ git(['config', '--get', 'remote.cache.url'], :path => @path.to_s, :raise_on_fail => false).stdout
40
+ end
41
+
42
+ def tracked_paths(ref="HEAD")
43
+ git(['ls-tree', '-t', '-r', '--name-only', ref], :path => @path.to_s).stdout.split("\n")
44
+ end
45
+
46
+ private
47
+
48
+ def setup_cache_remote
49
+ git ["remote", "add", "cache", @cache_repo.git_dir.to_s], :path => @path.to_s
50
+ fetch
51
+ end
52
+
53
+ def git(cmd, opts = {})
54
+ if !@_synced_alternates
55
+ sync_alternates
56
+ @_synced_alternates = true
57
+ end
58
+ super
59
+ end
60
+
61
+ def sync_alternates
62
+ if git_dir.exist?
63
+ entry_added = alternates.add?(@cache_repo.objects_dir.to_s)
64
+ if entry_added
65
+ logger.debug2 { _("Updated repo %{path} to include alternate object db path %{objects_dir}") % {path: @path, objects_dir: @cache_repo.objects_dir} }
66
+ end
67
+ end
68
+ end
69
+ end