puppet 3.1.1 → 3.2.0.rc1

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 (477) hide show
  1. data/CONTRIBUTING.md +2 -2
  2. data/Gemfile +32 -19
  3. data/README_DEVELOPER.md +332 -14
  4. data/Rakefile +9 -5
  5. data/ext/build_defaults.yaml +2 -3
  6. data/ext/debian/changelog.erb +6 -0
  7. data/ext/debian/control +6 -6
  8. data/ext/envpuppet +4 -4
  9. data/ext/project_data.yaml +1 -0
  10. data/ext/puppet-nm-dispatcher +13 -0
  11. data/ext/redhat/puppet.spec.erb +17 -0
  12. data/ext/suse/client.init +1 -1
  13. data/ext/systemd/puppetagent.service +2 -2
  14. data/ext/systemd/puppetmaster.service +2 -2
  15. data/lib/hiera/scope.rb +29 -11
  16. data/lib/hiera_puppet.rb +1 -3
  17. data/lib/puppet/agent.rb +3 -3
  18. data/lib/puppet/application.rb +2 -2
  19. data/lib/puppet/application/agent.rb +27 -12
  20. data/lib/puppet/application/apply.rb +11 -1
  21. data/lib/puppet/application/describe.rb +1 -1
  22. data/lib/puppet/application/doc.rb +13 -9
  23. data/lib/puppet/application/filebucket.rb +0 -1
  24. data/lib/puppet/application/kick.rb +1 -0
  25. data/lib/puppet/application/master.rb +16 -8
  26. data/lib/puppet/daemon.rb +19 -64
  27. data/lib/puppet/defaults.rb +61 -5
  28. data/lib/puppet/error.rb +15 -4
  29. data/lib/puppet/external/nagios/grammar.ry +1 -1
  30. data/lib/puppet/external/nagios/makefile +1 -1
  31. data/lib/puppet/external/nagios/parser.rb +185 -618
  32. data/lib/puppet/external/pson/pure/parser.rb +47 -1
  33. data/lib/puppet/face/certificate.rb +3 -3
  34. data/lib/puppet/face/module.rb +1 -1
  35. data/lib/puppet/face/module/changes.rb +3 -1
  36. data/lib/puppet/face/module/uninstall.rb +1 -1
  37. data/lib/puppet/face/node/clean.rb +5 -5
  38. data/lib/puppet/feature/base.rb +3 -1
  39. data/lib/puppet/feature/libuser.rb +8 -0
  40. data/lib/puppet/file_serving/fileset.rb +9 -1
  41. data/lib/puppet/forge.rb +28 -5
  42. data/lib/puppet/forge/errors.rb +34 -0
  43. data/lib/puppet/forge/repository.rb +1 -1
  44. data/lib/puppet/indirector.rb +4 -1
  45. data/lib/puppet/indirector/catalog/compiler.rb +37 -30
  46. data/lib/puppet/indirector/facts/inventory_active_record.rb +1 -0
  47. data/lib/puppet/indirector/indirection.rb +28 -15
  48. data/lib/puppet/indirector/rest.rb +18 -10
  49. data/lib/puppet/interface.rb +11 -4
  50. data/lib/puppet/interface/action.rb +1 -3
  51. data/lib/puppet/interface/action_builder.rb +0 -3
  52. data/lib/puppet/interface/action_manager.rb +0 -3
  53. data/lib/puppet/interface/face_collection.rb +0 -2
  54. data/lib/puppet/interface/option.rb +0 -2
  55. data/lib/puppet/interface/option_builder.rb +0 -2
  56. data/lib/puppet/interface/option_manager.rb +0 -2
  57. data/lib/puppet/metatype/manager.rb +1 -1
  58. data/lib/puppet/module_tool.rb +1 -0
  59. data/lib/puppet/module_tool/applications/application.rb +0 -3
  60. data/lib/puppet/module_tool/applications/builder.rb +8 -20
  61. data/lib/puppet/module_tool/applications/checksummer.rb +1 -1
  62. data/lib/puppet/module_tool/applications/installer.rb +1 -0
  63. data/lib/puppet/module_tool/applications/unpacker.rb +3 -11
  64. data/lib/puppet/module_tool/checksums.rb +1 -1
  65. data/lib/puppet/module_tool/errors/installer.rb +18 -1
  66. data/lib/puppet/module_tool/modulefile.rb +2 -2
  67. data/lib/puppet/module_tool/skeleton/templates/generator/Modulefile.erb +1 -1
  68. data/lib/puppet/module_tool/tar.rb +17 -0
  69. data/lib/puppet/module_tool/tar/gnu.rb +9 -0
  70. data/lib/puppet/module_tool/tar/mini.rb +39 -0
  71. data/lib/puppet/module_tool/tar/solaris.rb +5 -0
  72. data/lib/puppet/network/http.rb +1 -0
  73. data/lib/puppet/network/http/connection.rb +9 -23
  74. data/lib/puppet/network/http/handler.rb +38 -7
  75. data/lib/puppet/network/http/rack/rest.rb +14 -3
  76. data/lib/puppet/network/http/webrick.rb +3 -1
  77. data/lib/puppet/network/http/webrick/rest.rb +11 -2
  78. data/lib/puppet/node/environment.rb +3 -1
  79. data/lib/puppet/parameter.rb +32 -29
  80. data/lib/puppet/parameter/package_options.rb +1 -1
  81. data/lib/puppet/parameter/path.rb +1 -1
  82. data/lib/puppet/parameter/value.rb +1 -1
  83. data/lib/puppet/parameter/value_collection.rb +7 -3
  84. data/lib/puppet/parser/ast.rb +3 -1
  85. data/lib/puppet/parser/ast/arithmetic_operator.rb +56 -12
  86. data/lib/puppet/parser/ast/astarray.rb +1 -1
  87. data/lib/puppet/parser/ast/block_expression.rb +41 -0
  88. data/lib/puppet/parser/ast/function.rb +13 -2
  89. data/lib/puppet/parser/ast/lambda.rb +107 -0
  90. data/lib/puppet/parser/ast/leaf.rb +1 -2
  91. data/lib/puppet/parser/ast/method_call.rb +77 -0
  92. data/lib/puppet/parser/ast/vardef.rb +7 -0
  93. data/lib/puppet/parser/compiler.rb +27 -16
  94. data/lib/puppet/parser/e_parser_adapter.rb +120 -0
  95. data/lib/puppet/parser/files.rb +7 -6
  96. data/lib/puppet/parser/functions.rb +10 -8
  97. data/lib/puppet/parser/functions/collect.rb +43 -0
  98. data/lib/puppet/parser/functions/each.rb +96 -0
  99. data/lib/puppet/parser/functions/foreach.rb +96 -0
  100. data/lib/puppet/parser/functions/fqdn_rand.rb +2 -2
  101. data/lib/puppet/parser/functions/hiera.rb +20 -2
  102. data/lib/puppet/parser/functions/hiera_array.rb +21 -2
  103. data/lib/puppet/parser/functions/hiera_hash.rb +23 -2
  104. data/lib/puppet/parser/functions/hiera_include.rb +33 -2
  105. data/lib/puppet/parser/functions/inline_template.rb +4 -4
  106. data/lib/puppet/parser/functions/reduce.rb +74 -0
  107. data/lib/puppet/parser/functions/reject.rb +46 -0
  108. data/lib/puppet/parser/functions/select.rb +46 -0
  109. data/lib/puppet/parser/functions/slice.rb +96 -0
  110. data/lib/puppet/parser/functions/template.rb +2 -2
  111. data/lib/puppet/parser/grammar.ra +7 -4
  112. data/lib/puppet/parser/lexer.rb +10 -0
  113. data/lib/puppet/parser/methods.rb +69 -0
  114. data/lib/puppet/parser/parser.rb +855 -808
  115. data/lib/puppet/parser/parser_factory.rb +62 -0
  116. data/lib/puppet/parser/parser_support.rb +8 -2
  117. data/lib/puppet/parser/scope.rb +153 -47
  118. data/lib/puppet/parser/templatewrapper.rb +28 -21
  119. data/lib/puppet/parser/type_loader.rb +3 -1
  120. data/lib/puppet/pops.rb +40 -0
  121. data/lib/puppet/pops/adaptable.rb +190 -0
  122. data/lib/puppet/pops/adapters.rb +65 -0
  123. data/lib/puppet/pops/containment.rb +37 -0
  124. data/lib/puppet/pops/issues.rb +258 -0
  125. data/lib/puppet/pops/label_provider.rb +71 -0
  126. data/lib/puppet/pops/model/ast_transformer.rb +636 -0
  127. data/lib/puppet/pops/model/ast_tree_dumper.rb +378 -0
  128. data/lib/puppet/pops/model/factory.rb +804 -0
  129. data/lib/puppet/pops/model/model.rb +567 -0
  130. data/lib/puppet/pops/model/model_label_provider.rb +75 -0
  131. data/lib/puppet/pops/model/model_tree_dumper.rb +352 -0
  132. data/lib/puppet/pops/model/tree_dumper.rb +59 -0
  133. data/lib/puppet/pops/parser/egrammar.ra +723 -0
  134. data/lib/puppet/pops/parser/eparser.rb +2300 -0
  135. data/lib/puppet/pops/parser/grammar.ra +746 -0
  136. data/lib/puppet/pops/parser/lexer.rb +842 -0
  137. data/lib/puppet/pops/parser/makefile +13 -0
  138. data/lib/puppet/pops/parser/parser_support.rb +203 -0
  139. data/lib/puppet/pops/patterns.rb +35 -0
  140. data/lib/puppet/pops/utils.rb +104 -0
  141. data/lib/puppet/pops/validation.rb +297 -0
  142. data/lib/puppet/pops/validation/checker3_1.rb +551 -0
  143. data/lib/puppet/pops/validation/validator_factory_3_1.rb +41 -0
  144. data/lib/puppet/pops/visitable.rb +6 -0
  145. data/lib/puppet/pops/visitor.rb +50 -0
  146. data/lib/puppet/property.rb +37 -28
  147. data/lib/puppet/property/ensure.rb +2 -2
  148. data/lib/puppet/property/ordered_list.rb +1 -1
  149. data/lib/puppet/provider.rb +26 -30
  150. data/lib/puppet/provider/aixobject.rb +45 -44
  151. data/lib/puppet/provider/augeas/augeas.rb +0 -1
  152. data/lib/puppet/provider/confiner.rb +1 -1
  153. data/lib/puppet/provider/cron/crontab.rb +107 -67
  154. data/lib/puppet/provider/group/groupadd.rb +59 -3
  155. data/lib/puppet/provider/interface/cisco.rb +4 -4
  156. data/lib/puppet/provider/mount/parsed.rb +1 -1
  157. data/lib/puppet/provider/nameservice.rb +22 -6
  158. data/lib/puppet/provider/nameservice/pw.rb +1 -1
  159. data/lib/puppet/provider/package/aix.rb +28 -4
  160. data/lib/puppet/provider/package/gem.rb +0 -2
  161. data/lib/puppet/provider/package/macports.rb +1 -1
  162. data/lib/puppet/provider/package/nim.rb +249 -4
  163. data/lib/puppet/provider/package/opkg.rb +77 -0
  164. data/lib/puppet/provider/package/pacman.rb +2 -2
  165. data/lib/puppet/provider/package/rpm.rb +30 -16
  166. data/lib/puppet/provider/package/yum.rb +3 -3
  167. data/lib/puppet/provider/parsedfile.rb +80 -3
  168. data/lib/puppet/provider/selmodule/semodule.rb +2 -2
  169. data/lib/puppet/provider/service/debian.rb +0 -4
  170. data/lib/puppet/provider/service/freebsd.rb +2 -2
  171. data/lib/puppet/provider/service/gentoo.rb +0 -9
  172. data/lib/puppet/provider/service/init.rb +27 -2
  173. data/lib/puppet/provider/service/launchd.rb +1 -1
  174. data/lib/puppet/provider/service/openwrt.rb +36 -0
  175. data/lib/puppet/provider/service/redhat.rb +0 -9
  176. data/lib/puppet/provider/service/src.rb +38 -4
  177. data/lib/puppet/provider/service/systemd.rb +2 -2
  178. data/lib/puppet/provider/service/upstart.rb +1 -8
  179. data/lib/puppet/provider/user/aix.rb +4 -10
  180. data/lib/puppet/provider/user/pw.rb +6 -10
  181. data/lib/puppet/provider/user/useradd.rb +129 -31
  182. data/lib/puppet/provider/vlan/cisco.rb +4 -4
  183. data/lib/puppet/reference/function.rb +2 -2
  184. data/lib/puppet/reference/indirection.rb +46 -5
  185. data/lib/puppet/reference/metaparameter.rb +2 -2
  186. data/lib/puppet/reports.rb +5 -5
  187. data/lib/puppet/reports/rrdgraph.rb +4 -4
  188. data/lib/puppet/reports/tagmail.rb +1 -1
  189. data/lib/puppet/resource.rb +1 -1
  190. data/lib/puppet/resource/type.rb +13 -11
  191. data/lib/puppet/scheduler.rb +16 -0
  192. data/lib/puppet/scheduler/job.rb +53 -0
  193. data/lib/puppet/scheduler/scheduler.rb +45 -0
  194. data/lib/puppet/scheduler/splay_job.rb +32 -0
  195. data/lib/puppet/scheduler/timer.rb +13 -0
  196. data/lib/puppet/settings/base_setting.rb +1 -1
  197. data/lib/puppet/simple_graph.rb +4 -4
  198. data/lib/puppet/ssl/base.rb +12 -2
  199. data/lib/puppet/ssl/certificate.rb +4 -1
  200. data/lib/puppet/ssl/certificate_request.rb +4 -1
  201. data/lib/puppet/ssl/certificate_revocation_list.rb +4 -1
  202. data/lib/puppet/ssl/configuration.rb +32 -0
  203. data/lib/puppet/ssl/host.rb +18 -21
  204. data/lib/puppet/ssl/key.rb +4 -1
  205. data/lib/puppet/ssl/validator.rb +116 -0
  206. data/lib/puppet/transaction.rb +1 -1
  207. data/lib/puppet/transaction/event.rb +3 -10
  208. data/lib/puppet/transaction/event_manager.rb +8 -1
  209. data/lib/puppet/transaction/report.rb +17 -16
  210. data/lib/puppet/type.rb +77 -69
  211. data/lib/puppet/type/cron.rb +20 -8
  212. data/lib/puppet/type/exec.rb +9 -3
  213. data/lib/puppet/type/file.rb +95 -21
  214. data/lib/puppet/type/file/content.rb +1 -1
  215. data/lib/puppet/type/file/mode.rb +7 -1
  216. data/lib/puppet/type/file/source.rb +2 -2
  217. data/lib/puppet/type/group.rb +11 -0
  218. data/lib/puppet/type/scheduled_task.rb +5 -1
  219. data/lib/puppet/type/service.rb +1 -1
  220. data/lib/puppet/type/ssh_authorized_key.rb +2 -2
  221. data/lib/puppet/type/user.rb +24 -6
  222. data/lib/puppet/util.rb +12 -2
  223. data/lib/puppet/util/classgen.rb +4 -4
  224. data/lib/puppet/util/colors.rb +55 -0
  225. data/lib/puppet/util/command_line/trollop.rb +4 -4
  226. data/lib/puppet/util/errors.rb +39 -3
  227. data/lib/puppet/util/fileparsing.rb +5 -0
  228. data/lib/puppet/util/filetype.rb +11 -9
  229. data/lib/puppet/util/instrumentation/instrumentable.rb +2 -2
  230. data/lib/puppet/util/libuser.conf +15 -0
  231. data/lib/puppet/util/libuser.rb +12 -0
  232. data/lib/puppet/util/monkey_patches.rb +48 -0
  233. data/lib/puppet/util/network_device.rb +1 -1
  234. data/lib/puppet/util/network_device/base.rb +2 -2
  235. data/lib/puppet/util/network_device/cisco/device.rb +29 -19
  236. data/lib/puppet/util/network_device/config.rb +5 -2
  237. data/lib/puppet/util/network_device/ipcalc.rb +1 -1
  238. data/lib/puppet/util/network_device/transport/ssh.rb +4 -3
  239. data/lib/puppet/util/network_device/transport/telnet.rb +4 -2
  240. data/lib/puppet/util/plugins.rb +4 -4
  241. data/lib/puppet/util/posix.rb +1 -1
  242. data/lib/puppet/util/profiler.rb +28 -0
  243. data/lib/puppet/util/profiler/logging.rb +47 -0
  244. data/lib/puppet/util/profiler/none.rb +8 -0
  245. data/lib/puppet/util/profiler/object_counts.rb +17 -0
  246. data/lib/puppet/util/profiler/wall_clock.rb +34 -0
  247. data/lib/puppet/util/provider_features.rb +1 -1
  248. data/lib/puppet/util/rdoc/parser.rb +5 -5
  249. data/lib/puppet/util/ssl.rb +38 -0
  250. data/lib/puppet/util/subclass_loader.rb +1 -5
  251. data/lib/puppet/util/windows.rb +1 -0
  252. data/lib/puppet/util/windows/process.rb +3 -0
  253. data/lib/puppet/util/windows/root_certs.rb +86 -0
  254. data/lib/puppet/util/windows/security.rb +1 -0
  255. data/lib/puppet/version.rb +1 -1
  256. data/spec/fixtures/integration/provider/cron/crontab/create_normal_entry +19 -0
  257. data/spec/fixtures/integration/provider/cron/crontab/create_special_entry +18 -0
  258. data/spec/fixtures/integration/provider/cron/crontab/crontab_user1 +15 -0
  259. data/spec/fixtures/integration/provider/cron/crontab/crontab_user2 +4 -0
  260. data/spec/fixtures/integration/provider/cron/crontab/modify_entry +13 -0
  261. data/spec/fixtures/integration/provider/cron/crontab/moved_cronjob_input1 +15 -0
  262. data/spec/fixtures/integration/provider/cron/crontab/moved_cronjob_input2 +6 -0
  263. data/spec/fixtures/integration/provider/cron/crontab/remove_named_resource +12 -0
  264. data/spec/fixtures/integration/provider/cron/crontab/remove_unnamed_resource +14 -0
  265. data/spec/fixtures/unit/pops/parser/lexer/aliastest.pp +16 -0
  266. data/spec/fixtures/unit/pops/parser/lexer/append.pp +11 -0
  267. data/spec/fixtures/unit/pops/parser/lexer/argumentdefaults.pp +14 -0
  268. data/spec/fixtures/unit/pops/parser/lexer/arithmetic_expression.pp +8 -0
  269. data/spec/fixtures/unit/pops/parser/lexer/arraytrailingcomma.pp +3 -0
  270. data/spec/fixtures/unit/pops/parser/lexer/casestatement.pp +65 -0
  271. data/spec/fixtures/unit/pops/parser/lexer/classheirarchy.pp +15 -0
  272. data/spec/fixtures/unit/pops/parser/lexer/classincludes.pp +17 -0
  273. data/spec/fixtures/unit/pops/parser/lexer/classpathtest.pp +11 -0
  274. data/spec/fixtures/unit/pops/parser/lexer/collection.pp +10 -0
  275. data/spec/fixtures/unit/pops/parser/lexer/collection_override.pp +8 -0
  276. data/spec/fixtures/unit/pops/parser/lexer/collection_within_virtual_definitions.pp +20 -0
  277. data/spec/fixtures/unit/pops/parser/lexer/componentmetaparams.pp +11 -0
  278. data/spec/fixtures/unit/pops/parser/lexer/componentrequire.pp +8 -0
  279. data/spec/fixtures/unit/pops/parser/lexer/deepclassheirarchy.pp +23 -0
  280. data/spec/fixtures/unit/pops/parser/lexer/defineoverrides.pp +17 -0
  281. data/spec/fixtures/unit/pops/parser/lexer/emptyclass.pp +9 -0
  282. data/spec/fixtures/unit/pops/parser/lexer/emptyexec.pp +3 -0
  283. data/spec/fixtures/unit/pops/parser/lexer/emptyifelse.pp +9 -0
  284. data/spec/fixtures/unit/pops/parser/lexer/falsevalues.pp +3 -0
  285. data/spec/fixtures/unit/pops/parser/lexer/filecreate.pp +11 -0
  286. data/spec/fixtures/unit/pops/parser/lexer/fqdefinition.pp +5 -0
  287. data/spec/fixtures/unit/pops/parser/lexer/fqparents.pp +11 -0
  288. data/spec/fixtures/unit/pops/parser/lexer/funccomma.pp +5 -0
  289. data/spec/fixtures/unit/pops/parser/lexer/hash.pp +33 -0
  290. data/spec/fixtures/unit/pops/parser/lexer/ifexpression.pp +12 -0
  291. data/spec/fixtures/unit/pops/parser/lexer/implicititeration.pp +15 -0
  292. data/spec/fixtures/unit/pops/parser/lexer/multilinecomments.pp +10 -0
  293. data/spec/fixtures/unit/pops/parser/lexer/multipleclass.pp +9 -0
  294. data/spec/fixtures/unit/pops/parser/lexer/multipleinstances.pp +7 -0
  295. data/spec/fixtures/unit/pops/parser/lexer/multisubs.pp +13 -0
  296. data/spec/fixtures/unit/pops/parser/lexer/namevartest.pp +9 -0
  297. data/spec/fixtures/unit/pops/parser/lexer/scopetest.pp +13 -0
  298. data/spec/fixtures/unit/pops/parser/lexer/selectorvalues.pp +49 -0
  299. data/spec/fixtures/unit/pops/parser/lexer/simpledefaults.pp +5 -0
  300. data/spec/fixtures/unit/pops/parser/lexer/simpleselector.pp +38 -0
  301. data/spec/fixtures/unit/pops/parser/lexer/singleary.pp +19 -0
  302. data/spec/fixtures/unit/pops/parser/lexer/singlequote.pp +11 -0
  303. data/spec/fixtures/unit/pops/parser/lexer/singleselector.pp +22 -0
  304. data/spec/fixtures/unit/pops/parser/lexer/subclass_name_duplication.pp +11 -0
  305. data/spec/fixtures/unit/pops/parser/lexer/tag.pp +9 -0
  306. data/spec/fixtures/unit/pops/parser/lexer/tagged.pp +35 -0
  307. data/spec/fixtures/unit/pops/parser/lexer/virtualresources.pp +14 -0
  308. data/spec/fixtures/unit/provider/cron/crontab/single_line.yaml +4 -4
  309. data/spec/fixtures/unit/provider/cron/crontab/vixie_header.txt +3 -0
  310. data/spec/fixtures/unit/provider/cron/parsed/managed +6 -0
  311. data/spec/fixtures/unit/provider/cron/parsed/simple +9 -0
  312. data/spec/fixtures/unit/provider/parsedfile/simple.txt +4 -0
  313. data/spec/fixtures/unit/provider/service/systemd/list_units +18 -0
  314. data/spec/integration/parser/collector_spec.rb +1 -1
  315. data/spec/integration/parser/compiler_spec.rb +252 -227
  316. data/spec/integration/parser/parser_spec.rb +171 -53
  317. data/spec/integration/parser/scope_spec.rb +1 -1
  318. data/spec/integration/provider/cron/crontab_spec.rb +187 -0
  319. data/spec/integration/provider/service/systemd_spec.rb +20 -0
  320. data/spec/integration/type/file_spec.rb +21 -21
  321. data/spec/integration/type/package_spec.rb +1 -1
  322. data/spec/lib/puppet_spec/database.rb +2 -5
  323. data/spec/spec_helper.rb +6 -1
  324. data/spec/unit/application/apply_spec.rb +16 -1
  325. data/spec/unit/application/describe_spec.rb +1 -1
  326. data/spec/unit/application/doc_spec.rb +55 -32
  327. data/spec/unit/application/kick_spec.rb +8 -6
  328. data/spec/unit/application/master_spec.rb +4 -4
  329. data/spec/unit/daemon_spec.rb +1 -1
  330. data/spec/unit/forge/errors_spec.rb +40 -0
  331. data/spec/unit/forge/repository_spec.rb +11 -1
  332. data/spec/unit/forge_spec.rb +13 -3
  333. data/spec/unit/hiera/backend/puppet_backend_spec.rb +1 -0
  334. data/spec/unit/hiera/scope_spec.rb +48 -25
  335. data/spec/unit/indirector/catalog/active_record_spec.rb +6 -3
  336. data/spec/unit/indirector/catalog/compiler_spec.rb +3 -28
  337. data/spec/unit/indirector/catalog/static_compiler_spec.rb +1 -1
  338. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +154 -150
  339. data/spec/unit/indirector/indirection_spec.rb +5 -0
  340. data/spec/unit/indirector/resource/active_record_spec.rb +5 -22
  341. data/spec/unit/indirector_spec.rb +7 -1
  342. data/spec/unit/interface/action_builder_spec.rb +1 -1
  343. data/spec/unit/interface/action_manager_spec.rb +0 -2
  344. data/spec/unit/interface/action_spec.rb +1 -1
  345. data/spec/unit/interface/documentation_spec.rb +0 -2
  346. data/spec/unit/interface/face_collection_spec.rb +1 -1
  347. data/spec/unit/interface/option_builder_spec.rb +1 -1
  348. data/spec/unit/interface/option_spec.rb +0 -1
  349. data/spec/unit/module_spec.rb +17 -19
  350. data/spec/unit/module_tool/application_spec.rb +1 -3
  351. data/spec/unit/module_tool/applications/builder_spec.rb +38 -0
  352. data/spec/unit/module_tool/applications/checksummer_spec.rb +134 -0
  353. data/spec/unit/module_tool/applications/installer_spec.rb +71 -91
  354. data/spec/unit/module_tool/applications/searcher_spec.rb +1 -3
  355. data/spec/unit/module_tool/applications/uninstaller_spec.rb +18 -26
  356. data/spec/unit/module_tool/applications/unpacker_spec.rb +19 -52
  357. data/spec/unit/module_tool/tar/gnu_spec.rb +19 -0
  358. data/spec/unit/module_tool/tar/mini_spec.rb +59 -0
  359. data/spec/unit/module_tool/tar/solaris_spec.rb +19 -0
  360. data/spec/unit/network/http/connection_spec.rb +17 -2
  361. data/spec/unit/network/http/handler_spec.rb +195 -167
  362. data/spec/unit/network/http/rack/rest_spec.rb +26 -4
  363. data/spec/unit/network/http/webrick/rest_spec.rb +28 -1
  364. data/spec/unit/network/http/webrick_spec.rb +12 -3
  365. data/spec/unit/node/environment_spec.rb +421 -404
  366. data/spec/unit/parser/ast/arithmetic_operator_spec.rb +98 -2
  367. data/spec/unit/parser/collector_spec.rb +4 -4
  368. data/spec/unit/parser/compiler_spec.rb +13 -13
  369. data/spec/unit/parser/eparser_adapter_spec.rb +407 -0
  370. data/spec/unit/parser/functions/extlookup_spec.rb +20 -17
  371. data/spec/unit/parser/functions/fqdn_rand_spec.rb +5 -0
  372. data/spec/unit/parser/functions/hiera_include_spec.rb +0 -2
  373. data/spec/unit/parser/functions/hiera_spec.rb +0 -2
  374. data/spec/unit/parser/functions_spec.rb +27 -15
  375. data/spec/unit/parser/methods/collect_spec.rb +110 -0
  376. data/spec/unit/parser/methods/each_spec.rb +91 -0
  377. data/spec/unit/parser/methods/foreach_spec.rb +91 -0
  378. data/spec/unit/parser/methods/reduce_spec.rb +67 -0
  379. data/spec/unit/parser/methods/reject_spec.rb +73 -0
  380. data/spec/unit/parser/methods/select_spec.rb +79 -0
  381. data/spec/unit/parser/methods/shared.rb +61 -0
  382. data/spec/unit/parser/methods/slice_spec.rb +97 -0
  383. data/spec/unit/parser/parser_spec.rb +2 -2
  384. data/spec/unit/parser/scope_spec.rb +39 -16
  385. data/spec/unit/parser/templatewrapper_spec.rb +6 -5
  386. data/spec/unit/parser/type_loader_spec.rb +191 -165
  387. data/spec/unit/pops/adaptable_spec.rb +143 -0
  388. data/spec/unit/pops/containment_spec.rb +25 -0
  389. data/spec/unit/pops/factory_rspec_helper.rb +77 -0
  390. data/spec/unit/pops/factory_spec.rb +329 -0
  391. data/spec/unit/pops/issues_spec.rb +26 -0
  392. data/spec/unit/pops/label_provider_spec.rb +42 -0
  393. data/spec/unit/pops/model/ast_transformer_spec.rb +65 -0
  394. data/spec/unit/pops/model/model_spec.rb +37 -0
  395. data/spec/unit/pops/parser/lexer_spec.rb +884 -0
  396. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +248 -0
  397. data/spec/unit/pops/parser/parse_calls_spec.rb +93 -0
  398. data/spec/unit/pops/parser/parse_conditionals_spec.rb +159 -0
  399. data/spec/unit/pops/parser/parse_containers_spec.rb +175 -0
  400. data/spec/unit/pops/parser/parse_resource_spec.rb +228 -0
  401. data/spec/unit/pops/parser/parser_rspec_helper.rb +11 -0
  402. data/spec/unit/pops/parser/parser_spec.rb +15 -0
  403. data/spec/unit/pops/parser/rgen_sanitycheck_spec.rb +16 -0
  404. data/spec/unit/pops/transformer/transform_basic_expressions_spec.rb +243 -0
  405. data/spec/unit/pops/transformer/transform_calls_spec.rb +80 -0
  406. data/spec/unit/pops/transformer/transform_conditionals_spec.rb +132 -0
  407. data/spec/unit/pops/transformer/transform_containers_spec.rb +182 -0
  408. data/spec/unit/pops/transformer/transform_resource_spec.rb +185 -0
  409. data/spec/unit/pops/transformer/transformer_rspec_helper.rb +27 -0
  410. data/spec/unit/pops/visitor_spec.rb +94 -0
  411. data/spec/unit/property_spec.rb +11 -0
  412. data/spec/unit/provider/augeas/augeas_spec.rb +3 -0
  413. data/spec/unit/provider/cron/crontab_spec.rb +97 -7
  414. data/spec/unit/provider/cron/parsed_spec.rb +325 -0
  415. data/spec/unit/provider/exec/posix_spec.rb +1 -1
  416. data/spec/unit/provider/group/groupadd_spec.rb +33 -3
  417. data/spec/unit/provider/group/pw_spec.rb +5 -5
  418. data/spec/unit/provider/nameservice_spec.rb +304 -0
  419. data/spec/unit/provider/package/aix_spec.rb +53 -11
  420. data/spec/unit/provider/package/aptrpm_spec.rb +6 -0
  421. data/spec/unit/provider/package/gem_spec.rb +6 -11
  422. data/spec/unit/provider/package/nim_spec.rb +216 -7
  423. data/spec/unit/provider/package/opkg_spec.rb +180 -0
  424. data/spec/unit/provider/package/rpm_spec.rb +149 -3
  425. data/spec/unit/provider/package/yum_spec.rb +6 -5
  426. data/spec/unit/provider/parsedfile_spec.rb +122 -28
  427. data/spec/unit/provider/service/freebsd_spec.rb +18 -0
  428. data/spec/unit/provider/service/init_spec.rb +108 -87
  429. data/spec/unit/provider/service/launchd_spec.rb +2 -2
  430. data/spec/unit/provider/service/openwrt_spec.rb +109 -0
  431. data/spec/unit/provider/service/src_spec.rb +117 -41
  432. data/spec/unit/provider/service/systemd_spec.rb +125 -17
  433. data/spec/unit/provider/service/upstart_spec.rb +1 -1
  434. data/spec/unit/provider/user/aix_spec.rb +42 -0
  435. data/spec/unit/provider/user/directoryservice_spec.rb +1 -0
  436. data/spec/unit/provider/user/pw_spec.rb +24 -12
  437. data/spec/unit/provider/user/user_role_add_spec.rb +1 -1
  438. data/spec/unit/provider/user/useradd_spec.rb +179 -15
  439. data/spec/unit/resource/type_spec.rb +3 -3
  440. data/spec/unit/scheduler/job_spec.rb +79 -0
  441. data/spec/unit/scheduler/scheduler_spec.rb +129 -0
  442. data/spec/unit/scheduler/splay_job_spec.rb +35 -0
  443. data/spec/unit/ssl/base_spec.rb +3 -9
  444. data/spec/unit/ssl/certificate_authority_spec.rb +1 -0
  445. data/spec/unit/ssl/certificate_request_spec.rb +3 -1
  446. data/spec/unit/ssl/certificate_spec.rb +3 -1
  447. data/spec/unit/ssl/configuration_spec.rb +74 -0
  448. data/spec/unit/ssl/host_spec.rb +28 -7
  449. data/spec/unit/ssl/validator_spec.rb +311 -0
  450. data/spec/unit/transaction/event_manager_spec.rb +49 -0
  451. data/spec/unit/transaction/event_spec.rb +20 -5
  452. data/spec/unit/transaction/report_spec.rb +8 -0
  453. data/spec/unit/type/cron_spec.rb +9 -0
  454. data/spec/unit/type/exec_spec.rb +11 -0
  455. data/spec/unit/type/file/content_spec.rb +20 -20
  456. data/spec/unit/type/file/mode_spec.rb +6 -0
  457. data/spec/unit/type/file/source_spec.rb +9 -7
  458. data/spec/unit/type/file_spec.rb +22 -3
  459. data/spec/unit/type/service_spec.rb +34 -21
  460. data/spec/unit/type_spec.rb +46 -1
  461. data/spec/unit/util/backups_spec.rb +2 -2
  462. data/spec/unit/util/execution_spec.rb +4 -1
  463. data/spec/unit/util/filetype_spec.rb +6 -0
  464. data/spec/unit/util/monkey_patches_spec.rb +18 -0
  465. data/spec/unit/util/network_device/cisco/device_spec.rb +37 -0
  466. data/spec/unit/util/network_device/config_spec.rb +14 -0
  467. data/spec/unit/util/network_device_spec.rb +3 -3
  468. data/spec/unit/util/profiler/logging_spec.rb +81 -0
  469. data/spec/unit/util/profiler/none_spec.rb +12 -0
  470. data/spec/unit/util/profiler/object_counts_spec.rb +14 -0
  471. data/spec/unit/util/profiler/wall_clock_spec.rb +13 -0
  472. data/spec/unit/util/pson_spec.rb +5 -0
  473. data/spec/unit/util/ssl_spec.rb +51 -0
  474. data/spec/unit/util/windows/root_certs_spec.rb +15 -0
  475. data/spec/unit/util_spec.rb +28 -0
  476. metadata +2593 -2307
  477. data/spec/unit/module_tool/applications/application_spec.rb +0 -19
@@ -0,0 +1,13 @@
1
+
2
+ #parser.rb: grammar.ra
3
+ # racc -o$@ grammar.ra
4
+ #
5
+ #grammar.output: grammar.ra
6
+ # racc -v -o$@ grammar.ra
7
+ #
8
+
9
+ eparser.rb: egrammar.ra
10
+ racc -o$@ egrammar.ra
11
+
12
+ egrammar.output: egrammar.ra
13
+ racc -v -o$@ egrammar.ra
@@ -0,0 +1,203 @@
1
+ require 'puppet/parser/functions'
2
+ require 'puppet/parser/files'
3
+ require 'puppet/resource/type_collection'
4
+ require 'puppet/resource/type_collection_helper'
5
+ require 'puppet/resource/type'
6
+ require 'monitor'
7
+
8
+ # Supporting logic for the parser.
9
+ # This supporting logic has slightly different responsibilities compared to the original Puppet::Parser::Parser.
10
+ # It is only concerned with parsing.
11
+ #
12
+ class Puppet::Pops::Parser::Parser
13
+ # Note that the name of the contained class and the file name (currently parser_support.rb)
14
+ # needs to be different as the class is generated by Racc, and this file (parser_support.rb) is included as a mix in
15
+ #
16
+
17
+ # Simplify access to the Model factory
18
+ # Note that the parser/parser support does not have direct knowledge about the Model.
19
+ # All model construction/manipulation is made by the Factory.
20
+ #
21
+ Factory = Puppet::Pops::Model::Factory
22
+ Model = Puppet::Pops::Model
23
+
24
+ include Puppet::Resource::TypeCollectionHelper
25
+
26
+ attr_accessor :lexer
27
+
28
+ # Returns the token text of the given lexer token, or nil, if token is nil
29
+ def token_text t
30
+ return t if t.nil?
31
+ t = t.current if t.respond_to?(:current)
32
+ return t.value if t.is_a? Model::QualifiedName
33
+
34
+ # else it is a lexer token
35
+ t[:value]
36
+ end
37
+
38
+ # Produces the fully qualified name, with the full (current) namespace for a given name.
39
+ #
40
+ # This is needed because class bodies are lazily evaluated and an inner class' container(s) may not
41
+ # have been evaluated before some external reference is made to the inner class; its must therefore know its complete name
42
+ # before evaluation-time.
43
+ #
44
+ def classname(name)
45
+ [@lexer.namespace, name].join("::").sub(/^::/, '')
46
+ end
47
+
48
+ # Reinitializes variables (i.e. creates a new lexer instance
49
+ #
50
+ def clear
51
+ initvars
52
+ end
53
+
54
+ # Raises a Parse error.
55
+ def error(message, options = {})
56
+ except = Puppet::ParseError.new(message)
57
+ except.line = options[:line] || @lexer.line
58
+ except.file = options[:file] || @lexer.file
59
+ except.pos = options[:pos] || @lexer.pos
60
+
61
+ raise except
62
+ end
63
+
64
+ # Parses a file expected to contain pp DSL logic.
65
+ def parse_file(file)
66
+ unless FileTest.exist?(file)
67
+ unless file =~ /\.pp$/
68
+ file = file + ".pp"
69
+ end
70
+ end
71
+ @lexer.file = file
72
+ _parse()
73
+ end
74
+
75
+ def initialize()
76
+ # Since the parser is not responsible for importing (removed), and does not perform linking,
77
+ # and there is no syntax that requires knowing if something referenced exists, it is safe
78
+ # to assume that no environment is needed when parsing. (All that comes later).
79
+ #
80
+ initvars
81
+ end
82
+
83
+ # Initializes the parser support by creating a new instance of {Puppet::Pops::Parser::Lexer}
84
+ # @return [void]
85
+ #
86
+ def initvars
87
+ @lexer = Puppet::Pops::Parser::Lexer.new
88
+ end
89
+
90
+ # This is a callback from the generated grammar (when an error occurs while parsing)
91
+ # TODO Picks up origin information from the lexer, probably needs this from the caller instead
92
+ # (for code strings, and when start line is not line 1 in a code string (or file), etc.)
93
+ #
94
+ def on_error(token,value,stack)
95
+ if token == 0 # denotes end of file
96
+ value = 'end of file'
97
+ else
98
+ value = "'#{value[:value]}'"
99
+ end
100
+ error = "Syntax error at #{value}"
101
+
102
+ # The 'expected' is only of value at end of input, otherwise any parse error involving a
103
+ # start of a pair will be reported as expecting the close of the pair - e.g. "$x.each |$x {", would
104
+ # report that "seeing the '{', the '}' is expected. That would be wrong.
105
+ # Real "expected" tokens are very difficult to compute (would require parsing of racc output data). Output of the stack
106
+ # could help, but can require extensive backtracking and produce many options.
107
+ #
108
+ if token == 0 && brace = @lexer.expected
109
+ error += "; expected '#{brace}'"
110
+ end
111
+
112
+ except = Puppet::ParseError.new(error)
113
+ except.line = @lexer.line
114
+ except.file = @lexer.file if @lexer.file
115
+ except.pos = @lexer.pos
116
+
117
+ raise except
118
+ end
119
+
120
+ # Parses a String of pp DSL code.
121
+ # @todo make it possible to pass a given origin
122
+ #
123
+ def parse_string(code)
124
+ @lexer.string = code
125
+ _parse()
126
+ end
127
+
128
+ # Mark the factory wrapped model object with location information
129
+ # @todo the lexer produces :line for token, but no offset or length
130
+ # @return [Puppet::Pops::Model::Factory] the given factory
131
+ # @api private
132
+ #
133
+ def loc(factory, start_token, end_token = nil)
134
+ factory.record_position(sourcepos(start_token), sourcepos(end_token))
135
+ end
136
+
137
+ # Associate documentation with the factory wrapped model object.
138
+ # @return [Puppet::Pops::Model::Factory] the given factory
139
+ # @api private
140
+ def doc factory, doc_string
141
+ factory.doc = doc_string
142
+ end
143
+
144
+ def sourcepos(o)
145
+ if !o
146
+ Puppet::Pops::Adapters::SourcePosAdapter.new
147
+ elsif o.is_a? Puppet::Pops::Model::Factory
148
+ # It is a built model element with loc set returns start at pos 0
149
+ o.loc
150
+ else
151
+ loc = Puppet::Pops::Adapters::SourcePosAdapter.new
152
+ # It must be a token
153
+ loc.line = o[:line]
154
+ loc.pos = o[:pos]
155
+ loc.offset = o[:offset]
156
+ loc.length = o[:length]
157
+ loc
158
+ end
159
+ end
160
+
161
+ def aryfy(o)
162
+ o = [o] unless o.is_a?(Array)
163
+ o
164
+ end
165
+
166
+ # Transforms an array of expressions containing literal name expressions to calls if followed by an
167
+ # expression, or expression list
168
+ #
169
+ def transform_calls(expressions)
170
+ Factory.transform_calls(expressions)
171
+ end
172
+
173
+ # Performs the parsing and returns the resulting model.
174
+ # The lexer holds state, and this is setup with {#parse_string}, or {#parse_file}.
175
+ #
176
+ # TODO: Drop support for parsing a ruby file this way (should be done where it is decided
177
+ # which file to load/run (i.e. loaders), and initial file to run
178
+ # TODO: deal with options containing origin (i.e. parsing a string from externally known location).
179
+ # TODO: should return the model, not a Hostclass
180
+ #
181
+ # @api private
182
+ #
183
+ def _parse()
184
+ begin
185
+ @yydebug = false
186
+ main = yyparse(@lexer,:scan)
187
+ # #Commented out now because this hides problems in the racc grammar while developing
188
+ # # TODO include this when test coverage is good enough.
189
+ # rescue Puppet::ParseError => except
190
+ # except.line ||= @lexer.line
191
+ # except.file ||= @lexer.file
192
+ # except.pos ||= @lexer.pos
193
+ # raise except
194
+ # rescue => except
195
+ # raise Puppet::ParseError.new(except.message, @lexer.file, @lexer.line, @lexer.pos, except)
196
+ end
197
+ main.record_origin(@lexer.file) if main
198
+ return main
199
+ ensure
200
+ @lexer.clear
201
+ end
202
+
203
+ end
@@ -0,0 +1,35 @@
1
+ # The Patterns module contains common regular expression patters for the Puppet DSL language
2
+ module Puppet::Pops::Patterns
3
+
4
+ # NUMERIC matches hex, octal, decimal, and floating point and captures three parts
5
+ # 0 = entire matched number, leading and trailing whitespace included
6
+ # 1 = hexadecimal number
7
+ # 2 = non hex integer portion, possibly with leading 0 (octal)
8
+ # 3 = floating point part, starts with ".", decimals and optional exponent
9
+ #
10
+ # Thus, a hex number has group 1 value, an octal value has group 2 (if it starts with 0), and no group 3
11
+ # and a floating point value has group 2 and group 3.
12
+ #
13
+ NUMERIC = %r{^\s*(?:(0[xX][0-9A-Fa-f]+)|(0?\d+)((?:\.\d+)?(?:[eE]-?\d+)?))\s*$}
14
+
15
+ # ILLEGAL_P3_1_HOSTNAME matches if a hostname contains illegal characters.
16
+ # This check does not prevent pathological names like 'a....b', '.....', "---". etc.
17
+ ILLEGAL_HOSTNAME_CHARS = %r{[^-\w.]}
18
+
19
+ # NAME matches a name the same way as the lexer.
20
+ # This name includes hyphen, which may be illegal in variables, and names in general.
21
+ NAME = %r{((::)?[a-z0-9][-\w]*)(::[a-z0-9][-\w]*)*}
22
+
23
+ # CLASSREF_EXT matches a class reference the same way as the lexer - i.e. the external source form
24
+ # where each part must start with a capital letter A-Z.
25
+ # This name includes hyphen, which may be illegal in some cases.
26
+ #
27
+ CLASSREF_EXT = %r{((::){0,1}[A-Z][-\w]*)+}
28
+
29
+ # CLASSREF matches a class reference the way it is represented internall in the
30
+ # model (i.e. in lower case).
31
+ # This name includes hyphen, which may be illegal in some cases.
32
+ #
33
+ CLASSREF = %r{((::){0,1}[a-z][-\w]*)+}
34
+
35
+ end
@@ -0,0 +1,104 @@
1
+ # Provides utility methods
2
+ module Puppet::Pops::Utils
3
+ # Can the given o be converted to numeric? (or is numeric already)
4
+ # Accepts a leading '::'
5
+ # Returns a boolean if the value is numeric
6
+ # If testing if value can be converted it is more efficient to call {#to_n} or {#to_n_with_radix} directly
7
+ # and check if value is nil.
8
+ def self.is_numeric?(o)
9
+ case o
10
+ when Numeric, Integer, Fixnum, Float
11
+ !!o
12
+ else
13
+ !!Puppet::Pops::Patterns::NUMERIC.match(relativize_name(o.to_s))
14
+ end
15
+ end
16
+
17
+ # To LiteralNumber with radix, or nil if not a number.
18
+ # If the value is already a number it is returned verbatim with a radix of 10.
19
+ # @param o [String, Number] a string containing a number in octal, hex, integer (decimal) or floating point form
20
+ # @return [Array<Number, Integer>, nil] array with converted number and radix, or nil if not possible to convert
21
+ # @api public
22
+ #
23
+ def self.to_n_with_radix o
24
+ begin
25
+ case o
26
+ when String
27
+ match = Puppet::Pops::Patterns::NUMERIC.match(relativize_name(o))
28
+ if !match
29
+ nil
30
+ elsif match[3].to_s.length > 0
31
+ # Use default radix (default is decimal == 10) for floats
32
+ [Float(match[0]), 10]
33
+ else
34
+ # Set radix (default is decimal == 10)
35
+ radix = 10
36
+ if match[1].to_s.length > 0
37
+ radix = 16
38
+ elsif match[2].to_s.length > 0 && match[2][0] == '0'
39
+ radix = 8
40
+ end
41
+ [Integer(match[0], radix), radix]
42
+ end
43
+ when Numeric, Fixnum, Integer, Float
44
+ # Impossible to calculate radix, assume decimal
45
+ [o, 10]
46
+ else
47
+ nil
48
+ end
49
+ rescue ArgumentError
50
+ nil
51
+ end
52
+ end
53
+
54
+ # To Numeric (or already numeric)
55
+ # Returns nil if value is not numeric, else an Integer or Float
56
+ # A leading '::' is accepted (and ignored)
57
+ #
58
+ def self.to_n o
59
+ begin
60
+ case o
61
+ when String
62
+ match = Puppet::Pops::Patterns::NUMERIC.match(relativize_name(o))
63
+ if !match
64
+ nil
65
+ elsif match[3].to_s.length > 0
66
+ Float(match[0])
67
+ else
68
+ Integer(match[0])
69
+ end
70
+ when Numeric, Fixnum, Integer, Float
71
+ o
72
+ else
73
+ nil
74
+ end
75
+ rescue ArgumentError
76
+ nil
77
+ end
78
+ end
79
+
80
+ # is the name absolute (i.e. starts with ::)
81
+ def self.is_absolute? name
82
+ name.start_with? "::"
83
+ end
84
+
85
+ def self.name_to_segments name
86
+ name.split("::")
87
+ end
88
+
89
+ def self.relativize_name name
90
+ is_absolute?(name) ? name[2..-1] : name
91
+ end
92
+
93
+ # Finds an adapter for o or for one of its containers, or nil, if none of the containers
94
+ # was adapted with the given adapter.
95
+ # This method can only be used with objects that respond to `:eContainer`.
96
+ # with true, and Adaptable#adapters.
97
+ #
98
+ def self.find_adapter(o, adapter)
99
+ return nil unless o
100
+ a = adapter.get(o)
101
+ return a if a
102
+ return find_adapter(o.eContainer, adapter)
103
+ end
104
+ end
@@ -0,0 +1,297 @@
1
+ # A module with base functionality for validation of a model.
2
+ #
3
+ # * SeverityProducer - produces a severity (:error, :warning, :ignore) for a given Issue
4
+ # * DiagnosticProducer - produces a Diagnostic which binds an Issue to an occurrence of that issue
5
+ # * Acceptor - the receiver/sink/collector of computed diagnostics
6
+ # * DiagnosticFormatter - produces human readable output for a Diagnostic
7
+ #
8
+ module Puppet::Pops::Validation
9
+ # Decides on the severity of a given issue.
10
+ # The produced severity is one of `:error`, `:warning`, or `:ignore`.
11
+ # By default, a severity of `:error` is produced for all issues. To configure the severity
12
+ # of an issue call `#severity=(issue, level)`.
13
+ #
14
+ class SeverityProducer
15
+ # Creates a new instance where all issues are diagnosed as :error unless overridden.
16
+ #
17
+ def initialize
18
+ # If diagnose is not set, the default is returned by the block
19
+ @severities = Hash.new :error
20
+ end
21
+
22
+ # Returns the severity of the given issue.
23
+ # @returns [Symbol] severity level :error, :warning, or :ignore
24
+ #
25
+ def severity issue
26
+ assert_issue(issue)
27
+ @severities[issue]
28
+ end
29
+
30
+ def [] issue
31
+ severity issue
32
+ end
33
+
34
+ # Override a default severity with the given severity level.
35
+ #
36
+ # @param issue [Puppet::Pops::Issues::Issue] the issue for which to set severity
37
+ # @param level [Symbol] the severity level (:error, :warning, or :ignore).
38
+ #
39
+ def []= issue, level
40
+ assert_issue(issue)
41
+ assert_severity(level)
42
+ raise Puppet::DevError.new("Attempt to demote the hard issue '#{issue.issue_code}' to #{level}") unless issue.demotable? || level == :error
43
+ @severities[issue] = level
44
+ end
45
+
46
+ # Returns true if the issue should be reported or not.
47
+ # @returns [Boolean] this implementation returns true for errors and warnings
48
+ #
49
+ def should_report? issue
50
+ diagnose = self[issue]
51
+ diagnose == :error || diagnose == :warning || diagnose == :deprecation
52
+ end
53
+
54
+ def assert_issue issue
55
+ raise Puppet::DevError.new("Attempt to get validation severity for something that is not an Issue. (Got #{issue.class})") unless issue.is_a? Puppet::Pops::Issues::Issue
56
+ end
57
+
58
+ def assert_severity level
59
+ raise Puppet::DevError.new("Illegal severity level: #{option}") unless [:ignore, :warning, :error, :deprecation].include? level
60
+ end
61
+ end
62
+
63
+ # A producer of diagnostics.
64
+ # An producer of diagnostics is given each issue occurrence as they are found by a diagnostician/validator. It then produces
65
+ # a Diagnostic, which it passes on to a configured Acceptor.
66
+ #
67
+ # This class exists to aid a diagnostician/validator which will typically first check if a particular issue
68
+ # will be accepted at all (before checking for an occurrence of the issue; i.e. to perform check avoidance for expensive checks).
69
+ # A validator passes an instance of Issue, the semantic object (the "culprit"), a hash with arguments, and an optional
70
+ # exception. The semantic object is used to determine the location of the occurrence of the issue (file/line), and it
71
+ # sets keys in the given argument hash that may be used in the formatting of the issue message.
72
+ #
73
+ class DiagnosticProducer
74
+
75
+ # A producer of severity for a given issue
76
+ # @return [SeverityProducer]
77
+ #
78
+ attr_reader :severity_producer
79
+
80
+ # A producer of labels for objects involved in the issue
81
+ # @return [LabelProvider]
82
+ #
83
+ attr_reader :label_provider
84
+ # Initializes this producer.
85
+ #
86
+ # @param acceptor [Acceptor] a sink/collector of diagnostic results
87
+ # @param severity_producer [SeverityProducer] the severity producer to use to determine severity of a given issue
88
+ # @param label_provider [LabelProvider] a provider of model element type to human readable label
89
+ #
90
+ def initialize(acceptor, severity_producer, label_provider)
91
+ @acceptor = acceptor
92
+ @severity_producer = severity_producer
93
+ @label_provider = label_provider
94
+ end
95
+
96
+ def accept(issue, semantic, arguments={}, except=nil)
97
+ return unless will_accept? issue
98
+
99
+ # Set label provider unless caller provided a special label provider
100
+ arguments[:label] ||= @label_provider
101
+ arguments[:semantic] ||= semantic
102
+
103
+ # A detail message is always provided, but is blank by default.
104
+ arguments[:detail] ||= ''
105
+
106
+ origin_adapter = Puppet::Pops::Utils.find_adapter(semantic, Puppet::Pops::Adapters::OriginAdapter)
107
+ file = origin_adapter ? origin_adapter.origin : nil
108
+ source_pos = Puppet::Pops::Utils.find_adapter(semantic, Puppet::Pops::Adapters::SourcePosAdapter)
109
+ severity = @severity_producer.severity(issue)
110
+ @acceptor.accept(Diagnostic.new(severity, issue, file, source_pos, arguments))
111
+ end
112
+
113
+ def will_accept? issue
114
+ @severity_producer.should_report? issue
115
+ end
116
+ end
117
+
118
+ class Diagnostic
119
+ attr_reader :severity
120
+ attr_reader :issue
121
+ attr_reader :arguments
122
+ attr_reader :exception
123
+ attr_reader :file
124
+ attr_reader :source_pos
125
+ def initialize severity, issue, file, source_pos, arguments={}, exception=nil
126
+ @severity = severity
127
+ @issue = issue
128
+ @file = file
129
+ @source_pos = source_pos
130
+ @arguments = arguments
131
+ @exception = exception
132
+ end
133
+ end
134
+
135
+ # Formats a diagnostic for output.
136
+ # Produces a diagnostic output typical for a compiler (suitable for interpretation by tools)
137
+ # The format is:
138
+ # `file:line:pos: Message`, where pos, line and file are included if available.
139
+ #
140
+ class DiagnosticFormatter
141
+ def format diagnostic
142
+ "#{loc(diagnostic)} #{format_severity(diagnostic)}#{format_message(diagnostic)}"
143
+ end
144
+
145
+ def format_message diagnostic
146
+ diagnostic.issue.format(diagnostic.arguments)
147
+ end
148
+
149
+ # This produces "Deprecation notice: " prefix if the diagnostic has :deprecation severity, otherwise "".
150
+ # The idea is that all other diagnostics are emitted with the methods Puppet.err (or an exception), and
151
+ # Puppet.warning.
152
+ # @note Note that it is not a good idea to use Puppet.deprecation_warning as it is for internal deprecation.
153
+ #
154
+ def format_severity diagnostic
155
+ diagnostic.severity == :deprecation ? "Deprecation notice: " : ""
156
+ end
157
+
158
+ def format_location diagnostic
159
+ file = diagnostic.file
160
+ line = diagnostic.source_pos.line
161
+ pos = diagnostic.source_pos.pos
162
+ if file && line && pos
163
+ "#{file}:#{line}:#{pos}:"
164
+ elsif file && line
165
+ "#{file}:#{line}:"
166
+ elsif file
167
+ "#{file}:"
168
+ else
169
+ ""
170
+ end
171
+ end
172
+ end
173
+
174
+ # Produces a diagnostic output in the "puppet style", where the location is appended with an "at ..." if the
175
+ # location is known.
176
+ #
177
+ class DiagnosticFormatterPuppetStyle < DiagnosticFormatter
178
+ def format diagnostic
179
+ if (location = format_location diagnostic) != ""
180
+ "#{format_severity(diagnostic)}#{format_message(diagnostic)}#{location}"
181
+ else
182
+ format_message(diagnostic)
183
+ end
184
+ end
185
+
186
+ # The somewhat (machine) unusable format in current use by puppet.
187
+ # have to be used here for backwards compatibility.
188
+ def format_location diagnostic
189
+ file = diagnostic.file
190
+ line = diagnostic.source_pos.line
191
+ pos = diagnostic.source_pos.pos
192
+ if file && line && pos
193
+ " at #{file}:#{line}:#{pos}"
194
+ elsif file and line
195
+ " at #{file}:#{line}"
196
+ elsif line && pos
197
+ " at line #{line}:#{pos}"
198
+ elsif line
199
+ " at line #{line}"
200
+ elsif file
201
+ " in #{file}"
202
+ else
203
+ ""
204
+ end
205
+ end
206
+ end
207
+
208
+ # An acceptor of diagnostics.
209
+ # An acceptor of diagnostics is given each issue as they are found by a diagnostician/validator. An
210
+ # acceptor can collect all found issues, or decide to collect a few and then report, or give up as the first issue
211
+ # if found.
212
+ # This default implementation collects all diagnostics in the order they are produced, and can then
213
+ # answer questions about what was diagnosed.
214
+ #
215
+ class Acceptor
216
+
217
+ # All diagnstic in the order they were issued
218
+ attr_reader :diagnostics
219
+
220
+ # The number of :warning severity issues + number of :deprecation severity issues
221
+ attr_reader :warning_count
222
+
223
+ # The number of :error severity issues
224
+ attr_reader :error_count
225
+ # Initializes this diagnostics acceptor.
226
+ # By default, the acceptor is configured with a default severity producer.
227
+ # @param severity_producer [SeverityProducer] the severity producer to use to determine severity of an issue
228
+ #
229
+ # TODO add semantic_label_provider
230
+ #
231
+ def initialize()
232
+ @diagnostics = []
233
+ @error_count = 0
234
+ @warning_count = 0
235
+ end
236
+
237
+ # Returns true when errors have been diagnosed.
238
+ def errors?
239
+ @error_count > 0
240
+ end
241
+
242
+ # Returns true when warnings have been diagnosed.
243
+ def warnings?
244
+ @warning_count > 0
245
+ end
246
+
247
+ # Returns true when errors and/or warnings have been diagnosed.
248
+ def errors_or_warnings?
249
+ errors? || warnings?
250
+ end
251
+
252
+ # Returns the diagnosed errors in the order thwy were reported.
253
+ def errors
254
+ @diagnostics.select {|d| d.severity == :error }
255
+ end
256
+
257
+ # Returns the diagnosed warnings in the order thwy were reported.
258
+ # (This includes :warning and :deprecation severity)
259
+ def warnings
260
+ @diagnostics.select {|d| d.severity == :warning || d.severity == :deprecation }
261
+ end
262
+
263
+ def errors_and_warnings
264
+ @diagnostics.select {|d| d.severity != :ignored}
265
+ end
266
+
267
+ # Returns the ignored diagnostics in the order thwy were reported (if reported at all)
268
+ def ignored
269
+ @diagnostics.select {|d| d.severity == :ignore }
270
+ end
271
+
272
+ # Add a diagnostic to the set of diagnostics
273
+ def accept(diagnostic)
274
+ self.send(diagnostic.severity, diagnostic)
275
+ end
276
+
277
+ private
278
+
279
+ def ignore diagnostic
280
+ @diagnostics << diagnostic
281
+ end
282
+
283
+ def error diagnostic
284
+ @diagnostics << diagnostic
285
+ @error_count += 1
286
+ end
287
+
288
+ def warning diagnostic
289
+ @diagnostics << diagnostic
290
+ @warning_count += 1
291
+ end
292
+
293
+ def deprecation diagnostic
294
+ warning diagnostic
295
+ end
296
+ end
297
+ end