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,39 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "a puppetfile action" do
4
+ describe "initializing" do
5
+ it "accepts the :root option" do
6
+ described_class.new({root: "/some/nonexistent/path"}, [])
7
+ end
8
+
9
+ it "accepts the :puppetfile option" do
10
+ described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [])
11
+ end
12
+
13
+ it "accepts the :moduledir option" do
14
+ described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ shared_examples_for "a puppetfile install action" do
21
+ describe "initializing" do
22
+ it "accepts the :root option" do
23
+ described_class.new({root: "/some/nonexistent/path"}, [])
24
+ end
25
+
26
+ it "accepts the :puppetfile option" do
27
+ described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [])
28
+ end
29
+
30
+ it "accepts the :moduledir option" do
31
+ described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
32
+ end
33
+
34
+ it "accepts the :force option" do
35
+ described_class.new({force: true}, [])
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ require 'r10k/settings/collection'
4
+ require 'r10k/settings/list'
5
+
6
+ shared_examples_for "a setting with ancestors" do
7
+ describe '#parent=' do
8
+ it "allows assignment to a collection" do
9
+ parent = R10K::Settings::Collection.new(:parent, [])
10
+
11
+ subject.parent = parent
12
+
13
+ expect(subject.parent).to eq parent
14
+ end
15
+
16
+ it "allows assignment to a list" do
17
+ parent = R10K::Settings::List.new(:parent, [])
18
+
19
+ subject.parent = parent
20
+
21
+ expect(subject.parent).to eq parent
22
+ end
23
+
24
+ it "rejects assignment when argument is not a settings collection or list" do
25
+ parent = Hash.new
26
+
27
+ expect { subject.parent = parent }.to raise_error do |error|
28
+ expect(error.message).to match /may only belong to a settings collection or list/i
29
+ end
30
+ end
31
+
32
+ it "rejects re-assignment" do
33
+ parent = R10K::Settings::Collection.new(:parent, [])
34
+ step_parent = R10K::Settings::Collection.new(:step_parent, [])
35
+
36
+ subject.parent = parent
37
+
38
+ expect { subject.parent = step_parent }.to raise_error do |error|
39
+ expect(error.message).to match /cannot be reassigned.*new parent/i
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,83 @@
1
+ shared_examples_for "a subprocess runner" do |fixture_root|
2
+
3
+ describe "running 'echo test'" do
4
+ subject { described_class.new(%w[echo test]) }
5
+
6
+ it "sets the exit code to 0" do
7
+ result = subject.run
8
+ expect(result.exit_code).to eq 0
9
+ end
10
+
11
+ it "returns the contents of stdout" do
12
+ result = subject.run
13
+ expect(result.stdout).to eq 'test'
14
+ end
15
+
16
+ it "indicates the command succeeded" do
17
+ result = subject.run
18
+ expect(result).to be_success
19
+ expect(result).to_not be_failed
20
+ end
21
+ end
22
+
23
+ describe "running a command with a large amount of output" do
24
+ subject do
25
+ described_class.new(['ruby', '-e', 'blob = "buffalo!" * (2 << 16); puts blob'])
26
+ end
27
+
28
+ it "does not hang" do
29
+ Timeout.timeout(5) do
30
+ subject.run
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "running 'ls' with a different working directory" do
36
+ subject do
37
+ described_class.new(%w[ls]).tap do |o|
38
+ o.cwd = fixture_root
39
+ end
40
+ end
41
+
42
+ it "returns the contents of the given working directory" do
43
+ result = subject.run
44
+ expect(result.stdout).to eq 'no-execute.sh'
45
+ end
46
+ end
47
+
48
+ describe "running 'false'" do
49
+ subject { described_class.new(%w[false]) }
50
+
51
+ it "sets the exit code to 1" do
52
+ result = subject.run
53
+ expect(result.exit_code).to eq 1
54
+ end
55
+
56
+ it "indicates the command failed" do
57
+ result = subject.run
58
+ expect(result).to_not be_success
59
+ expect(result).to be_failed
60
+ end
61
+ end
62
+
63
+ describe "running '/this/command/will/not/exist'" do
64
+ subject { described_class.new(%w[/this/command/will/not/exist]) }
65
+
66
+ it "indicates the command failed" do
67
+ result = subject.run
68
+ expect(result).to_not be_success
69
+ expect(result).to be_failed
70
+ end
71
+ end
72
+
73
+ describe "running a non-executable file", :unless => R10K::Util::Platform.windows? do
74
+ let(:fixture_file) { File.join(fixture_root, 'no-execute.sh') }
75
+ subject { described_class.new([fixture_file]) }
76
+
77
+ it "indicates the command failed" do
78
+ result = subject.run
79
+ expect(result).to_not be_success
80
+ expect(result).to be_failed
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,40 @@
1
+ PROJECT_ROOT = File.expand_path('..', File.dirname(__FILE__))
2
+
3
+ if ENV['COVERAGE']
4
+ require 'simplecov'
5
+ SimpleCov.start do
6
+ libdir = File.join(PROJECT_ROOT, 'lib')
7
+ add_filter do |src|
8
+ !src.filename.match(%r[\A#{libdir}])
9
+ end
10
+
11
+ %w[Deployment Source Environment Module Git SVN Action Util].each do |group|
12
+ add_group group, "lib/r10k/#{group.downcase}"
13
+ end
14
+ end
15
+ end
16
+
17
+ require 'r10k'
18
+
19
+ Dir.glob(File.expand_path('spec/shared-examples/**/*.rb', PROJECT_ROOT)).each { |file| require file }
20
+
21
+ require 'shared-contexts/git-fixtures'
22
+ require 'matchers/exit_with'
23
+ require 'matchers/match_realpath'
24
+ require 'r10k-mocks'
25
+
26
+ # Add a negated version of the change matcher.
27
+ RSpec::Matchers.define_negated_matcher :not_change, :change
28
+
29
+ RSpec.configure do |config|
30
+ config.before(:all) do
31
+ Log4r::Logger.global.level = Log4r::OFF
32
+ end
33
+ end
34
+
35
+ shared_context 'fail on execution' do
36
+ before do
37
+ allow_any_instance_of(described_class).to receive(:execute).and_raise "Tests should never invoke system calls"
38
+ allow_any_instance_of(R10K::Util::Subprocess).to receive(:execute).and_raise "Tests should never invoke system calls"
39
+ end
40
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'r10k/action/base'
3
+ require 'r10k/action/cri_runner'
4
+
5
+ describe R10K::Action::CriRunner do
6
+
7
+ let(:action_class) do
8
+ Class.new do
9
+ attr_reader :opts
10
+ attr_reader :argv
11
+
12
+ def initialize(opts, argv, settings = {})
13
+ @opts = opts
14
+ @argv = argv
15
+ @settings = {}
16
+ end
17
+
18
+ def call
19
+ @opts[:runok]
20
+ end
21
+ end
22
+ end
23
+
24
+ subject(:cri_runner) { described_class.wrap(action_class) }
25
+
26
+ let(:opts) { {:value => :yep} }
27
+ let(:argv) { %w[value yes] }
28
+
29
+ describe "handling options" do
30
+ it "adapts the :verbose flag to :loglevel" do
31
+ input = {:value => :yep, :verbose => 'DEBUG'}
32
+ output = {:value => :yep, :loglevel => 'DEBUG'}
33
+ expect(cri_runner.handle_opts(input)).to eq(output)
34
+ end
35
+ end
36
+
37
+ describe "handling arguments" do
38
+ it "sets the arguments as-is" do
39
+ expect(cri_runner.handle_argv(%w[one two])).to eq(%w[one two])
40
+ end
41
+ end
42
+
43
+ describe "proxying invocations to .new" do
44
+ it "returns itself" do
45
+ expect(cri_runner.new(opts, argv, :cri_cmd)).to eql cri_runner
46
+ end
47
+
48
+ it "handles options" do
49
+ expect(cri_runner).to receive(:handle_opts)
50
+ cri_runner.new({:value => :yep, :verbose => 'DEBUG'}, argv, :cri_cmd)
51
+ end
52
+
53
+ it "handles arguments" do
54
+ expect(cri_runner).to receive(:handle_argv)
55
+ cri_runner.new({:value => :yep, :verbose => 'DEBUG'}, argv, :cri_cmd)
56
+ end
57
+ end
58
+
59
+ describe "calling" do
60
+ it "exits with a return value of 0 if the action returned true" do
61
+ expect {
62
+ cri_runner.new({:runok => true}, []).call
63
+ }.to exit_with(0)
64
+ end
65
+
66
+ it "exits with a return value of 1 if the action returned false" do
67
+ expect {
68
+ cri_runner.new({:runok => false}, []).call
69
+ }.to exit_with(1)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ require 'r10k/logging'
4
+ require 'r10k/action/deploy/deploy_helpers'
5
+
6
+ describe R10K::Action::Deploy::DeployHelpers do
7
+ subject do
8
+ Object.new.tap do |o|
9
+ o.extend(R10K::Logging)
10
+ o.extend(described_class)
11
+ end
12
+ end
13
+
14
+ describe "checking for a config file" do
15
+ it "logs a warning and exits when no config file was set" do
16
+ logger = subject.logger
17
+
18
+ expect(logger).to receive(:fatal).with("No configuration file given, no config file found in current directory, and no global config present")
19
+
20
+ expect {
21
+ subject.expect_config!
22
+ }.to exit_with(8)
23
+ end
24
+ end
25
+
26
+ describe "checking the write lock setting" do
27
+ it "logs a warning and exits when the write lock is set" do
28
+ logger = subject.logger
29
+
30
+ expect(logger).to receive(:fatal).with("Making changes to deployed environments has been administratively disabled.")
31
+ expect(logger).to receive(:fatal).with("Reason: r10k is sleepy and wants to take a nap")
32
+
33
+ expect {
34
+ subject.check_write_lock!(deploy: {write_lock: "r10k is sleepy and wants to take a nap"})
35
+ }.to exit_with(16)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ require 'r10k/action/deploy/display'
4
+
5
+ describe R10K::Action::Deploy::Display do
6
+ describe "initializing" do
7
+ it "accepts a puppetfile option" do
8
+ described_class.new({puppetfile: true}, [])
9
+ end
10
+
11
+ it "accepts a detail option" do
12
+ described_class.new({detail: true}, [])
13
+ end
14
+
15
+ it "accepts a format option" do
16
+ described_class.new({format: "json"}, [])
17
+ end
18
+
19
+ it "accepts a fetch option" do
20
+ described_class.new({fetch: true}, [])
21
+ end
22
+ end
23
+
24
+ subject { described_class.new({config: "/some/nonexistent/path"}, []) }
25
+
26
+ before do
27
+ allow(subject).to receive(:puts)
28
+ end
29
+
30
+ it_behaves_like "a deploy action that requires a config file"
31
+ end
@@ -0,0 +1,395 @@
1
+ require 'spec_helper'
2
+
3
+ require 'r10k/deployment'
4
+ require 'r10k/action/deploy/environment'
5
+
6
+ describe R10K::Action::Deploy::Environment do
7
+
8
+ subject { described_class.new({config: "/some/nonexistent/path"}, []) }
9
+
10
+ it_behaves_like "a deploy action that can be write locked"
11
+ it_behaves_like "a deploy action that requires a config file"
12
+
13
+ describe "initializing" do
14
+ it "can accept a cachedir option" do
15
+ described_class.new({cachedir: "/some/nonexistent/cachedir"}, [])
16
+ end
17
+
18
+ it "can accept a puppetfile option" do
19
+ described_class.new({puppetfile: true}, [])
20
+ end
21
+
22
+ it "can accept a default_branch_override option" do
23
+ described_class.new({:'default-branch-override' => 'default_branch_override_name'}, [])
24
+ end
25
+
26
+ it "can accept a no-force option" do
27
+ described_class.new({:'no-force' => true}, [])
28
+ end
29
+
30
+ it "normalizes environment names in the arg vector"
31
+
32
+ it 'can accept a generate-types option' do
33
+ described_class.new({ 'generate-types': true }, [])
34
+ end
35
+
36
+ it 'can accept a puppet-path option' do
37
+ described_class.new({ 'puppet-path': '/nonexistent' }, [])
38
+ end
39
+ end
40
+
41
+ describe "when called" do
42
+ let(:mock_config) do
43
+ R10K::Deployment::MockConfig.new(
44
+ :sources => {
45
+ :control => {
46
+ :type => :mock,
47
+ :basedir => '/some/nonexistent/path/control',
48
+ :environments => %w[first second third env-that/will-be-corrected],
49
+ :prefix => 'PREFIX'
50
+ }
51
+ }
52
+ )
53
+ end
54
+
55
+ describe "with an environment that doesn't exist" do
56
+ let(:deployment) do
57
+ R10K::Deployment.new(mock_config)
58
+ end
59
+
60
+ before do
61
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
62
+ end
63
+
64
+ subject { described_class.new({config: "/some/nonexistent/path"}, %w[not_an_environment]) }
65
+
66
+ it "logs that the environments can't be deployed and returns false" do
67
+ expect(subject.logger).to receive(:error).with("Environment(s) 'not_an_environment' cannot be found in any source and will not be deployed.")
68
+ logger = subject.logger
69
+ expect(subject.call).to eq false
70
+ end
71
+ end
72
+
73
+ describe "with no-force" do
74
+ subject { described_class.new({ config: "/some/nonexistent/path", puppetfile: true, :'no-force' => true}, %w[first]) }
75
+
76
+ it "tries to preserve local modifications" do
77
+ expect(subject.force).to equal(false)
78
+ end
79
+ end
80
+
81
+ describe "postrun" do
82
+ context "basic postrun hook" do
83
+ let(:settings) { { postrun: ["/path/to/executable", "arg1", "arg2"] } }
84
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
85
+
86
+ before do
87
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
88
+ end
89
+
90
+ subject do
91
+ described_class.new( {config: "/some/nonexistent/path" },
92
+ %w[PREFIX_first],
93
+ settings )
94
+ end
95
+
96
+ it "is passed to Subprocess" do
97
+ mock_subprocess = double
98
+ allow(mock_subprocess).to receive(:logger=)
99
+ expect(mock_subprocess).to receive(:execute)
100
+
101
+ expect(R10K::Util::Subprocess).to receive(:new).
102
+ with(["/path/to/executable", "arg1", "arg2"]).
103
+ and_return(mock_subprocess)
104
+
105
+ subject.call
106
+ end
107
+ end
108
+
109
+ context "supports environments" do
110
+ context "when one environment" do
111
+ let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
112
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
113
+
114
+ before do
115
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
116
+ end
117
+
118
+ subject do
119
+ described_class.new( {config: "/some/nonexistent/path" },
120
+ %w[PREFIX_first],
121
+ settings )
122
+ end
123
+
124
+ it "properly substitutes the environment" do
125
+ mock_subprocess = double
126
+ allow(mock_subprocess).to receive(:logger=)
127
+ expect(mock_subprocess).to receive(:execute)
128
+
129
+ expect(R10K::Util::Subprocess).to receive(:new).
130
+ with(["/generate/types/wrapper", "PREFIX_first"]).
131
+ and_return(mock_subprocess)
132
+
133
+ subject.call
134
+ end
135
+ end
136
+ context "when many environments" do
137
+ let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
138
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
139
+
140
+ before do
141
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
142
+ end
143
+
144
+ subject do
145
+ described_class.new( {config: "/some/nonexistent/path" },
146
+ [],
147
+ settings )
148
+ end
149
+
150
+ it "properly substitutes the environment" do
151
+ mock_subprocess = double
152
+ allow(mock_subprocess).to receive(:logger=)
153
+ expect(mock_subprocess).to receive(:execute)
154
+
155
+ expect(R10K::Util::Subprocess).to receive(:new).
156
+ with(["/generate/types/wrapper", "PREFIX_first PREFIX_second PREFIX_third PREFIX_env_that_will_be_corrected"]).
157
+ and_return(mock_subprocess)
158
+
159
+ subject.call
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ describe "purge_levels" do
166
+ let(:settings) { { deploy: { purge_levels: purge_levels } } }
167
+
168
+ let(:deployment) do
169
+ R10K::Deployment.new(mock_config.merge(settings))
170
+ end
171
+
172
+ before do
173
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
174
+ end
175
+
176
+ subject { described_class.new({ config: "/some/nonexistent/path", puppetfile: true }, %w[PREFIX_first], settings) }
177
+
178
+ describe "deployment purge level" do
179
+ let(:purge_levels) { [:deployment] }
180
+
181
+ it "only logs about purging deployment" do
182
+ expect(subject.logger).to receive(:debug).with(/purging unmanaged environments for deployment/i)
183
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged content for environment/i)
184
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
185
+
186
+ subject.call
187
+ end
188
+ end
189
+
190
+ describe "environment purge level" do
191
+ let(:purge_levels) { [:environment] }
192
+
193
+ it "only logs about purging environment" do
194
+ expect(subject.logger).to receive(:debug).with(/purging unmanaged content for environment/i)
195
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged environments for deployment/i)
196
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
197
+
198
+ subject.call
199
+ end
200
+
201
+ it "logs that environment was not purged if deploy failed" do
202
+ expect(subject).to receive(:visit_puppetfile) { subject.instance_variable_set(:@visit_ok, false) }
203
+
204
+ expect(subject.logger).to receive(:debug).with(/not purging unmanaged content for environment/i)
205
+
206
+ subject.call
207
+ end
208
+ end
209
+
210
+ describe "puppetfile purge level" do
211
+ let(:purge_levels) { [:puppetfile] }
212
+
213
+ it "only logs about purging puppetfile" do
214
+ expect(subject.logger).to receive(:debug).with(/purging unmanaged puppetfile content/i)
215
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged environments for deployment/i)
216
+ expect(subject.logger).to_not receive(:debug).with(/purging unmanaged content for environment/i)
217
+
218
+ subject.call
219
+ end
220
+ end
221
+ end
222
+ describe "generate-types" do
223
+ let(:deployment) do
224
+ R10K::Deployment.new(
225
+ R10K::Deployment::MockConfig.new(
226
+ sources: {
227
+ control: {
228
+ type: :mock,
229
+ basedir: '/some/nonexistent/path/control',
230
+ environments: %w[first second]
231
+ }
232
+ }
233
+ )
234
+ )
235
+ end
236
+
237
+ before do
238
+ allow(R10K::Deployment).to receive(:new).and_return(deployment)
239
+ end
240
+
241
+ before(:each) do
242
+ allow(subject).to receive(:write_environment_info!)
243
+ expect(subject.logger).not_to receive(:error)
244
+ end
245
+
246
+ context 'with generate-types enabled' do
247
+ subject do
248
+ described_class.new(
249
+ {
250
+ config: '/some/nonexistent/path',
251
+ puppetfile: true,
252
+ 'generate-types': true
253
+ },
254
+ %w[first second]
255
+ )
256
+ end
257
+
258
+ it 'generate_types is true' do
259
+ expect(subject.instance_variable_get(:@generate_types)).to eq(true)
260
+ end
261
+
262
+ it 'only calls puppet generate types on specified environment' do
263
+ subject.instance_variable_set(:@argv, %w[first])
264
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
265
+ if environment.dirname == 'first'
266
+ expect(environment).to receive(:generate_types!)
267
+ else
268
+ expect(environment).not_to receive(:generate_types!)
269
+ end
270
+ original.call(environment, &block)
271
+ end.twice
272
+ subject.call
273
+ end
274
+
275
+ it 'does not call puppet generate types on puppetfile failure' do
276
+ allow(subject).to receive(:visit_puppetfile) { subject.instance_variable_set(:@visit_ok, false) }
277
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
278
+ expect(environment).not_to receive(:generate_types!)
279
+ original.call(environment, &block)
280
+ end.twice
281
+ subject.call
282
+ end
283
+
284
+ it 'calls puppet generate types on previous puppetfile failure' do
285
+ allow(subject).to receive(:visit_puppetfile) do |puppetfile|
286
+ subject.instance_variable_set(:@visit_ok, false) if puppetfile.environment.dirname == 'first'
287
+ end
288
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
289
+ if environment.dirname == 'second'
290
+ expect(environment).to receive(:generate_types!)
291
+ else
292
+ expect(environment).not_to receive(:generate_types!)
293
+ end
294
+ original.call(environment, &block)
295
+ end.twice
296
+ subject.call
297
+ end
298
+ end
299
+
300
+ context 'with generate-types disabled' do
301
+ subject do
302
+ described_class.new(
303
+ {
304
+ config: '/some/nonexistent/path',
305
+ puppetfile: true,
306
+ 'generate-types': false
307
+ },
308
+ %w[first]
309
+ )
310
+ end
311
+
312
+ it 'generate_types is false' do
313
+ expect(subject.instance_variable_get(:@generate_types)).to eq(false)
314
+ end
315
+
316
+ it 'does not call puppet generate types' do
317
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
318
+ expect(environment).not_to receive(:generate_types!)
319
+ original.call(environment, &block)
320
+ end.twice
321
+ subject.call
322
+ end
323
+ end
324
+ end
325
+
326
+ describe 'with puppet-path' do
327
+
328
+ subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-path': '/nonexistent' }, []) }
329
+
330
+ it 'sets puppet_path' do
331
+ expect(subject.instance_variable_get(:@puppet_path)).to eq('/nonexistent')
332
+ end
333
+ end
334
+ end
335
+
336
+ describe "write_environment_info!" do
337
+
338
+ class Fake_Environment
339
+ attr_accessor :path
340
+ attr_accessor :puppetfile
341
+ attr_accessor :info
342
+
343
+ def initialize(path, info)
344
+ @path = path
345
+ @info = info
346
+ @puppetfile = R10K::Puppetfile.new
347
+ end
348
+ end
349
+
350
+ let(:mock_stateful_repo_1) { instance_double("R10K::Git::StatefulRepository", :head => "123456") }
351
+ let(:mock_stateful_repo_2) { instance_double("R10K::Git::StatefulRepository", :head => "654321") }
352
+ let(:mock_git_module_1) { instance_double("R10K::Module::Git", :name => "my_cool_module", :version => "1.0", :repo => mock_stateful_repo_1) }
353
+ let(:mock_git_module_2) { instance_double("R10K::Module::Git", :name => "my_lame_module", :version => "0.0.1", :repo => mock_stateful_repo_2) }
354
+ let(:mock_forge_module_1) { double(:name => "their_shiny_module", :version => "2.0.0") }
355
+ let(:mock_puppetfile) { instance_double("R10K::Puppetfile", :modules => [mock_git_module_1, mock_git_module_2, mock_forge_module_1]) }
356
+
357
+ before(:all) do
358
+ @tmp_path = "./tmp-r10k-test-dir/"
359
+ Dir.mkdir(@tmp_path) unless File.exists?(@tmp_path)
360
+ end
361
+
362
+ after(:all) do
363
+ File.delete("#{@tmp_path}/.r10k-deploy.json")
364
+ Dir.delete(@tmp_path)
365
+ end
366
+
367
+ it "writes the .r10k-deploy file correctly" do
368
+ allow(R10K::Puppetfile).to receive(:new).and_return(mock_puppetfile)
369
+ allow(mock_forge_module_1).to receive(:repo).and_raise(NoMethodError)
370
+
371
+ fake_env = Fake_Environment.new(@tmp_path, {:name => "my_cool_environment", :signature => "pablo picasso"})
372
+ allow(fake_env).to receive(:modules).and_return(mock_puppetfile.modules)
373
+ subject.send(:write_environment_info!, fake_env, "2019-01-01 23:23:22 +0000", true)
374
+
375
+ file_contents = File.read("#{@tmp_path}/.r10k-deploy.json")
376
+ r10k_deploy = JSON.parse(file_contents)
377
+
378
+ expect(r10k_deploy['name']).to eq("my_cool_environment")
379
+ expect(r10k_deploy['signature']).to eq("pablo picasso")
380
+ expect(r10k_deploy['started_at']).to eq("2019-01-01 23:23:22 +0000")
381
+ expect(r10k_deploy['deploy_success']).to eq(true)
382
+ expect(r10k_deploy['module_deploys'].length).to eq(3)
383
+ expect(r10k_deploy['module_deploys'][0]['name']).to eq("my_cool_module")
384
+ expect(r10k_deploy['module_deploys'][0]['version']).to eq("1.0")
385
+ expect(r10k_deploy['module_deploys'][0]['sha']).to eq("123456")
386
+ expect(r10k_deploy['module_deploys'][1]['name']).to eq("my_lame_module")
387
+ expect(r10k_deploy['module_deploys'][1]['version']).to eq("0.0.1")
388
+ expect(r10k_deploy['module_deploys'][1]['sha']).to eq("654321")
389
+ expect(r10k_deploy['module_deploys'][2]['name']).to eq("their_shiny_module")
390
+ expect(r10k_deploy['module_deploys'][2]['version']).to eq("2.0.0")
391
+ expect(r10k_deploy['module_deploys'][2]['sha']).to eq(nil)
392
+
393
+ end
394
+ end
395
+ end