puppet 4.7.1 → 4.8.0

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 (276) hide show
  1. data/Gemfile +0 -3
  2. data/MAINTAINERS +76 -0
  3. data/README.md +0 -6
  4. data/Rakefile +2 -2
  5. data/lib/puppet/agent.rb +3 -3
  6. data/lib/puppet/application/apply.rb +1 -1
  7. data/lib/puppet/configurer.rb +2 -2
  8. data/lib/puppet/data_providers.rb +1 -0
  9. data/lib/puppet/data_providers/data_adapter.rb +1 -0
  10. data/lib/puppet/data_providers/data_function_support.rb +1 -0
  11. data/lib/puppet/data_providers/function_env_data_provider.rb +1 -0
  12. data/lib/puppet/data_providers/function_module_data_provider.rb +1 -0
  13. data/lib/puppet/data_providers/hiera_config.rb +1 -0
  14. data/lib/puppet/data_providers/hiera_env_data_provider.rb +1 -0
  15. data/lib/puppet/data_providers/hiera_interpolate.rb +1 -0
  16. data/lib/puppet/data_providers/hiera_module_data_provider.rb +1 -0
  17. data/lib/puppet/data_providers/hiera_support.rb +1 -2
  18. data/lib/puppet/data_providers/json_data_provider_factory.rb +2 -0
  19. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -0
  20. data/lib/puppet/defaults.rb +20 -1
  21. data/lib/puppet/environments.rb +5 -2
  22. data/lib/puppet/face/catalog.rb +1 -1
  23. data/lib/puppet/face/epp.rb +57 -11
  24. data/lib/puppet/face/module/install.rb +6 -6
  25. data/lib/puppet/functions.rb +23 -24
  26. data/lib/puppet/functions/alert.rb +14 -0
  27. data/lib/puppet/functions/binary_file.rb +25 -0
  28. data/lib/puppet/functions/break.rb +22 -0
  29. data/lib/puppet/functions/contain.rb +33 -0
  30. data/lib/puppet/functions/crit.rb +14 -0
  31. data/lib/puppet/functions/debug.rb +14 -0
  32. data/lib/puppet/functions/emerg.rb +14 -0
  33. data/lib/puppet/functions/epp.rb +1 -1
  34. data/lib/puppet/functions/err.rb +14 -0
  35. data/lib/puppet/functions/find_file.rb +31 -0
  36. data/lib/puppet/functions/include.rb +21 -0
  37. data/lib/puppet/functions/info.rb +14 -0
  38. data/lib/puppet/functions/new.rb +1 -1
  39. data/lib/puppet/functions/next.rb +23 -0
  40. data/lib/puppet/functions/notice.rb +14 -0
  41. data/lib/puppet/functions/regsubst.rb +12 -16
  42. data/lib/puppet/functions/require.rb +37 -0
  43. data/lib/puppet/functions/return.rb +22 -0
  44. data/lib/puppet/functions/strftime.rb +35 -0
  45. data/lib/puppet/functions/warning.rb +14 -0
  46. data/lib/puppet/generate/models/type/type.rb +4 -0
  47. data/lib/puppet/generate/templates/type/pcore.erb +2 -1
  48. data/lib/puppet/indirector/face.rb +6 -1
  49. data/lib/puppet/network/http/error.rb +2 -2
  50. data/lib/puppet/network/http/handler.rb +2 -2
  51. data/lib/puppet/node/environment.rb +11 -0
  52. data/lib/puppet/parser/ast.rb +5 -0
  53. data/lib/puppet/parser/ast/pops_bridge.rb +17 -4
  54. data/lib/puppet/parser/compiler.rb +29 -1
  55. data/lib/puppet/parser/functions.rb +6 -0
  56. data/lib/puppet/parser/functions/assert_type.rb +1 -1
  57. data/lib/puppet/parser/functions/binary_file.rb +24 -0
  58. data/lib/puppet/parser/functions/break.rb +39 -0
  59. data/lib/puppet/parser/functions/contain.rb +7 -15
  60. data/lib/puppet/parser/functions/defined.rb +2 -2
  61. data/lib/puppet/parser/functions/dig.rb +1 -1
  62. data/lib/puppet/parser/functions/each.rb +1 -1
  63. data/lib/puppet/parser/functions/epp.rb +2 -2
  64. data/lib/puppet/parser/functions/filter.rb +1 -1
  65. data/lib/puppet/parser/functions/find_file.rb +28 -0
  66. data/lib/puppet/parser/functions/hiera.rb +4 -4
  67. data/lib/puppet/parser/functions/hiera_array.rb +1 -1
  68. data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
  69. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  70. data/lib/puppet/parser/functions/include.rb +4 -8
  71. data/lib/puppet/parser/functions/inline_epp.rb +1 -1
  72. data/lib/puppet/parser/functions/lest.rb +1 -1
  73. data/lib/puppet/parser/functions/lookup.rb +4 -2
  74. data/lib/puppet/parser/functions/map.rb +1 -1
  75. data/lib/puppet/parser/functions/match.rb +1 -1
  76. data/lib/puppet/parser/functions/new.rb +414 -18
  77. data/lib/puppet/parser/functions/next.rb +38 -0
  78. data/lib/puppet/parser/functions/reduce.rb +1 -1
  79. data/lib/puppet/parser/functions/regsubst.rb +4 -2
  80. data/lib/puppet/parser/functions/require.rb +4 -27
  81. data/lib/puppet/parser/functions/return.rb +71 -0
  82. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  83. data/lib/puppet/parser/functions/scanf.rb +13 -8
  84. data/lib/puppet/parser/functions/slice.rb +1 -1
  85. data/lib/puppet/parser/functions/split.rb +1 -1
  86. data/lib/puppet/parser/functions/step.rb +1 -1
  87. data/lib/puppet/parser/functions/strftime.rb +185 -0
  88. data/lib/puppet/parser/functions/then.rb +1 -1
  89. data/lib/puppet/parser/functions/type.rb +1 -1
  90. data/lib/puppet/parser/functions/with.rb +3 -3
  91. data/lib/puppet/parser/resource.rb +8 -5
  92. data/lib/puppet/parser/scope.rb +1 -1
  93. data/lib/puppet/plugins/configuration.rb +8 -0
  94. data/lib/puppet/plugins/data_providers.rb +1 -0
  95. data/lib/puppet/plugins/data_providers/data_provider.rb +7 -28
  96. data/lib/puppet/plugins/data_providers/registry.rb +1 -0
  97. data/lib/puppet/pops.rb +4 -0
  98. data/lib/puppet/pops/evaluator/access_operator.rb +36 -5
  99. data/lib/puppet/pops/evaluator/closure.rb +81 -12
  100. data/lib/puppet/pops/evaluator/compare_operator.rb +24 -1
  101. data/lib/puppet/pops/evaluator/evaluator_impl.rb +29 -5
  102. data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +1 -1
  103. data/lib/puppet/pops/evaluator/runtime3_converter.rb +53 -62
  104. data/lib/puppet/pops/evaluator/runtime3_support.rb +15 -6
  105. data/lib/puppet/pops/functions/dispatch.rb +9 -2
  106. data/lib/puppet/pops/functions/dispatcher.rb +3 -1
  107. data/lib/puppet/pops/functions/function.rb +19 -2
  108. data/lib/puppet/pops/issues.rb +9 -0
  109. data/lib/puppet/pops/label_provider.rb +2 -2
  110. data/lib/puppet/pops/loader/loader.rb +17 -0
  111. data/lib/puppet/pops/loader/static_loader.rb +0 -41
  112. data/lib/puppet/pops/lookup.rb +12 -0
  113. data/lib/puppet/pops/lookup/context.rb +86 -0
  114. data/lib/puppet/pops/lookup/explainer.rb +46 -6
  115. data/lib/puppet/pops/lookup/invocation.rb +19 -0
  116. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  117. data/lib/puppet/pops/model/factory.rb +20 -8
  118. data/lib/puppet/pops/model/model_label_provider.rb +3 -0
  119. data/lib/puppet/pops/model/model_meta.rb +2 -0
  120. data/lib/puppet/pops/model/model_tree_dumper.rb +14 -0
  121. data/lib/puppet/pops/parser/egrammar.ra +11 -6
  122. data/lib/puppet/pops/parser/eparser.rb +1112 -1086
  123. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  124. data/lib/puppet/pops/pcore.rb +1 -0
  125. data/lib/puppet/pops/puppet_stack.rb +3 -3
  126. data/lib/puppet/pops/resource/param.rb +5 -1
  127. data/lib/puppet/pops/resource/resource_type_impl.rb +8 -4
  128. data/lib/puppet/pops/resource/resource_type_set.pcore +1 -0
  129. data/lib/puppet/pops/serialization/abstract_reader.rb +19 -2
  130. data/lib/puppet/pops/serialization/abstract_writer.rb +16 -3
  131. data/lib/puppet/pops/serialization/deserializer.rb +5 -1
  132. data/lib/puppet/pops/serialization/extension.rb +2 -0
  133. data/lib/puppet/pops/serialization/json.rb +76 -26
  134. data/lib/puppet/pops/serialization/serializer.rb +5 -1
  135. data/lib/puppet/pops/serialization/time_factory.rb +2 -1
  136. data/lib/puppet/pops/time/timespan.rb +718 -0
  137. data/lib/puppet/pops/time/timestamp.rb +148 -0
  138. data/lib/puppet/pops/types/p_binary_type.rb +220 -0
  139. data/lib/puppet/pops/types/p_object_type.rb +12 -6
  140. data/lib/puppet/pops/types/p_sensitive_type.rb +5 -1
  141. data/lib/puppet/pops/types/p_timespan_type.rb +141 -0
  142. data/lib/puppet/pops/types/p_timestamp_type.rb +69 -0
  143. data/lib/puppet/pops/types/string_converter.rb +62 -0
  144. data/lib/puppet/pops/types/type_asserter.rb +1 -1
  145. data/lib/puppet/pops/types/type_calculator.rb +17 -3
  146. data/lib/puppet/pops/types/type_factory.rb +35 -1
  147. data/lib/puppet/pops/types/type_formatter.rb +64 -11
  148. data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -61
  149. data/lib/puppet/pops/types/type_parser.rb +18 -4
  150. data/lib/puppet/pops/types/types.rb +98 -63
  151. data/lib/puppet/pops/validation.rb +9 -1
  152. data/lib/puppet/pops/validation/checker4_0.rb +7 -0
  153. data/lib/puppet/property.rb +1 -1
  154. data/lib/puppet/provider.rb +3 -6
  155. data/lib/puppet/provider/mcx/mcxcontent.rb +1 -1
  156. data/lib/puppet/provider/mount/parsed.rb +18 -4
  157. data/lib/puppet/provider/nameservice/directoryservice.rb +15 -7
  158. data/lib/puppet/provider/package/gem.rb +6 -1
  159. data/lib/puppet/provider/package/pip.rb +0 -1
  160. data/lib/puppet/provider/package/pkg.rb +5 -1
  161. data/lib/puppet/provider/package/pkgng.rb +1 -1
  162. data/lib/puppet/provider/package/yum.rb +10 -0
  163. data/lib/puppet/provider/service/launchd.rb +1 -0
  164. data/lib/puppet/provider/user/directoryservice.rb +6 -6
  165. data/lib/puppet/provider/yumrepo/inifile.rb +1 -1
  166. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  167. data/lib/puppet/resource.rb +54 -12
  168. data/lib/puppet/resource/capability_finder.rb +15 -9
  169. data/lib/puppet/resource/catalog.rb +25 -6
  170. data/lib/puppet/resource/type.rb +3 -1
  171. data/lib/puppet/settings.rb +1 -1
  172. data/lib/puppet/settings/environment_conf.rb +12 -4
  173. data/lib/puppet/syntax_checkers/base64.rb +41 -0
  174. data/lib/puppet/syntax_checkers/json.rb +0 -2
  175. data/lib/puppet/transaction.rb +6 -0
  176. data/lib/puppet/transaction/additional_resource_generator.rb +5 -0
  177. data/lib/puppet/transaction/report.rb +7 -2
  178. data/lib/puppet/type.rb +2 -1
  179. data/lib/puppet/type/file/checksum.rb +1 -0
  180. data/lib/puppet/type/file/content.rb +4 -4
  181. data/lib/puppet/type/mount.rb +44 -0
  182. data/lib/puppet/type/ssh_authorized_key.rb +1 -1
  183. data/lib/puppet/type/tidy.rb +3 -0
  184. data/lib/puppet/type/user.rb +12 -6
  185. data/lib/puppet/util/log.rb +25 -0
  186. data/lib/puppet/util/plist.rb +8 -3
  187. data/lib/puppet/version.rb +1 -1
  188. data/lib/puppet_x.rb +7 -1
  189. data/spec/integration/application/apply_spec.rb +118 -0
  190. data/spec/integration/parser/compiler_spec.rb +28 -0
  191. data/spec/integration/parser/pcore_resource_spec.rb +40 -3
  192. data/spec/integration/provider/mount_spec.rb +2 -1
  193. data/spec/integration/util/windows/principal_spec.rb +2 -2
  194. data/spec/integration/util/windows/registry_spec.rb +4 -4
  195. data/spec/lib/puppet_spec/compiler.rb +5 -1
  196. data/spec/lib/puppet_spec/unindent.rb +5 -0
  197. data/spec/shared_contexts/types_setup.rb +6 -0
  198. data/spec/shared_examples/rhel_package_provider.rb +16 -0
  199. data/spec/spec_helper.rb +1 -0
  200. data/spec/unit/agent_spec.rb +11 -0
  201. data/spec/unit/application/lookup_spec.rb +94 -3
  202. data/spec/unit/capability_spec.rb +22 -0
  203. data/spec/unit/configurer_spec.rb +8 -0
  204. data/spec/unit/face/epp_face_spec.rb +22 -3
  205. data/spec/unit/functions/assert_type_spec.rb +3 -3
  206. data/spec/unit/functions/binary_file_spec.rb +46 -0
  207. data/spec/unit/functions/break_spec.rb +89 -0
  208. data/spec/unit/{parser/functions → functions}/contain_spec.rb +68 -3
  209. data/spec/unit/functions/find_file_spec.rb +69 -0
  210. data/spec/unit/functions/include_spec.rb +175 -0
  211. data/spec/unit/functions/logging_spec.rb +54 -0
  212. data/spec/unit/functions/lookup_spec.rb +3 -3
  213. data/spec/unit/functions/new_spec.rb +105 -5
  214. data/spec/unit/functions/next_spec.rb +93 -0
  215. data/spec/unit/functions/require_spec.rb +83 -0
  216. data/spec/unit/functions/return_spec.rb +105 -0
  217. data/spec/unit/{parser/functions → functions}/shared.rb +14 -11
  218. data/spec/unit/functions/strftime_spec.rb +152 -0
  219. data/spec/unit/functions4_spec.rb +22 -0
  220. data/spec/unit/indirector/face_spec.rb +10 -2
  221. data/spec/unit/network/http/error_spec.rb +1 -2
  222. data/spec/unit/network/http/handler_spec.rb +6 -5
  223. data/spec/unit/parser/functions/hiera_array_spec.rb +1 -1
  224. data/spec/unit/parser/functions/hiera_hash_spec.rb +1 -1
  225. data/spec/unit/parser/functions/hiera_include_spec.rb +1 -1
  226. data/spec/unit/parser/functions/hiera_spec.rb +1 -1
  227. data/spec/unit/parser/functions/lookup_spec.rb +1 -1
  228. data/spec/unit/parser/functions/regsubst_spec.rb +1 -1
  229. data/spec/unit/parser/functions/split_spec.rb +1 -1
  230. data/spec/unit/pops/evaluator/access_ops_spec.rb +81 -1
  231. data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +170 -0
  232. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +29 -4
  233. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +112 -4
  234. data/spec/unit/pops/loaders/dependency_loader_spec.rb +12 -0
  235. data/spec/unit/pops/loaders/static_loader_spec.rb +0 -26
  236. data/spec/unit/pops/lookup/context_spec.rb +149 -0
  237. data/spec/unit/pops/parser/parse_functions_spec.rb +19 -0
  238. data/spec/unit/pops/parser/parse_lambda_spec.rb +19 -0
  239. data/spec/unit/pops/puppet_stack_spec.rb +1 -1
  240. data/spec/unit/pops/resource/resource_type_impl_spec.rb +74 -0
  241. data/spec/unit/pops/serialization/packer_spec.rb +34 -14
  242. data/spec/unit/pops/serialization/serialization_spec.rb +67 -5
  243. data/spec/unit/pops/time/timespan_spec.rb +121 -0
  244. data/spec/unit/pops/types/p_binary_type_spec.rb +243 -0
  245. data/spec/unit/pops/types/p_object_type_spec.rb +7 -7
  246. data/spec/unit/pops/types/p_sensitive_type_spec.rb +1 -1
  247. data/spec/unit/pops/types/p_timespan_type_spec.rb +273 -0
  248. data/spec/unit/pops/types/p_timestamp_type_spec.rb +311 -0
  249. data/spec/unit/pops/types/p_type_set_type_spec.rb +13 -13
  250. data/spec/unit/pops/types/ruby_generator_spec.rb +12 -12
  251. data/spec/unit/pops/types/string_converter_spec.rb +89 -0
  252. data/spec/unit/pops/types/type_asserter_spec.rb +3 -3
  253. data/spec/unit/pops/types/type_calculator_spec.rb +113 -5
  254. data/spec/unit/pops/types/type_formatter_spec.rb +40 -0
  255. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +49 -38
  256. data/spec/unit/pops/types/type_parser_spec.rb +87 -4
  257. data/spec/unit/pops/types/types_spec.rb +1 -1
  258. data/spec/unit/pops/validator/validator_spec.rb +23 -0
  259. data/spec/unit/provider/mount/parsed_spec.rb +47 -29
  260. data/spec/unit/provider/package/pkg_spec.rb +109 -99
  261. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -0
  262. data/spec/unit/provider/user/aix_spec.rb +1 -1
  263. data/spec/unit/provider/user/directoryservice_spec.rb +101 -30
  264. data/spec/unit/resource/capability_finder_spec.rb +29 -7
  265. data/spec/unit/resource/catalog_spec.rb +127 -0
  266. data/spec/unit/ssl/certificate_request_spec.rb +1 -1
  267. data/spec/unit/transaction/additional_resource_generator_spec.rb +30 -0
  268. data/spec/unit/transaction/persistence_spec.rb +1 -6
  269. data/spec/unit/transaction/report_spec.rb +23 -0
  270. data/spec/unit/transaction_spec.rb +38 -0
  271. data/spec/unit/type/mount_spec.rb +5 -0
  272. data/spec/unit/util/plist_spec.rb +14 -2
  273. metadata +71 -12
  274. data/spec/integration/parser/functions/require_spec.rb +0 -43
  275. data/spec/unit/parser/functions/include_spec.rb +0 -55
  276. data/spec/unit/parser/functions/require_spec.rb +0 -68
@@ -40,8 +40,6 @@ module Puppet::Pops::LabelProvider
40
40
  count == 1 ? text : "#{text}s"
41
41
  end
42
42
 
43
- private
44
-
45
43
  # Produces an *indefinite article* (a/an) for the given text ('a' if
46
44
  # it starts with a vowel) This is obviously flawed in the general
47
45
  # sense as may labels have punctuation at the start and this method
@@ -52,6 +50,8 @@ module Puppet::Pops::LabelProvider
52
50
  article_for_letter(first_letter_of(s))
53
51
  end
54
52
 
53
+ private
54
+
55
55
  def first_letter_of(string)
56
56
  char = string[0,1]
57
57
  if SKIPPED_CHARACTERS.include? char
@@ -150,6 +150,23 @@ class Loader
150
150
  LOADABLE_KINDS
151
151
  end
152
152
 
153
+ # A loader may want to implement its own version with more detailed information.
154
+ def to_s
155
+ loader_name
156
+ end
157
+
158
+ # Loaders may contain references to the environment they load items within.
159
+ # Consequently, calling Kernel#inspect may return strings that are large
160
+ # enough to cause OutOfMemoryErrors on some platforms.
161
+ #
162
+ # We do not call alias_method here as that would copy the content of to_s
163
+ # at this point to inspect (ie children would print out `loader_name`
164
+ # rather than their version of to_s if they chose to implement it).
165
+ def inspect
166
+ self.to_s
167
+ end
168
+
169
+
153
170
  # An entry for one entity loaded by the loader.
154
171
  #
155
172
  class NamedEntry
@@ -63,7 +63,6 @@ class StaticLoader < Loader
63
63
  attr_reader :loaded
64
64
  def initialize
65
65
  @loaded = {}
66
- create_logging_functions()
67
66
  create_built_in_types()
68
67
  create_resource_type_references()
69
68
  end
@@ -99,46 +98,6 @@ class StaticLoader < Loader
99
98
  @loaded[typed_name]
100
99
  end
101
100
 
102
- # Creates a function for each of the specified log levels
103
- #
104
- def create_logging_functions()
105
- Puppet::Util::Log.levels.each do |level|
106
-
107
- fc = Puppet::Functions.create_function(level) do
108
- # create empty dispatcher to stop it from complaining about missing method since
109
- # an override of :call is made instead of using dispatch.
110
- dispatch(:log) { }
111
-
112
- # Logs per the specified level, outputs formatted information for arrays, hashes etc.
113
- # Overrides the implementation in Function that uses dispatching. This is not needed here
114
- # since it accepts 0-n Object.
115
- #
116
- define_method(:call) do |scope, *vals|
117
- # NOTE: 3x, does this: vals.join(" ")
118
- # New implementation uses the evaluator to get proper formatting per type
119
- # TODO: uses a fake scope (nil) - fix when :scopes are available via settings
120
- mapped = vals.map {|v| Puppet::Pops::Evaluator::EvaluatorImpl.new.string(v, nil) }
121
-
122
- # Bypass Puppet.<level> call since it picks up source from "self" which is not applicable in the 4x
123
- # Function API.
124
- # TODO: When a function can obtain the file, line, pos of the call merge those in (3x supports
125
- # options :file, :line. (These were never output when calling the 3x logging functions since
126
- # 3x scope does not know about the calling location at that detailed level, nor do they
127
- # appear in a report to stdout/error when included). Now, the output simply uses scope (like 3x)
128
- # as this is good enough, but does not reflect the true call-stack, but is a rough estimate
129
- # of where the logging call originates from).
130
- #
131
- Puppet::Util::Log.create({:level => level, :source => scope, :message => mapped.join(" ")})
132
- end
133
- end
134
-
135
- typed_name = TypedName.new(:function, level)
136
- # TODO:closure scope is fake (an empty hash) - waiting for new global scope to be available via lookup of :scopes
137
- func = fc.new({},self)
138
- @loaded[ typed_name ] = NamedEntry.new(typed_name, func, __FILE__)
139
- end
140
- end
141
-
142
101
  def create_built_in_types
143
102
  origin_uri = URI("puppet:Puppet-Type-System/Static-Loader")
144
103
  type_map = Puppet::Pops::Types::TypeParser.type_map
@@ -54,12 +54,24 @@ module Lookup
54
54
  elsif has_default
55
55
  answer = assert_type('Default value', value_type, default_value)
56
56
  else
57
+ lookup_invocation.emit_debug_info(debug_preamble(names)) if Puppet[:debug]
57
58
  fail_lookup(names)
58
59
  end
59
60
  end
61
+ lookup_invocation.emit_debug_info(debug_preamble(names)) if Puppet[:debug]
60
62
  answer
61
63
  end
62
64
 
65
+ # @api private
66
+ def self.debug_preamble(names)
67
+ if names.size == 1
68
+ names = "'#{names[0]}'"
69
+ else
70
+ names = names.map { |n| "'#{n}'" }.join(', ')
71
+ end
72
+ "Lookup of #{names}"
73
+ end
74
+
63
75
  # @api private
64
76
  def self.search_and_merge(name, lookup_invocation, merge)
65
77
  return Puppet::DataProviders.lookup_adapter(lookup_invocation).lookup(name, lookup_invocation, merge)
@@ -0,0 +1,86 @@
1
+ module Puppet::Pops
2
+ module Lookup
3
+ class Context
4
+ include Types::PuppetObject
5
+
6
+ def self._ptype
7
+ @type
8
+ end
9
+
10
+ def self.register_ptype(loader, ir)
11
+ tf = Types::TypeFactory
12
+ @type = Pcore::create_object_type(loader, ir, self, 'Puppet::LookupContext', 'Any',
13
+ {
14
+ 'environment_name' => Types::PStringType::NON_EMPTY,
15
+ 'module_name' => {
16
+ Types::KEY_TYPE => tf.optional(Types::PStringType::NON_EMPTY),
17
+ Types::KEY_VALUE => nil
18
+ }
19
+ },
20
+ {
21
+ 'not_found' => tf.callable([0, 0], tf.undef),
22
+ 'explain' => tf.callable([0, 0, tf.callable(0,0)], tf.undef),
23
+ 'cache' => tf.callable([tf.scalar, tf.any], tf.undef),
24
+ 'cache_all' => tf.callable([tf.hash_kv(tf.scalar, tf.any)], tf.undef),
25
+ 'cached_value' => tf.callable([tf.scalar], tf.any),
26
+ 'cached_entries' => tf.variant(
27
+ tf.callable([0, 0, tf.callable(1,1)], tf.undef),
28
+ tf.callable([0, 0, tf.callable(2,2)], tf.undef),
29
+ tf.callable([0, 0], tf.iterable(tf.tuple([tf.scalar, tf.any])))
30
+ )
31
+ }
32
+ ).resolve(Types::TypeParser.singleton, loader)
33
+ end
34
+
35
+ attr_reader :environment_name
36
+ attr_reader :module_name
37
+
38
+ def initialize(environment_name, module_name, lookup_invocation = Invocation.current)
39
+ @lookup_invocation = lookup_invocation
40
+ @environment_name = environment_name
41
+ @module_name = module_name
42
+ @cache = {}
43
+ end
44
+
45
+ def cache(key, value)
46
+ @cache[key] = value
47
+ nil
48
+ end
49
+
50
+ def cache_all(hash)
51
+ @cache.merge!(hash)
52
+ nil
53
+ end
54
+
55
+ def cached_value(key)
56
+ @cache[key]
57
+ end
58
+
59
+ def cached_entries(&block)
60
+ @cache
61
+ if block_given?
62
+ enumerator = @cache.each_pair
63
+ @cache.size.times do
64
+ if block.arity == 2
65
+ yield(*enumerator.next)
66
+ else
67
+ yield(enumerator.next)
68
+ end
69
+ end
70
+ nil
71
+ else
72
+ Types::Iterable.on(@cache)
73
+ end
74
+ end
75
+
76
+ def explain(&block)
77
+ @lookup_invocation.report_text(&block) unless @lookup_invocation.nil?
78
+ nil
79
+ end
80
+
81
+ def not_found
82
+ throw :no_such_key
83
+ end
84
+ end
85
+ end
86
+ end
@@ -18,9 +18,9 @@ module Puppet::Pops::Lookup
18
18
  end
19
19
 
20
20
  def to_s
21
- io = StringIO.new
21
+ io = ''
22
22
  dump_on(io, '', '')
23
- io.string
23
+ io
24
24
  end
25
25
 
26
26
  def dump_on(io, indent, first_indent)
@@ -34,6 +34,7 @@ module Puppet::Pops::Lookup
34
34
  def initialize(parent)
35
35
  @parent = parent
36
36
  @event = nil
37
+ @texts = nil
37
38
  end
38
39
 
39
40
  def found_in_overrides(key, value)
@@ -59,6 +60,11 @@ module Puppet::Pops::Lookup
59
60
  @event = :result
60
61
  end
61
62
 
63
+ def text(text)
64
+ @texts ||= []
65
+ @texts << text
66
+ end
67
+
62
68
  def not_found(key)
63
69
  @key = key
64
70
  @event = :not_found
@@ -81,6 +87,7 @@ module Puppet::Pops::Lookup
81
87
  hash[:key] = @key unless @key.nil?
82
88
  hash[:value] = @value if [:found, :found_in_defaults, :found_in_overrides, :result].include?(@event)
83
89
  hash[:event] = @event unless @event.nil?
90
+ hash[:texts] = @texts unless @texts.nil?
84
91
  hash[:type] = type
85
92
  hash
86
93
  end
@@ -98,6 +105,11 @@ module Puppet::Pops::Lookup
98
105
  io << ' in defaults' if @event == :found_in_defaults
99
106
  io << "\n"
100
107
  end
108
+ dump_texts(io, indent, @texts)
109
+ end
110
+
111
+ def dump_texts(io, indent, texts)
112
+ texts.each { |text| io << indent << text << "\n" } unless texts.nil?
101
113
  end
102
114
 
103
115
  def dump_value(io, indent, value)
@@ -218,7 +230,7 @@ module Puppet::Pops::Lookup
218
230
  # It's pointless to report a merge where there's only one branch
219
231
  return branches[0].dump_on(io, indent, first_indent) if branches.size == 1
220
232
 
221
- io << first_indent << 'Merge strategy ' << @merge.class.key << "\n"
233
+ io << first_indent << 'Merge strategy ' << @merge.class.key.to_s << "\n"
222
234
  indent = increase_indent(indent)
223
235
  options = options_wo_strategy
224
236
  unless options.nil?
@@ -297,7 +309,7 @@ module Puppet::Pops::Lookup
297
309
  end
298
310
 
299
311
  def dump_on(io, indent, first_indent)
300
- io << first_indent << 'Data Binding "' << @binding_terminus << "\"\n"
312
+ io << first_indent << 'Data Binding "' << @binding_terminus.to_s << "\"\n"
301
313
  indent = increase_indent(indent)
302
314
  branches.each {|b| b.dump_on(io, indent, indent)}
303
315
  dump_outcome(io, indent)
@@ -323,7 +335,7 @@ module Puppet::Pops::Lookup
323
335
  def dump_on(io, indent, first_indent)
324
336
  io << first_indent << 'Data Provider "' << @provider.name << "\"\n"
325
337
  indent = increase_indent(indent)
326
- io << indent << 'ConfigurationPath "' << @provider.config_path << "\"\n" if @provider.respond_to?(:config_path)
338
+ io << indent << 'ConfigurationPath "' << @provider.config_path.to_s << "\"\n" if @provider.respond_to?(:config_path)
327
339
  branches.each {|b| b.dump_on(io, indent, indent)}
328
340
  dump_outcome(io, indent)
329
341
  end
@@ -347,7 +359,7 @@ module Puppet::Pops::Lookup
347
359
  end
348
360
 
349
361
  def dump_on(io, indent, first_indent)
350
- io << indent << 'Path "' << @path.path << "\"\n"
362
+ io << indent << 'Path "' << @path.path.to_s << "\"\n"
351
363
  indent = increase_indent(indent)
352
364
  io << indent << 'Original path: "' << @path.original_path << "\"\n"
353
365
  branches.each {|b| b.dump_on(io, indent, indent)}
@@ -498,6 +510,10 @@ module Puppet::Pops::Lookup
498
510
  @current.result(result)
499
511
  end
500
512
 
513
+ def accept_text(text)
514
+ @current.text(text)
515
+ end
516
+
501
517
  def dump_on(io, indent, first_indent)
502
518
  branches.each { |b| b.dump_on(io, indent, first_indent) }
503
519
  end
@@ -506,4 +522,28 @@ module Puppet::Pops::Lookup
506
522
  branches.size == 1 ? branches[0].to_hash : super
507
523
  end
508
524
  end
525
+
526
+ class DebugExplainer < Explainer
527
+ attr_reader :wrapped_explainer
528
+
529
+ def initialize(wrapped_explainer)
530
+ @wrapped_explainer = wrapped_explainer
531
+ if wrapped_explainer.nil?
532
+ @current = self
533
+ @explain_options = false
534
+ @only_explain_options = false
535
+ else
536
+ @current = wrapped_explainer
537
+ @explain_options = wrapped_explainer.explain_options?
538
+ @only_explain_options = wrapped_explainer.only_explain_options?
539
+ end
540
+ end
541
+
542
+ def emit_debug_info(preamble)
543
+ io = ''
544
+ io << preamble << "\n"
545
+ @current.dump_on(io, ' ', ' ')
546
+ Puppet.debug(io.chomp!)
547
+ end
548
+ end
509
549
  end
@@ -3,6 +3,10 @@ module Puppet::Pops::Lookup
3
3
  attr_reader :scope, :override_values, :default_values, :explainer
4
4
  attr_accessor :module_name, :top_key
5
5
 
6
+ def self.current
7
+ nil # TODO, determine how to obtain the current lookup invocation.
8
+ end
9
+
6
10
  # Creates a context object for a lookup invocation. The object contains the current scope, overrides, and default
7
11
  # values and may optionally contain an {ExplanationAcceptor} instance that will receive book-keeping information
8
12
  # about the progress of the lookup.
@@ -23,6 +27,7 @@ module Puppet::Pops::Lookup
23
27
  unless explainer.is_a?(Explainer)
24
28
  explainer = explainer == true ? Explainer.new : nil
25
29
  end
30
+ explainer = DebugExplainer.new(explainer) if Puppet[:debug] && !explainer.is_a?(DebugExplainer)
26
31
  @explainer = explainer
27
32
  end
28
33
 
@@ -44,6 +49,14 @@ module Puppet::Pops::Lookup
44
49
  end
45
50
  end
46
51
 
52
+ def emit_debug_info(preamble)
53
+ debug_explainer = @explainer
54
+ if debug_explainer.is_a?(DebugExplainer)
55
+ @explainer = debug_explainer.wrapped_explainer
56
+ debug_explainer.emit_debug_info(preamble)
57
+ end
58
+ end
59
+
47
60
  # The qualifier_type can be one of:
48
61
  # :global - qualifier is the data binding terminus name
49
62
  # :data_provider - qualifier a DataProvider instance
@@ -114,6 +127,12 @@ module Puppet::Pops::Lookup
114
127
  def report_module_not_found
115
128
  @explainer.accept_module_not_found unless @explainer.nil?
116
129
  end
130
+
131
+ def report_text(&block)
132
+ unless @explainer.nil?
133
+ @explainer.accept_text(block.call)
134
+ end
135
+ end
117
136
  end
118
137
  end
119
138
 
@@ -9,7 +9,7 @@ module SubLookup
9
9
  # parameter block. The block must return an exception instance.
10
10
  #
11
11
  # @param key [String] the string to split
12
- # @return Array<String> the array of segments
12
+ # @return [Array<String>] the array of segments
13
13
  # @yieldparam problem [String] the problem, i.e. 'Syntax error'
14
14
  # @yieldreturn [Exception] the exception to raise
15
15
  #
@@ -228,10 +228,11 @@ class Factory
228
228
  end
229
229
  end
230
230
 
231
- def build_LambdaExpression(o, parameters, body)
231
+ def build_LambdaExpression(o, parameters, body, return_type)
232
232
  o.parameters = parameters.map {|p| build(p) }
233
233
  b = f_build_body(body)
234
234
  o.body = to_ops(b) if b
235
+ o.return_type = to_ops(return_type) unless return_type.nil?
235
236
  o
236
237
  end
237
238
 
@@ -243,6 +244,15 @@ class Factory
243
244
  o
244
245
  end
245
246
 
247
+ def build_FunctionDefinition(o, name, parameters, body, return_type)
248
+ o.parameters = parameters.map {|p| build(p) }
249
+ b = f_build_body(body)
250
+ o.body = b.current if b
251
+ o.name = name
252
+ o.return_type = to_ops(return_type) unless return_type.nil?
253
+ o
254
+ end
255
+
246
256
  def build_CapabilityMapping(o, kind, component, capability, mappings)
247
257
  o.kind = kind
248
258
  component = component.current if component.instance_of?(Factory)
@@ -690,7 +700,7 @@ class Factory
690
700
  params = parameters
691
701
  parameters_specified = true
692
702
  end
693
- LAMBDA(params, new(EppExpression, parameters_specified, body))
703
+ LAMBDA(params, new(EppExpression, parameters_specified, body), nil)
694
704
  end
695
705
 
696
706
  def self.RESERVED(name, future=false)
@@ -817,12 +827,12 @@ class Factory
817
827
  new(Application, name, parameters, body)
818
828
  end
819
829
 
820
- def self.FUNCTION(name, parameters, body)
821
- new(FunctionDefinition, name, parameters, body)
830
+ def self.FUNCTION(name, parameters, body, return_type)
831
+ new(FunctionDefinition, name, parameters, body, return_type)
822
832
  end
823
833
 
824
- def self.LAMBDA(parameters, body)
825
- new(LambdaExpression, parameters, body)
834
+ def self.LAMBDA(parameters, body, return_type)
835
+ new(LambdaExpression, parameters, body, return_type)
826
836
  end
827
837
 
828
838
  def self.TYPE_ASSIGNMENT(lhs, rhs)
@@ -855,7 +865,10 @@ class Factory
855
865
  'err' => true,
856
866
 
857
867
  'fail' => true,
858
- 'import' => true # discontinued, but transform it to make it call error reporting function
868
+ 'import' => true, # discontinued, but transform it to make it call error reporting function
869
+ 'break' => true,
870
+ 'next' => true,
871
+ 'return' => true
859
872
  }
860
873
  # Returns true if the given name is a "statement keyword" (require, include, contain,
861
874
  # error, notice, info, debug
@@ -1136,4 +1149,3 @@ class Factory
1136
1149
  end
1137
1150
  end
1138
1151
  end
1139
-