puppet 3.5.1-x86-mingw32 → 3.6.0.rc1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (342) hide show
  1. data/CONTRIBUTING.md +5 -0
  2. data/Gemfile +17 -9
  3. data/README.md +1 -0
  4. data/conf/fileserver.conf +4 -3
  5. data/ext/README.environment +8 -0
  6. data/ext/build_defaults.yaml +1 -1
  7. data/ext/debian/control +2 -2
  8. data/ext/debian/puppet-common.dirs +4 -0
  9. data/ext/debian/rules +4 -0
  10. data/ext/emacs/puppet-mode-init.el +1 -1
  11. data/ext/emacs/puppet-mode.el +36 -17
  12. data/ext/redhat/client.init +3 -3
  13. data/ext/redhat/puppet.spec.erb +9 -0
  14. data/ext/systemd/puppet.service +3 -4
  15. data/ext/systemd/puppetmaster.service +1 -3
  16. data/install.rb +1 -1
  17. data/lib/puppet.rb +2 -1
  18. data/lib/puppet/agent.rb +1 -1
  19. data/lib/puppet/application.rb +17 -17
  20. data/lib/puppet/application/doc.rb +1 -1
  21. data/lib/puppet/configurer.rb +4 -1
  22. data/lib/puppet/configurer/downloader.rb +13 -12
  23. data/lib/puppet/configurer/plugin_handler.rb +3 -3
  24. data/lib/puppet/context.rb +6 -1
  25. data/lib/puppet/defaults.rb +82 -12
  26. data/lib/puppet/environments.rb +169 -13
  27. data/lib/puppet/external/nagios/grammar.ry +2 -0
  28. data/lib/puppet/external/nagios/parser.rb +28 -19
  29. data/lib/puppet/face/config.rb +19 -6
  30. data/lib/puppet/face/module/generate.rb +209 -7
  31. data/lib/puppet/face/module/install.rb +17 -16
  32. data/lib/puppet/face/module/list.rb +83 -82
  33. data/lib/puppet/face/module/search.rb +1 -1
  34. data/lib/puppet/face/module/upgrade.rb +10 -9
  35. data/lib/puppet/face/parser.rb +3 -2
  36. data/lib/puppet/face/plugin.rb +8 -4
  37. data/lib/puppet/file_bucket/dipper.rb +6 -3
  38. data/lib/puppet/file_bucket/file.rb +4 -2
  39. data/lib/puppet/file_serving/metadata.rb +1 -1
  40. data/lib/puppet/file_system/memory_file.rb +27 -1
  41. data/lib/puppet/file_system/memory_impl.rb +15 -1
  42. data/lib/puppet/forge.rb +148 -52
  43. data/lib/puppet/forge/cache.rb +5 -1
  44. data/lib/puppet/forge/errors.rb +10 -0
  45. data/lib/puppet/forge/repository.rb +61 -26
  46. data/lib/puppet/functions.rb +548 -0
  47. data/lib/puppet/functions/assert_type.rb +42 -0
  48. data/lib/puppet/functions/import.rb +7 -0
  49. data/lib/puppet/indirector/facts/facter.rb +1 -1
  50. data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
  51. data/lib/puppet/indirector/rest.rb +18 -0
  52. data/lib/puppet/loaders.rb +20 -0
  53. data/lib/puppet/module.rb +2 -2
  54. data/lib/puppet/module_tool.rb +40 -14
  55. data/lib/puppet/module_tool/applications.rb +0 -1
  56. data/lib/puppet/module_tool/applications/application.rb +35 -26
  57. data/lib/puppet/module_tool/applications/builder.rb +16 -6
  58. data/lib/puppet/module_tool/applications/checksummer.rb +25 -19
  59. data/lib/puppet/module_tool/applications/installer.rb +196 -35
  60. data/lib/puppet/module_tool/applications/searcher.rb +1 -0
  61. data/lib/puppet/module_tool/applications/uninstaller.rb +7 -1
  62. data/lib/puppet/module_tool/applications/unpacker.rb +57 -31
  63. data/lib/puppet/module_tool/applications/upgrader.rb +221 -65
  64. data/lib/puppet/module_tool/checksums.rb +5 -8
  65. data/lib/puppet/module_tool/errors/installer.rb +12 -44
  66. data/lib/puppet/module_tool/errors/shared.rb +84 -11
  67. data/lib/puppet/module_tool/errors/upgrader.rb +16 -45
  68. data/lib/puppet/module_tool/install_directory.rb +7 -6
  69. data/lib/puppet/module_tool/installed_modules.rb +92 -0
  70. data/lib/puppet/module_tool/local_tarball.rb +91 -0
  71. data/lib/puppet/module_tool/metadata.rb +119 -115
  72. data/lib/puppet/module_tool/modulefile.rb +9 -9
  73. data/lib/puppet/module_tool/shared_behaviors.rb +19 -7
  74. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +79 -0
  75. data/lib/puppet/module_tool/skeleton/templates/generator/Rakefile +18 -0
  76. data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json.erb +1 -0
  77. data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +7 -0
  78. data/lib/puppet/module_tool/tar.rb +3 -7
  79. data/lib/puppet/module_tool/tar/gnu.rb +21 -9
  80. data/lib/puppet/module_tool/tar/mini.rb +2 -8
  81. data/lib/puppet/network/http/api/v1.rb +1 -1
  82. data/lib/puppet/network/http/api/v2/authorization.rb +4 -2
  83. data/lib/puppet/network/http/issues.rb +1 -0
  84. data/lib/puppet/network/http_pool.rb +15 -6
  85. data/lib/puppet/node/environment.rb +91 -20
  86. data/lib/puppet/parser/ast/pops_bridge.rb +44 -3
  87. data/lib/puppet/parser/collector.rb +1 -1
  88. data/lib/puppet/parser/compiler.rb +50 -7
  89. data/lib/puppet/parser/functions.rb +6 -0
  90. data/lib/puppet/parser/functions/generate.rb +1 -1
  91. data/lib/puppet/parser/resource.rb +1 -1
  92. data/lib/puppet/pops.rb +22 -1
  93. data/lib/puppet/pops/adapters.rb +8 -1
  94. data/lib/puppet/pops/binder/bindings_composer.rb +1 -1
  95. data/lib/puppet/pops/binder/bindings_factory.rb +1 -1
  96. data/lib/puppet/pops/binder/config/binder_config_checker.rb +1 -1
  97. data/lib/puppet/pops/binder/producers.rb +2 -2
  98. data/lib/puppet/pops/evaluator/access_operator.rb +65 -25
  99. data/lib/puppet/pops/evaluator/callable_signature.rb +101 -0
  100. data/lib/puppet/pops/evaluator/closure.rb +57 -2
  101. data/lib/puppet/pops/evaluator/compare_operator.rb +1 -1
  102. data/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -11
  103. data/lib/puppet/pops/evaluator/runtime3_support.rb +72 -21
  104. data/lib/puppet/pops/functions/dispatch.rb +71 -0
  105. data/lib/puppet/pops/functions/dispatcher.rb +237 -0
  106. data/lib/puppet/pops/functions/function.rb +77 -0
  107. data/lib/puppet/pops/issues.rb +12 -0
  108. data/lib/puppet/pops/loader/base_loader.rb +102 -0
  109. data/lib/puppet/pops/loader/dependency_loader.rb +60 -0
  110. data/lib/puppet/pops/loader/gem_support.rb +49 -0
  111. data/lib/puppet/pops/loader/loader.rb +180 -0
  112. data/lib/puppet/pops/loader/loader_paths.rb +137 -0
  113. data/lib/puppet/pops/loader/module_loaders.rb +242 -0
  114. data/lib/puppet/pops/loader/null_loader.rb +44 -0
  115. data/lib/puppet/pops/loader/ruby_function_instantiator.rb +34 -0
  116. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +109 -0
  117. data/lib/puppet/pops/loader/simple_environment_loader.rb +20 -0
  118. data/lib/puppet/pops/loader/static_loader.rb +69 -0
  119. data/lib/puppet/pops/loader/uri_helper.rb +22 -0
  120. data/lib/puppet/pops/loaders.rb +240 -0
  121. data/lib/puppet/pops/model/factory.rb +13 -5
  122. data/lib/puppet/pops/model/model_tree_dumper.rb +12 -4
  123. data/lib/puppet/pops/parser/egrammar.ra +31 -18
  124. data/lib/puppet/pops/parser/eparser.rb +1137 -1106
  125. data/lib/puppet/pops/parser/lexer2.rb +17 -16
  126. data/lib/puppet/pops/semantic_error.rb +17 -0
  127. data/lib/puppet/pops/types/type_calculator.rb +150 -15
  128. data/lib/puppet/pops/types/type_factory.rb +69 -0
  129. data/lib/puppet/pops/types/type_parser.rb +9 -0
  130. data/lib/puppet/pops/types/types.rb +65 -4
  131. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  132. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -1
  133. data/lib/puppet/property/list.rb +1 -1
  134. data/lib/puppet/provider/augeas/augeas.rb +2 -2
  135. data/lib/puppet/provider/cron/crontab.rb +13 -2
  136. data/lib/puppet/provider/package.rb +24 -0
  137. data/lib/puppet/provider/package/apt.rb +6 -1
  138. data/lib/puppet/provider/package/gem.rb +8 -2
  139. data/lib/puppet/provider/package/msi.rb +0 -15
  140. data/lib/puppet/provider/package/openbsd.rb +0 -24
  141. data/lib/puppet/provider/package/rpm.rb +3 -29
  142. data/lib/puppet/provider/package/windows.rb +0 -15
  143. data/lib/puppet/provider/package/yum.rb +101 -24
  144. data/lib/puppet/provider/package/yumhelper.py +31 -1
  145. data/lib/puppet/provider/package/zypper.rb +10 -28
  146. data/lib/puppet/provider/service/debian.rb +1 -1
  147. data/lib/puppet/provider/service/init.rb +3 -0
  148. data/lib/puppet/provider/service/openbsd.rb +318 -0
  149. data/lib/puppet/provider/service/redhat.rb +6 -3
  150. data/lib/puppet/provider/service/systemd.rb +2 -2
  151. data/lib/puppet/provider/yumrepo/inifile.rb +115 -42
  152. data/lib/puppet/resource.rb +13 -9
  153. data/lib/puppet/resource/catalog.rb +12 -6
  154. data/lib/puppet/resource/type_collection.rb +3 -3
  155. data/lib/puppet/settings.rb +57 -36
  156. data/lib/puppet/settings/config_file.rb +5 -0
  157. data/lib/puppet/settings/environment_conf.rb +147 -0
  158. data/lib/puppet/settings/ttl_setting.rb +48 -0
  159. data/lib/puppet/ssl/certificate_authority.rb +2 -3
  160. data/lib/puppet/ssl/certificate_authority/autosign_command.rb +1 -1
  161. data/lib/puppet/ssl/certificate_request.rb +4 -4
  162. data/lib/puppet/ssl/validator/default_validator.rb +2 -2
  163. data/lib/puppet/status.rb +1 -1
  164. data/lib/puppet/test/test_helper.rb +1 -0
  165. data/lib/puppet/type/augeas.rb +13 -1
  166. data/lib/puppet/type/cron.rb +32 -18
  167. data/lib/puppet/type/file.rb +4 -2
  168. data/lib/puppet/type/file/checksum.rb +15 -5
  169. data/lib/puppet/type/file/content.rb +3 -1
  170. data/lib/puppet/type/file/source.rb +5 -5
  171. data/lib/puppet/type/package.rb +12 -17
  172. data/lib/puppet/type/resources.rb +3 -1
  173. data/lib/puppet/type/scheduled_task.rb +4 -5
  174. data/lib/puppet/type/service.rb +12 -2
  175. data/lib/puppet/type/user.rb +106 -0
  176. data/lib/puppet/type/yumrepo.rb +9 -1
  177. data/lib/puppet/util/checksums.rb +60 -1
  178. data/lib/puppet/util/diff.rb +3 -1
  179. data/lib/puppet/util/execution.rb +20 -16
  180. data/lib/puppet/util/feature.rb +3 -0
  181. data/lib/puppet/util/logging.rb +19 -12
  182. data/lib/puppet/util/rubygems.rb +10 -0
  183. data/lib/puppet/util/watched_file.rb +1 -1
  184. data/lib/puppet/util/windows/security.rb +5 -3
  185. data/lib/puppet/vendor/load_semantic.rb +1 -0
  186. data/lib/puppet/vendor/require_vendored.rb +2 -0
  187. data/lib/puppet/vendor/semantic/Gemfile +20 -0
  188. data/lib/puppet/vendor/semantic/Rakefile +69 -0
  189. data/lib/puppet/vendor/semantic/lib/semantic.rb +7 -0
  190. data/lib/puppet/vendor/semantic/lib/semantic/dependency.rb +181 -0
  191. data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph.rb +60 -0
  192. data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph_node.rb +117 -0
  193. data/lib/puppet/vendor/semantic/lib/semantic/dependency/module_release.rb +46 -0
  194. data/lib/puppet/vendor/semantic/lib/semantic/dependency/source.rb +25 -0
  195. data/lib/puppet/vendor/semantic/lib/semantic/dependency/unsatisfiable_graph.rb +31 -0
  196. data/lib/puppet/vendor/semantic/lib/semantic/version.rb +168 -0
  197. data/lib/puppet/vendor/semantic/lib/semantic/version_range.rb +424 -0
  198. data/lib/puppet/vendor/semantic/spec/spec_helper.rb +24 -0
  199. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_node_spec.rb +141 -0
  200. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_spec.rb +162 -0
  201. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/module_release_spec.rb +143 -0
  202. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/source_spec.rb +5 -0
  203. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/unsatisfiable_graph_spec.rb +44 -0
  204. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency_spec.rb +383 -0
  205. data/lib/puppet/vendor/semantic/spec/unit/semantic/version_range_spec.rb +307 -0
  206. data/lib/puppet/vendor/semantic/spec/unit/semantic/version_spec.rb +608 -0
  207. data/lib/puppet/version.rb +1 -1
  208. data/spec/fixtures/java.tgz +0 -0
  209. data/spec/fixtures/stdlib.tgz +0 -0
  210. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/usee/lib/puppet/functions/usee/callee.rb +5 -0
  211. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/lib/puppet/functions/user/caller.rb +5 -0
  212. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/metadata.json +9 -0
  213. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/modulea/rb_func_a.rb +5 -0
  214. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/rb_func_a.rb +5 -0
  215. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/manifests/init.pp +3 -0
  216. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +19 -0
  217. data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/lib/puppet/functions/moduleb/rb_func_b.rb +6 -0
  218. data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/manifests/init.pp +3 -0
  219. data/spec/fixtures/unit/provider/naginator/define_empty_param +6 -0
  220. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +7 -0
  221. data/spec/fixtures/unit/type/user/authorized_keys +5 -0
  222. data/spec/integration/application/apply_spec.rb +1 -2
  223. data/spec/integration/configurer_spec.rb +2 -2
  224. data/spec/integration/faces/plugin_spec.rb +62 -0
  225. data/spec/integration/indirector/catalog/compiler_spec.rb +1 -1
  226. data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
  227. data/spec/integration/node/environment_spec.rb +2 -2
  228. data/spec/integration/parser/future_compiler_spec.rb +96 -142
  229. data/spec/integration/parser/ruby_manifest_spec.rb +0 -5
  230. data/spec/integration/provider/cron/crontab_spec.rb +35 -0
  231. data/spec/integration/type/file_spec.rb +74 -72
  232. data/spec/integration/util/windows/security_spec.rb +17 -0
  233. data/spec/lib/matchers/resource.rb +45 -13
  234. data/spec/lib/puppet_spec/files.rb +18 -0
  235. data/spec/lib/puppet_spec/module_tool/shared_functions.rb +56 -0
  236. data/spec/lib/puppet_spec/module_tool/stub_source.rb +133 -0
  237. data/spec/shared_contexts/checksums.rb +55 -0
  238. data/spec/unit/application/apply_spec.rb +10 -7
  239. data/spec/unit/application/doc_spec.rb +17 -10
  240. data/spec/unit/application/indirection_base_spec.rb +18 -10
  241. data/spec/unit/application/inspect_spec.rb +22 -20
  242. data/spec/unit/configurer/downloader_spec.rb +7 -6
  243. data/spec/unit/configurer/plugin_handler_spec.rb +5 -8
  244. data/spec/unit/configurer_spec.rb +1 -1
  245. data/spec/unit/context_spec.rb +23 -0
  246. data/spec/unit/environments_spec.rb +274 -16
  247. data/spec/unit/face/config_spec.rb +111 -11
  248. data/spec/unit/face/module/install_spec.rb +14 -85
  249. data/spec/unit/face/module/list_spec.rb +108 -62
  250. data/spec/unit/face/module/search_spec.rb +1 -1
  251. data/spec/unit/face/module/uninstall_spec.rb +21 -42
  252. data/spec/unit/face/parser_spec.rb +5 -2
  253. data/spec/unit/file_bucket/dipper_spec.rb +92 -86
  254. data/spec/unit/file_bucket/file_spec.rb +23 -75
  255. data/spec/unit/file_serving/metadata_spec.rb +74 -74
  256. data/spec/unit/forge/module_release_spec.rb +131 -0
  257. data/spec/unit/forge/repository_spec.rb +21 -20
  258. data/spec/unit/forge_spec.rb +99 -23
  259. data/spec/unit/functions/assert_type_spec.rb +59 -0
  260. data/spec/unit/functions4_spec.rb +671 -0
  261. data/spec/unit/indirector/catalog/static_compiler_spec.rb +2 -2
  262. data/spec/unit/indirector/facts/facter_spec.rb +9 -3
  263. data/spec/unit/indirector/file_bucket_file/file_spec.rb +156 -155
  264. data/spec/unit/indirector/rest_spec.rb +8 -0
  265. data/spec/unit/interface/face_collection_spec.rb +35 -23
  266. data/spec/unit/module_spec.rb +20 -8
  267. data/spec/unit/module_tool/applications/builder_spec.rb +40 -12
  268. data/spec/unit/module_tool/applications/checksummer_spec.rb +86 -105
  269. data/spec/unit/module_tool/applications/installer_spec.rb +293 -261
  270. data/spec/unit/module_tool/applications/searcher_spec.rb +1 -1
  271. data/spec/unit/module_tool/applications/uninstaller_spec.rb +90 -154
  272. data/spec/unit/module_tool/applications/unpacker_spec.rb +12 -12
  273. data/spec/unit/module_tool/applications/upgrader_spec.rb +286 -18
  274. data/spec/unit/module_tool/metadata_spec.rb +223 -14
  275. data/spec/unit/module_tool/tar/gnu_spec.rb +12 -9
  276. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  277. data/spec/unit/module_tool/tar_spec.rb +4 -18
  278. data/spec/unit/module_tool_spec.rb +123 -27
  279. data/spec/unit/network/formats_spec.rb +2 -2
  280. data/spec/unit/network/http_pool_spec.rb +21 -0
  281. data/spec/unit/network/rights_spec.rb +10 -8
  282. data/spec/unit/node/environment_spec.rb +27 -2
  283. data/spec/unit/parser/collector_spec.rb +1 -1
  284. data/spec/unit/parser/compiler_spec.rb +1 -1
  285. data/spec/unit/parser/functions/generate_spec.rb +4 -0
  286. data/spec/unit/pops/evaluator/access_ops_spec.rb +50 -11
  287. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +25 -0
  288. data/spec/unit/pops/loaders/dependency_loader_spec.rb +44 -0
  289. data/spec/unit/pops/loaders/loader_paths_spec.rb +66 -0
  290. data/spec/unit/pops/loaders/loaders_spec.rb +105 -0
  291. data/spec/unit/pops/loaders/module_loaders_spec.rb +119 -0
  292. data/spec/unit/pops/loaders/static_loader_spec.rb +46 -0
  293. data/spec/unit/pops/types/type_calculator_spec.rb +145 -10
  294. data/spec/unit/pops/types/type_factory_spec.rb +101 -0
  295. data/spec/unit/pops/types/type_parser_spec.rb +22 -0
  296. data/spec/unit/property/list_spec.rb +9 -1
  297. data/spec/unit/provider/augeas/augeas_spec.rb +58 -11
  298. data/spec/unit/provider/cron/crontab_spec.rb +1 -0
  299. data/spec/unit/provider/cron/parsed_spec.rb +15 -0
  300. data/spec/unit/provider/naginator_spec.rb +14 -0
  301. data/spec/unit/provider/package/apt_spec.rb +78 -64
  302. data/spec/unit/provider/package/gem_spec.rb +15 -0
  303. data/spec/unit/provider/package/rpm_spec.rb +6 -6
  304. data/spec/unit/provider/package/windows_spec.rb +1 -1
  305. data/spec/unit/provider/package/yum_spec.rb +199 -104
  306. data/spec/unit/provider/package/zypper_spec.rb +41 -15
  307. data/spec/unit/provider/service/openbsd_spec.rb +129 -22
  308. data/spec/unit/provider/service/redhat_spec.rb +18 -4
  309. data/spec/unit/provider/service/systemd_spec.rb +5 -9
  310. data/spec/unit/provider/service/upstart_spec.rb +1 -1
  311. data/spec/unit/provider/user/directoryservice_spec.rb +10 -0
  312. data/spec/unit/provider/yumrepo/inifile_spec.rb +171 -15
  313. data/spec/unit/resource/catalog_spec.rb +20 -104
  314. data/spec/unit/resource/type_collection_spec.rb +10 -9
  315. data/spec/unit/settings/config_file_spec.rb +29 -6
  316. data/spec/unit/settings/environment_conf_spec.rb +51 -0
  317. data/spec/unit/settings_spec.rb +97 -12
  318. data/spec/unit/ssl/certificate_authority_spec.rb +2 -0
  319. data/spec/unit/type/augeas_spec.rb +1 -1
  320. data/spec/unit/type/cron_spec.rb +6 -7
  321. data/spec/unit/type/file/checksum_spec.rb +6 -0
  322. data/spec/unit/type/file/content_spec.rb +277 -207
  323. data/spec/unit/type/file_spec.rb +9 -7
  324. data/spec/unit/type/user_spec.rb +106 -18
  325. data/spec/unit/type/yumrepo_spec.rb +8 -0
  326. data/spec/unit/util/checksums_spec.rb +12 -5
  327. data/spec/unit/util/diff_spec.rb +8 -0
  328. data/spec/unit/util/execution_spec.rb +4 -4
  329. data/spec/unit/util/feature_spec.rb +2 -0
  330. data/spec/unit/util/logging_spec.rb +14 -4
  331. data/spec/unit/util/rdoc/parser_spec.rb +5 -4
  332. data/spec/unit/util/rubygems_spec.rb +14 -0
  333. data/tasks/parallel.rake +2 -2
  334. metadata +154 -21
  335. checksums.yaml +0 -7
  336. data/lib/puppet/module_tool/applications/generator.rb +0 -142
  337. data/lib/puppet/module_tool/skeleton.rb +0 -37
  338. data/lib/puppet/module_tool/skeleton/templates/generator/Modulefile.erb +0 -11
  339. data/lib/puppet/module_tool/skeleton/templates/generator/README.erb +0 -16
  340. data/lib/puppet/module_tool/tar/solaris.rb +0 -5
  341. data/spec/fixtures/unit/provider/service/systemd/list_units_services +0 -17
  342. data/spec/unit/module_tool/tar/solaris_spec.rb +0 -22
@@ -0,0 +1,49 @@
1
+ # GemSupport offers methods to find a gem's location by name or gem://gemname URI.
2
+ #
3
+ # TODO: The Puppet 3x, uses Puppet::Util::RubyGems to do this, and obtain paths, and avoids using ::Gems
4
+ # when ::Bundler is in effect. A quick check what happens on Ruby 1.8.7 and Ruby 1.9.3 with current
5
+ # version of bundler seems to work just fine without jumping through any hoops. Hopefully the Puppet::Utils::RubyGems is
6
+ # just dealing with arcane things prior to RubyGems 1.8 that are not needed any more. To verify there is
7
+ # the need to set up a scenario where additional bundles than what Bundler allows for a given configuration are available
8
+ # and then trying to access those.
9
+ #
10
+ module Puppet::Pops::Loader::GemSupport
11
+
12
+ # Produces the root directory of a gem given as an URI (gem://gemname/optional/path), or just the
13
+ # gemname as a string.
14
+ #
15
+ def gem_dir(uri_or_string)
16
+ case uri_or_string
17
+ when URI
18
+ gem_dir_from_uri(uri_or_string)
19
+ when String
20
+ gem_dir_from_name(uri_or_string)
21
+ end
22
+ end
23
+
24
+ # Produces the root directory of a gem given as an uri, where hostname is the gemname, and an optional
25
+ # path is appended to the root of the gem (i.e. if the reference is given to a sub-location within a gem.
26
+ # TODO: FIND by name raises exception Gem::LoadError with list of all gems on the path
27
+ #
28
+ def gem_dir_from_uri(uri)
29
+ unless spec = Gem::Specification.find_by_name(uri.hostname)
30
+ raise ArgumentError, "Gem not found #{uri}"
31
+ end
32
+ # if path given append that, else append given subdir
33
+ if uri.path.empty?
34
+ spec.gem_dir
35
+ else
36
+ File.join(spec.full_gem_path, uri.path)
37
+ end
38
+ end
39
+
40
+ # Produces the root directory of a gem given as a string with the gem's name.
41
+ # TODO: FIND by name raises exception Gem::LoadError with list of all gems on the path
42
+ #
43
+ def gem_dir_from_name(gem_name)
44
+ unless spec = Gem::Specification.find_by_name(gem_name)
45
+ raise ArgumentError, "Gem not found '#{gem_name}'"
46
+ end
47
+ spec.full_gem_path
48
+ end
49
+ end
@@ -0,0 +1,180 @@
1
+ # Loader
2
+ # ===
3
+ # A Loader is responsible for loading "entities" ("instantiable and executable objects in the puppet language" which
4
+ # are type, hostclass, definition, function, and bindings.
5
+ #
6
+ # The main method for users of a Loader is the `load` or `load_typed methods`, which returns a previously loaded entity
7
+ # of a given type/name, and searches and loads the entity if not already loaded.
8
+ #
9
+ # private entities
10
+ # ---
11
+ # TODO: handle loading of entities that are private. Suggest that all calls pass an origin_loader (the loader
12
+ # where request originated (or symbol :public). A module loader has one (or possibly a list) of what is
13
+ # considered to represent private loader - i.e. the dependency loader for a module. If an entity is private
14
+ # it should be stored with this status, and an error should be raised if the origin_loader is not on the list
15
+ # of accepted "private" loaders.
16
+ # The private loaders can not be given at creation time (they are parented by the loader in question). Another
17
+ # alternative is to check if the origin_loader is a child loader, but this requires bidirectional links
18
+ # between loaders or a search if loader with private entity is a parent of the origin_loader).
19
+ #
20
+ # @api public
21
+ #
22
+ class Puppet::Pops::Loader::Loader
23
+
24
+ # Produces the value associated with the given name if already loaded, or available for loading
25
+ # by this loader, one of its parents, or other loaders visible to this loader.
26
+ # This is the method an external party should use to "get" the named element.
27
+ #
28
+ # An implementor of this method should first check if the given name is already loaded by self, or a parent
29
+ # loader, and if so return that result. If not, it should call `find` to perform the loading.
30
+ #
31
+ # @param type [:Symbol] the type to load
32
+ # @param name [String, Symbol] the name of the entity to load
33
+ # @return [Object, nil] the value or nil if not found
34
+ #
35
+ # @api public
36
+ #
37
+ def load(type, name)
38
+ if result = load_typed(TypedName.new(type, name.to_s))
39
+ result.value
40
+ end
41
+ end
42
+
43
+ # Loads the given typed name, and returns a NamedEntry if found, else returns nil.
44
+ # This the same a `load`, but returns a NamedEntry with origin/value information.
45
+ #
46
+ # @param typed_name [TypedName] - the type, name combination to lookup
47
+ # @return [NamedEntry, nil] the entry containing the loaded value, or nil if not found
48
+ #
49
+ # @api public
50
+ #
51
+ def load_typed(typed_name)
52
+ raise NotImplementedError.new
53
+ end
54
+
55
+ # Produces the value associated with the given name if defined **in this loader**, or nil if not defined.
56
+ # This lookup does not trigger any loading, or search of the given name.
57
+ # An implementor of this method may not search or look up in any other loader, and it may not
58
+ # define the name.
59
+ #
60
+ # @param typed_name [TypedName] - the type, name combination to lookup
61
+ #
62
+ # @api private
63
+ #
64
+ def [] (typed_name)
65
+ if found = get_entry(typed_name)
66
+ found.value
67
+ else
68
+ nil
69
+ end
70
+ end
71
+
72
+ # Searches for the given name in this loader's context (parents should already have searched their context(s) without
73
+ # producing a result when this method is called).
74
+ # An implementation of find typically caches the result.
75
+ #
76
+ # @param typed_name [TypedName] the type, name combination to lookup
77
+ # @return [NamedEntry, nil] the entry for the loaded entry, or nil if not found
78
+ #
79
+ # @api private
80
+ #
81
+ def find(typed_name)
82
+ raise NotImplementedError.new
83
+ end
84
+
85
+ # Returns the parent of the loader, or nil, if this is the top most loader. This implementation returns nil.
86
+ def parent
87
+ nil
88
+ end
89
+
90
+ # Produces the private loader for loaders that have a one (the visibility given to loaded entities).
91
+ # For loaders that does not provide a private loader, self is returned.
92
+ #
93
+ # @api private
94
+ def private_loader
95
+ self
96
+ end
97
+
98
+ # Binds a value to a name. The name should not start with '::', but may contain multiple segments.
99
+ #
100
+ # @param type [:Symbol] the type of the entity being set
101
+ # @param name [String, Symbol] the name of the entity being set
102
+ # @param origin [URI, #uri, String] the origin of the set entity, a URI, or provider of URI, or URI in string form
103
+ # @return [NamedEntry, nil] the created entry
104
+ #
105
+ # @api private
106
+ #
107
+ def set_entry(type, name, value, origin = nil)
108
+ raise NotImplementedError.new
109
+ end
110
+
111
+ # Produces a NamedEntry if a value is bound to the given name, or nil if nothing is bound.
112
+ #
113
+ # @param typed_name [TypedName] the type, name combination to lookup
114
+ # @return [NamedEntry, nil] the value bound in an entry
115
+ #
116
+ # @api private
117
+ #
118
+ def get_entry(typed_name)
119
+ raise NotImplementedError.new
120
+ end
121
+
122
+ # An entry for one entity loaded by the loader.
123
+ #
124
+ class NamedEntry
125
+ attr_reader :typed_name
126
+ attr_reader :value
127
+ attr_reader :origin
128
+
129
+ def initialize(typed_name, value, origin)
130
+ @name = typed_name
131
+ @value = value
132
+ @origin = origin
133
+ freeze()
134
+ end
135
+ end
136
+
137
+ # A name/type combination that can be used as a compound hash key
138
+ #
139
+ class TypedName
140
+ attr_reader :type
141
+ attr_reader :name
142
+ attr_reader :name_parts
143
+
144
+ # True if name is qualified (more than a single segment)
145
+ attr_reader :qualified
146
+
147
+ def initialize(type, name)
148
+ @type = type
149
+ # relativize the name (get rid of leading ::), and make the split string available
150
+ @name_parts = name.to_s.split(/::/)
151
+ @name_parts.shift if name_parts[0].empty?
152
+ @name = name_parts.join('::')
153
+ @qualified = name_parts.size > 1
154
+ # precompute hash - the name is frozen, so this is safe to do
155
+ @hash = [self.class, type, @name].hash
156
+
157
+ # Not allowed to have numeric names - 0, 010, 0x10, 1.2 etc
158
+ if Puppet::Pops::Utils.is_numeric?(@name)
159
+ raise ArgumentError, "Illegal attempt to use a numeric name '#{name}' at #{origin_label(origin)}."
160
+ end
161
+
162
+ freeze()
163
+ end
164
+
165
+ def hash
166
+ @hash
167
+ end
168
+
169
+ def ==(o)
170
+ o.class == self.class && type == o.type && name == o.name
171
+ end
172
+
173
+ alias eql? ==
174
+
175
+ def to_s
176
+ "#{type}/#{name}"
177
+ end
178
+ end
179
+ end
180
+
@@ -0,0 +1,137 @@
1
+
2
+ # LoaderPaths
3
+ # ===
4
+ # The central loader knowledge about paths, what they represent and how to instantiate from them.
5
+ # Contains helpers (*smart paths*) to deal with lazy resolution of paths.
6
+ #
7
+ # TODO: Currently only supports loading of functions (3 kinds)
8
+ #
9
+ module Puppet::Pops::Loader::LoaderPaths
10
+ # Returns an array of SmartPath, each instantiated with a reference to the given loader (for root path resolution
11
+ # and existence checks). The smart paths in the array appear in precedence order. The returned array may be
12
+ # mutated.
13
+ #
14
+ def self.relative_paths_for_type(type, loader) #, start_index_in_name)
15
+ result =
16
+ case type # typed_name.type
17
+ when :function
18
+ if Puppet[:biff] == true
19
+ [FunctionPath4x.new(loader), FunctionPath3x.new(loader)]
20
+ else
21
+ [FunctionPath4x.new(loader)]
22
+ end
23
+
24
+ # when :xxx # TODO: Add all other types
25
+
26
+ else
27
+ # unknown types, simply produce an empty result; no paths to check, nothing to find... move along...
28
+ []
29
+ end
30
+ result
31
+ end
32
+
33
+ # # DO NOT REMOVE YET. needed later? when there is the need to decamel a classname
34
+ # def de_camel(fq_name)
35
+ # fq_name.to_s.gsub(/::/, '/').
36
+ # gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
37
+ # gsub(/([a-z\d])([A-Z])/,'\1_\2').
38
+ # tr("-", "_").
39
+ # downcase
40
+ # end
41
+
42
+ class SmartPath
43
+ # Generic path, in the sense of "if there are any entities of this kind to load, where are they?"
44
+ attr_reader :generic_path
45
+
46
+ # Creates SmartPath for the given loader (loader knows how to check for existence etc.)
47
+ def initialize(loader)
48
+ @loader = loader
49
+ end
50
+
51
+ def generic_path()
52
+ return @generic_path unless @generic_path.nil?
53
+
54
+ root_path = @loader.path
55
+ @generic_path = (root_path.nil? ? relative_path : File.join(root_path, relative_path))
56
+ end
57
+
58
+ # Effective path is the generic path + the name part(s) + extension.
59
+ #
60
+ def effective_path(typed_name, start_index_in_name)
61
+ "#{File.join(generic_path, typed_name.name_parts)}#{extension}"
62
+ end
63
+
64
+ def relative_path()
65
+ raise NotImplementedError.new
66
+ end
67
+
68
+ def instantiator()
69
+ raise NotImplementedError.new
70
+ end
71
+ end
72
+
73
+ class RubySmartPath < SmartPath
74
+ def extension
75
+ ".rb"
76
+ end
77
+
78
+ # Duplication of extension information, but avoids one call
79
+ def effective_path(typed_name, start_index_in_name)
80
+ "#{File.join(generic_path, typed_name.name_parts)}.rb"
81
+ end
82
+ end
83
+
84
+ class FunctionPath4x < RubySmartPath
85
+ FUNCTION_PATH_4X = File.join('lib', 'puppet', 'functions')
86
+
87
+ def relative_path
88
+ FUNCTION_PATH_4X
89
+ end
90
+
91
+ def instantiator()
92
+ Puppet::Pops::Loader::RubyFunctionInstantiator
93
+ end
94
+ end
95
+
96
+ class FunctionPath3x < RubySmartPath
97
+ FUNCTION_PATH_3X = File.join('lib', 'puppet', 'parser', 'functions')
98
+
99
+ def relative_path
100
+ FUNCTION_PATH_3X
101
+ end
102
+
103
+ def instantiator()
104
+ Puppet::Pops::Loader::RubyLegacyFunctionInstantiator
105
+ end
106
+ end
107
+
108
+ # SmartPaths
109
+ # ===
110
+ # Holds effective SmartPath instances per type
111
+ #
112
+ class SmartPaths
113
+ def initialize(path_based_loader)
114
+ @loader = path_based_loader
115
+ @smart_paths = {}
116
+ end
117
+
118
+ # Ensures that the paths for the type have been probed and pruned to what is existing relative to
119
+ # the given root.
120
+ #
121
+ # @param type [Symbol] the entity type to load
122
+ # @return [Array<SmartPath>] array of effective paths for type (may be empty)
123
+ #
124
+ def effective_paths(type)
125
+ smart_paths = @smart_paths
126
+ loader = @loader
127
+ unless effective_paths = smart_paths[type]
128
+ # type not yet processed, does the various directories for the type exist ?
129
+ # Get the relative dirs for the type
130
+ paths_for_type = Puppet::Pops::Loader::LoaderPaths.relative_paths_for_type(type, loader)
131
+ # Check which directories exist in the loader's content/index
132
+ effective_paths = smart_paths[type] = paths_for_type.select { |sp| loader.meaningful_to_search?(sp) }
133
+ end
134
+ effective_paths
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,242 @@
1
+
2
+ # =ModuleLoaders
3
+ # A ModuleLoader loads items from a single module.
4
+ # The ModuleLoaders (ruby) module contains various such loaders. There is currently one concrete
5
+ # implementation, ModuleLoaders::FileBased that loads content from the file system.
6
+ # Other implementations can be created - if they are based on name to path mapping where the path
7
+ # is relative to a root path, they can derive the base behavior from the ModuleLoaders::AbstractPathBasedModuleLoader class.
8
+ #
9
+ # Examples of such extensions could be a zip/jar/compressed file base loader.
10
+ #
11
+ # Notably, a ModuleLoader does not configure itself - it is given the information it needs (the root, its name etc.)
12
+ # Logic higher up in the loader hierarchy of things makes decisions based on the "shape of modules", and "available
13
+ # modules" to determine which module loader to use for each individual module. (There could be differences in
14
+ # internal layout etc.)
15
+ #
16
+ # A module loader is also not aware of the mapping of name to relative paths - this is performed by the
17
+ # included module Puppet::Pops::Loader::PathBasedInstantatorConfig which knows about the map from type/name to
18
+ # relative path, and the logic that can instantiate what is expected to be found in the content of that path.
19
+ #
20
+ # @api private
21
+ #
22
+ module Puppet::Pops::Loader::ModuleLoaders
23
+ class AbstractPathBasedModuleLoader < Puppet::Pops::Loader::BaseLoader
24
+
25
+ # The name of the module, or nil, if this is a global "component"
26
+ attr_reader :module_name
27
+
28
+ # The path to the location of the module/component - semantics determined by subclass
29
+ attr_reader :path
30
+
31
+ # A map of type to smart-paths that help with minimizing the number of paths to scan
32
+ attr_reader :smart_paths
33
+
34
+ # A Module Loader has a private loader, it is lazily obtained on request to provide the visibility
35
+ # for entities contained in the module. Since a ModuleLoader also represents an environment and it is
36
+ # created a different way, this loader can be set explicitly by the loaders bootstrap logic.
37
+ #
38
+ # @api private
39
+ attr_accessor :private_loader
40
+
41
+ # Initialize a kind of ModuleLoader for one module
42
+ # @param parent_loader [Puppet::Pops::Loader] loader with higher priority
43
+ # @param module_name [String] the name of the module (non qualified name), may be nil for a global "component"
44
+ # @param path [String] the path to the root of the module (semantics defined by subclass)
45
+ # @param loader_name [String] a name that is used for human identification (useful when module_name is nil)
46
+ #
47
+ def initialize(parent_loader, loaders, module_name, path, loader_name)
48
+ super parent_loader, loader_name
49
+
50
+ # Irrespective of the path referencing a directory or file, the path must exist.
51
+ unless Puppet::FileSystem.exist?(path)
52
+ raise ArgumentError, "The given path '#{path}' does not exist!"
53
+ end
54
+
55
+ @module_name = module_name
56
+ @path = path
57
+ @smart_paths = Puppet::Pops::Loader::LoaderPaths::SmartPaths.new(self)
58
+ @loaders = loaders
59
+ end
60
+
61
+ # Finds typed/named entity in this module
62
+ # @param typed_name [Puppet::Pops::Loader::TypedName] the type/name to find
63
+ # @return [Puppet::Pops::Loader::Loader::NamedEntry, nil found/created entry, or nil if not found
64
+ #
65
+ def find(typed_name)
66
+ # Assume it is a global name, and that all parts of the name should be used when looking up
67
+ name_part_index = 0
68
+ name_parts = typed_name.name_parts
69
+
70
+ # Certain types and names can be disqualified up front
71
+ if name_parts.size > 1
72
+ # The name is in a name space.
73
+
74
+ # Then entity cannot possible be in this module unless the name starts with the module name.
75
+ # Note: If "module" represents a "global component", the module_name is nil and cannot match which is
76
+ # ok since such a "module" cannot have namespaced content).
77
+ #
78
+ return nil unless name_parts[0] == module_name
79
+
80
+ # Skip the first part of the name when computing the path since the path already contains the name of the
81
+ # module
82
+ name_part_index = 1
83
+ else
84
+ # The name is in the global name space.
85
+
86
+ # The only globally name-spaced elements that may be loaded from modules are functions and resource types
87
+ case typed_name.type
88
+ when :function
89
+ when :resource_type
90
+ else
91
+ # anything else cannot possibly be in this module
92
+ # TODO: should not be allowed anyway... may have to revisit this decision
93
+ return nil
94
+ end
95
+ end
96
+
97
+ # Get the paths that actually exist in this module (they are lazily processed once and cached).
98
+ # The result is an array (that may be empty).
99
+ # Find the file to instantiate, and instantiate the entity if file is found
100
+ origin = nil
101
+ if (smart_path = smart_paths.effective_paths(typed_name.type).find do |sp|
102
+ origin = sp.effective_path(typed_name, name_part_index)
103
+ existing_path(origin)
104
+ end)
105
+ value = smart_path.instantiator.create(self, typed_name, origin, get_contents(origin))
106
+ # cache the entry and return it
107
+ set_entry(typed_name, value, origin)
108
+ else
109
+ nil
110
+ end
111
+ end
112
+
113
+ # Abstract method that subclasses override that checks if it is meaningful to search using a generic smart path.
114
+ # This optimization is performed to not be tricked into searching an empty directory over and over again.
115
+ # The implementation may perform a deep search for file content other than directories and cache this in
116
+ # and index. It is guaranteed that a call to meaningful_to_search? takes place before checking any other
117
+ # path with relative_path_exists?.
118
+ #
119
+ # This optimization exists because many modules have been created from a template and they have
120
+ # empty directories for functions, types, etc. (It is also the place to create a cached index of the content).
121
+ #
122
+ # @param smart_path [String] a path relative to the module's root
123
+ # @return [Boolean] true if there is content in the directory appointed by the relative path
124
+ #
125
+ def meaningful_to_search?(smart_path)
126
+ raise NotImplementedError.new
127
+ end
128
+
129
+ # Abstract method that subclasses override to answer if the given relative path exists, and if so returns that path
130
+ #
131
+ # @param resolved_path [String] a path resolved by a smart path against the loader's root (if it has one)
132
+ # @return [Boolean] true if the file exists
133
+ #
134
+ def existing_path(resolved_path)
135
+ raise NotImplementedError.new
136
+ end
137
+
138
+ # Abstract method that subclasses override to produce the content of the effective path.
139
+ # It should either succeed and return a String or fail with an exception.
140
+ #
141
+ # @param effective_path [String] a path as resolved by a smart path
142
+ # @return [String] the content of the file
143
+ #
144
+ def get_contents(effective_path)
145
+ raise NotImplementedError.new
146
+ end
147
+
148
+ # Abstract method that subclasses override to produce a source reference String used to identify the
149
+ # system resource (resource in the URI sense).
150
+ #
151
+ # @param relative_path [String] a path relative to the module's root
152
+ # @return [String] a reference to the source file (in file system, zip file, or elsewhere).
153
+ #
154
+ def get_source_ref(relative_path)
155
+ raise NotImplementedError.new
156
+ end
157
+
158
+ # Produces the private loader for the module. If this module is not already resolved, this will trigger resolution
159
+ #
160
+ def private_loader
161
+ @private_loader ||= @loaders.private_loader_for_module(module_name)
162
+ end
163
+ end
164
+
165
+ # @api private
166
+ #
167
+ class FileBased < AbstractPathBasedModuleLoader
168
+
169
+ attr_reader :smart_paths
170
+ attr_reader :path_index
171
+
172
+ # Create a kind of ModuleLoader for one module (Puppet Module, or module like)
173
+ #
174
+ # @param parent_loader [Puppet::Pops::Loader::Loader] typically the loader for the environment or root
175
+ # @param module_name [String] the name of the module (non qualified name), may be nil for "modules" only containing globals
176
+ # @param path [String] the path to the root of the module (semantics defined by subclass)
177
+ # @param loader_name [String] a name that identifies the loader
178
+ #
179
+ def initialize(parent_loader, loaders, module_name, path, loader_name)
180
+ super
181
+ unless Puppet::FileSystem.directory?(path)
182
+ raise ArgumentError, "The given module root path '#{path}' is not a directory (required for file system based module path entry)"
183
+ end
184
+ @path_index = Set.new()
185
+ end
186
+
187
+ def existing_path(effective_path)
188
+ # Optimized, checks index instead of visiting file system
189
+ @path_index.include?(effective_path) ? effective_path : nil
190
+ end
191
+
192
+ def meaningful_to_search?(smart_path)
193
+ ! add_to_index(smart_path).empty?
194
+ end
195
+
196
+ def to_s()
197
+ "(ModuleLoader::FileBased '#{loader_name()}' '#{module_name()}')"
198
+ end
199
+
200
+ def add_to_index(smart_path)
201
+ found = Dir.glob(File.join(smart_path.generic_path, '**', "*#{smart_path.extension}"))
202
+ @path_index.merge(found)
203
+ found
204
+ end
205
+
206
+ def get_contents(effective_path)
207
+ Puppet::FileSystem.read(effective_path)
208
+ end
209
+ end
210
+
211
+ # Loads from a gem specified as a URI, gem://gemname/optional/path/in/gem, or just a String gemname.
212
+ # The source reference (shown in errors etc.) is the expanded path of the gem as this is believed to be more
213
+ # helpful - given the location it should be quite obvious which gem it is, without the location, the user would
214
+ # need to go on a hunt for where the file actually is located.
215
+ #
216
+ # TODO: How does this get instantiated? Does the gemname refelect the name of the module (the namespace)
217
+ # or is that specified a different way? Can a gem be the container of multiple modules?
218
+ #
219
+ # @api private
220
+ #
221
+ class GemBased < FileBased
222
+ include Puppet::Pops::Loader::GemSupport
223
+
224
+ attr_reader :gem_ref
225
+
226
+ # Create a kind of ModuleLoader for one module
227
+ # The parameters are:
228
+ # * parent_loader - typically the loader for the root
229
+ # * module_name - the name of the module (non qualified name)
230
+ # * gem_ref - [URI, String] gem reference to the root of the module (URI, gem://gemname/optional/path/in/gem), or
231
+ # just the gem's name as a String.
232
+ #
233
+ def initialize(parent_loader, loaders, module_name, gem_ref, loader_name)
234
+ @gem_ref = gem_ref
235
+ super parent_loader, loaders, module_name, gem_dir(gem_ref), loader_name
236
+ end
237
+
238
+ def to_s()
239
+ "(ModuleLoader::GemBased '#{loader_name()}' '#{@gem_ref}' [#{module_name()}])"
240
+ end
241
+ end
242
+ end