puppet 4.0.0 → 4.1.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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -607,12 +607,17 @@ class Puppet::Parser::Scope
607
607
  raise Puppet::ParseError, "Attempt to assign to a reserved variable name: '#{name}'"
608
608
  end
609
609
 
610
+ # Check for server_facts reserved variable name if the trusted_sever_facts setting is true
611
+ if Puppet[:trusted_server_facts] && name == 'server_facts' && !options[:privileged]
612
+ raise Puppet::ParseError, "Attempt to assign to a reserved variable name: '#{name}'"
613
+ end
614
+
610
615
  table = effective_symtable(options[:ephemeral])
611
616
  if table.bound?(name)
612
617
  if options[:append]
613
- error = Puppet::ParseError.new("Cannot append, variable #{name} is defined in this scope")
618
+ error = Puppet::ParseError.new("Cannot append, variable '$#{name}' is defined in this scope")
614
619
  else
615
- error = Puppet::ParseError.new("Cannot reassign variable #{name}")
620
+ error = Puppet::ParseError.new("Cannot reassign variable '$#{name}'")
616
621
  end
617
622
  error.file = options[:file] if options[:file]
618
623
  error.line = options[:line] if options[:line]
@@ -636,6 +641,10 @@ class Puppet::Parser::Scope
636
641
  setvar('facts', deep_freeze(hash), :privileged => true)
637
642
  end
638
643
 
644
+ def set_server_facts(hash)
645
+ setvar('server_facts', deep_freeze(hash), :privileged => true)
646
+ end
647
+
639
648
  # Deeply freezes the given object. The object and its content must be of the types:
640
649
  # Array, Hash, Numeric, Boolean, Symbol, Regexp, NilClass, or String. All other types raises an Error.
641
650
  # (i.e. if they are assignable to Puppet::Pops::Types::Data type).
@@ -1,5 +1,6 @@
1
1
  require 'puppet/parser/files'
2
2
  require 'erb'
3
+ require 'puppet/file_system'
3
4
 
4
5
  # A simple wrapper for templates, so they don't have full access to
5
6
  # the scope objects.
@@ -70,7 +71,7 @@ class Puppet::Parser::TemplateWrapper
70
71
  if string
71
72
  template_source = "inline template"
72
73
  else
73
- string = File.read(@__file__)
74
+ string = Puppet::FileSystem.read_preserve_line_endings(@__file__)
74
75
  template_source = @__file__
75
76
  end
76
77
 
@@ -122,6 +122,10 @@ module Puppet
122
122
  require 'puppet/pops/functions/dispatch'
123
123
  require 'puppet/pops/functions/dispatcher'
124
124
  end
125
+
126
+ module Migration
127
+ require 'puppet/pops/migration/migration_checker'
128
+ end
125
129
  end
126
130
 
127
131
  require 'puppet/parser/ast/pops_bridge'
@@ -251,17 +251,37 @@ class Puppet::Pops::Evaluator::AccessOperator
251
251
  def access_POptionalType(o, scope, keys)
252
252
  keys.flatten!
253
253
  if keys.size == 1
254
- unless keys[0].is_a?(Puppet::Pops::Types::PAnyType)
255
- fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Optional-Type', :actual => keys[0].class})
254
+ type = keys[0]
255
+ unless type.is_a?(Puppet::Pops::Types::PAnyType) || type.is_a?(String)
256
+ fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Optional-Type', :actual => type.class})
256
257
  end
257
- result = Puppet::Pops::Types::POptionalType.new()
258
- result.optional_type = keys[0]
259
- result
258
+ TYPEFACTORY.optional(type)
260
259
  else
261
260
  fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Optional-Type', :min => 1, :actual => keys.size})
262
261
  end
263
262
  end
264
263
 
264
+ def access_PNotUndefType(o, scope, keys)
265
+ keys.flatten!
266
+ case keys.size
267
+ when 0
268
+ TYPEFACTORY.not_undef
269
+ when 1
270
+ type = keys[0]
271
+ case type
272
+ when String
273
+ type = TYPEFACTORY.string(type)
274
+ when Puppet::Pops::Types::PAnyType
275
+ type = nil if type.class == Puppet::Pops::Types::PAnyType
276
+ else
277
+ fail(Puppet::Pops::Issues::BAD_NOT_UNDEF_SLICE_TYPE, @semantic.keys[0], {:base_type => 'NotUndef-Type', :actual => type.class})
278
+ end
279
+ TYPEFACTORY.not_undef(type)
280
+ else
281
+ fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'NotUndef-Type', :min => 0, :max => 1, :actual => keys.size})
282
+ end
283
+ end
284
+
265
285
  def access_PType(o, scope, keys)
266
286
  keys.flatten!
267
287
  if keys.size == 1
@@ -39,10 +39,18 @@ class Puppet::Pops::Evaluator::Closure < Puppet::Pops::Evaluator::CallableSignat
39
39
  if tc.callable?(type, final_args)
40
40
  @evaluator.evaluate_block_with_bindings(@enclosing_scope, variable_bindings, @model.body)
41
41
  else
42
- raise ArgumentError, "lambda called with mis-matched arguments\n#{Puppet::Pops::Evaluator::CallableMismatchDescriber.diff_string('lambda', final_args, [self])}"
42
+ raise ArgumentError, "#{closure_name} called with mis-matched arguments\n#{Puppet::Pops::Evaluator::CallableMismatchDescriber.diff_string(closure_name, final_args, [self])}"
43
43
  end
44
44
  end
45
45
 
46
+ # This method makes a Closure compatible with a Dispatch. This is used when the closure is wrapped in a Function
47
+ # and the function is called. (Saves an extra Dispatch that just delegates to a Closure and avoids having two
48
+ # checks of the argument type/arity validity).
49
+ # @api private
50
+ def invoke(instance, calling_scope, args, &block)
51
+ call(*args, &block)
52
+ end
53
+
46
54
  # Call closure with argument assignment by name
47
55
  def call_by_name(args_hash, enforce_parameters)
48
56
  if enforce_parameters
@@ -73,7 +81,7 @@ class Puppet::Pops::Evaluator::Closure < Puppet::Pops::Evaluator::CallableSignat
73
81
  tc = Puppet::Pops::Types::TypeCalculator
74
82
  final_args = tc.infer_set(parameter_names.collect { |param| scope_hash[param] })
75
83
  if !tc.callable?(type, final_args)
76
- raise ArgumentError, "lambda called with mis-matched arguments\n#{Puppet::Pops::Evaluator::CallableMismatchDescriber.diff_string('lambda', final_args, [self])}"
84
+ raise ArgumentError, "#{closure_name} called with mis-matched arguments\n#{Puppet::Pops::Evaluator::CallableMismatchDescriber.diff_string(closure_name, final_args, [self])}"
77
85
  end
78
86
  else
79
87
  scope_hash = args_hash
@@ -115,6 +123,24 @@ class Puppet::Pops::Evaluator::Closure < Puppet::Pops::Evaluator::CallableSignat
115
123
  'unsupported_block'
116
124
  end
117
125
 
126
+ CLOSURE_NAME = 'lambda'.freeze
127
+
128
+ # @api public
129
+ def closure_name()
130
+ CLOSURE_NAME
131
+ end
132
+
133
+ class Named < Puppet::Pops::Evaluator::Closure
134
+ def initialize(name, evaluator, model, scope)
135
+ @name = name
136
+ super(evaluator, model, scope)
137
+ end
138
+
139
+ def closure_name
140
+ @name
141
+ end
142
+ end
143
+
118
144
  private
119
145
 
120
146
  def combine_values_with_parameters(args)
@@ -27,7 +27,7 @@ class Puppet::Pops::Evaluator::CollectorTransformer
27
27
 
28
28
  if !o.operations.empty?
29
29
  overrides = {
30
- :parameters => o.operations.map{ |x| to_3x_param(x).evaluate(scope)},
30
+ :parameters => o.operations.map{ |x| @@evaluator.evaluate(x, scope)}.flatten,
31
31
  :file => file_path,
32
32
  :line => [line_num, position],
33
33
  :source => scope.source,
@@ -206,14 +206,4 @@ protected
206
206
  def match_Object(o, scope)
207
207
  raise ArgumentError, "Cannot transform object of class #{o.class}"
208
208
  end
209
-
210
- # Produces (name => expr) or (name +> expr)
211
- def to_3x_param(o)
212
- bridge = Puppet::Parser::AST::PopsBridge::Expression.new(:value => o.value_expr)
213
- args = { :value => bridge }
214
- args[:add] = true if o.operator == :'+>'
215
- args[:param] = o.attribute_name
216
- args= Puppet::Pops::Model::AstTransformer.new().merge_location(args, o)
217
- Puppet::Parser::AST::ResourceParam.new(args)
218
- end
219
209
  end
@@ -22,4 +22,8 @@ class Puppet::Pops::Evaluator::Collectors::CatalogCollector < Puppet::Pops::Eval
22
22
  resource.type == t && (q ? q.call(resource) : true)
23
23
  end
24
24
  end
25
+
26
+ def to_s
27
+ "Catalog-Collector[#{@type.to_s}]"
28
+ end
25
29
  end
@@ -63,4 +63,8 @@ class Puppet::Pops::Evaluator::Collectors::ExportedCollector < Puppet::Pops::Eva
63
63
 
64
64
  resources
65
65
  end
66
+
67
+ def to_s
68
+ "Exported-Collector[#{@type.to_s}]"
69
+ end
66
70
  end
@@ -17,6 +17,7 @@ class Puppet::Pops::Evaluator::CompareOperator
17
17
  def initialize
18
18
  @@equals_visitor ||= Puppet::Pops::Visitor.new(self, "equals", 1, 1)
19
19
  @@compare_visitor ||= Puppet::Pops::Visitor.new(self, "cmp", 1, 1)
20
+ @@match_visitor ||= Puppet::Pops::Visitor.new(self, "match", 2, 2)
20
21
  @@include_visitor ||= Puppet::Pops::Visitor.new(self, "include", 2, 2)
21
22
  @type_calculator = Puppet::Pops::Types::TypeCalculator.new()
22
23
  end
@@ -31,6 +32,11 @@ class Puppet::Pops::Evaluator::CompareOperator
31
32
  @@compare_visitor.visit_this_1(self, a, b)
32
33
  end
33
34
 
35
+ # Performs a match of a and b, and returns true if b matches a
36
+ def match(a, b, scope)
37
+ @@match_visitor.visit_this_2(self, b, a, scope)
38
+ end
39
+
34
40
  # Answers is b included in a
35
41
  def include?(a, b, scope)
36
42
  @@include_visitor.visit_this_2(self, a, b, scope)
@@ -149,4 +155,41 @@ class Puppet::Pops::Evaluator::CompareOperator
149
155
  def include_Hash(a, b, scope)
150
156
  include?(a.keys, b, scope)
151
157
  end
158
+
159
+ # Matches in general by using == operator
160
+ def match_Object(pattern, a, scope)
161
+ equals(a, pattern)
162
+ end
163
+
164
+ # Matches only against strings
165
+ def match_Regexp(regexp, left, scope)
166
+ return false unless left.is_a? String
167
+ matched = regexp.match(left)
168
+ set_match_data(matched, scope) # creates or clears ephemeral
169
+ !!matched # convert to boolean
170
+ end
171
+
172
+ def match_PAnyType(any_type, left, scope)
173
+ # right is a type and left is not - check if left is an instance of the given type
174
+ # (The reverse is not terribly meaningful - computing which of the case options that first produces
175
+ # an instance of a given type).
176
+ #
177
+ @type_calculator.instance?(any_type, left)
178
+ end
179
+
180
+ def match_Array(array, left, scope)
181
+ return false unless left.is_a?(Array)
182
+ return false unless left.length == array.length
183
+ array.each_with_index.all? { | pattern, index| match(left[index], pattern, scope) }
184
+ end
185
+
186
+ def match_Hash(hash, left, scope)
187
+ return false unless left.is_a?(Hash)
188
+ hash.all? {|x,y| match(left[x], y, scope) }
189
+ end
190
+
191
+ def match_Symbol(symbol, left, scope)
192
+ return true if symbol == :default
193
+ equals(left, default, scope)
194
+ end
152
195
  end
@@ -24,10 +24,15 @@ class Puppet::Pops::Evaluator::EppEvaluator
24
24
  raise ArgumentError, "epp(): the first argument must be a String with the filename, got a #{file.class}"
25
25
  end
26
26
 
27
- file = file + ".epp" unless file =~ /\.epp$/
27
+ unless Puppet::FileSystem.exist?(file)
28
+ unless file =~ /\.epp$/
29
+ file = file + ".epp"
30
+ end
31
+ end
32
+
28
33
  scope.debug "Retrieving epp template #{file}"
29
34
  template_file = Puppet::Parser::Files.find_template(file, env_name)
30
- unless template_file
35
+ if template_file.nil? || !Puppet::FileSystem.exist?(template_file)
31
36
  raise Puppet::ParseError, "Could not find template '#{file}'"
32
37
  end
33
38
 
@@ -49,6 +49,9 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
49
49
 
50
50
  @@compare_operator ||= Puppet::Pops::Evaluator::CompareOperator.new()
51
51
  @@relationship_operator ||= Puppet::Pops::Evaluator::RelationshipOperator.new()
52
+
53
+ # Use null migration checker unless given in context
54
+ @migration_checker = (Puppet.lookup(:migration_checker) { Puppet::Pops::Migration::MigrationChecker.new() })
52
55
  end
53
56
 
54
57
  # @api private
@@ -176,6 +179,11 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
176
179
  fail(Issues::ILLEGAL_ASSIGNMENT, o)
177
180
  end
178
181
 
182
+ # An array is assignable if all entries are lvalues
183
+ def lvalue_LiteralList(o, scope)
184
+ o.values.map {|x| lvalue(x, scope) }
185
+ end
186
+
179
187
  # Assign value to named variable.
180
188
  # The '$' sign is never part of the name.
181
189
  # @example In Puppet DSL
@@ -204,6 +212,22 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
204
212
  fail(Issues::ILLEGAL_ASSIGNMENT, o)
205
213
  end
206
214
 
215
+ def assign_Array(lvalues, values, o, scope)
216
+ if values.is_a?(Hash)
217
+ lvalues.map do |lval|
218
+ assign(lval,
219
+ values.fetch(lval) {|k| fail(Issues::MISSING_MULTI_ASSIGNMENT_KEY, o, :key =>k)},
220
+ o, scope)
221
+ end
222
+ else
223
+ values = [values] unless values.is_a?(Array)
224
+ if values.size != lvalues.size
225
+ fail(Issues::ILLEGAL_MULTI_ASSIGNMENT_SIZE, o, :expected =>lvalues.size, :actual => values.size)
226
+ end
227
+ lvalues.zip(values).map { |lval, val| assign(lval, val, o, scope) }
228
+ end
229
+ end
230
+
207
231
  def eval_Factory(o, scope)
208
232
  evaluate(o.current, scope)
209
233
  end
@@ -250,7 +274,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
250
274
  end
251
275
 
252
276
  def eval_NotExpression(o, scope)
253
- ! is_true?(evaluate(o.expr, scope))
277
+ ! is_true?(evaluate(o.expr, scope), o.expr)
254
278
  end
255
279
 
256
280
  def eval_UnaryMinusExpression(o, scope)
@@ -511,7 +535,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
511
535
  # b is only evaluated if a is true
512
536
  #
513
537
  def eval_AndExpression o, scope
514
- is_true?(evaluate(o.left_expr, scope)) ? is_true?(evaluate(o.right_expr, scope)) : false
538
+ is_true?(evaluate(o.left_expr, scope), o.left_expr) ? is_true?(evaluate(o.right_expr, scope), o.right_expr) : false
515
539
  end
516
540
 
517
541
  # @example
@@ -519,7 +543,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
519
543
  # b is only evaluated if a is false
520
544
  #
521
545
  def eval_OrExpression o, scope
522
- is_true?(evaluate(o.left_expr, scope)) ? true : is_true?(evaluate(o.right_expr, scope))
546
+ is_true?(evaluate(o.left_expr, scope), o.left_expr) ? true : is_true?(evaluate(o.right_expr, scope), o.right_expr)
523
547
  end
524
548
 
525
549
  # Evaluates each entry of the literal list and creates a new Array
@@ -558,21 +582,23 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
558
582
  #
559
583
  with_guarded_scope(scope) do
560
584
  test = evaluate(o.test, scope)
585
+
561
586
  result = nil
562
587
  the_default = nil
563
588
  if o.options.find do |co|
564
589
  # the first case option that matches
565
590
  if co.values.find do |c|
591
+ c = unwind_parentheses(c)
566
592
  case c
567
593
  when Puppet::Pops::Model::LiteralDefault
568
594
  the_default = co.then_expr
569
- is_match?(test, evaluate(c, scope), c, scope)
595
+ next false
570
596
  when Puppet::Pops::Model::UnfoldExpression
571
597
  # not ideal for error reporting, since it is not known which unfolded result
572
598
  # that caused an error - the entire unfold expression is blamed (i.e. the var c, passed to is_match?)
573
- evaluate(c, scope).any? {|v| is_match?(test, v, c, scope) }
599
+ evaluate(c, scope).any? {|v| is_match?(test, v, c, co, scope) }
574
600
  else
575
- is_match?(test, evaluate(c, scope), c, scope)
601
+ is_match?(test, evaluate(c, scope), c, co, scope)
576
602
  end
577
603
  end
578
604
  result = evaluate(co.then_expr, scope)
@@ -796,13 +822,13 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
796
822
  unless o.functor_expr.is_a? Puppet::Pops::Model::NamedAccessExpression
797
823
  fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function accessor', :container => o})
798
824
  end
799
- receiver = evaluate(o.functor_expr.left_expr, scope)
825
+ receiver = unfold([], [o.functor_expr.left_expr], scope)
800
826
  name = o.functor_expr.right_expr
801
827
  unless name.is_a? Puppet::Pops::Model::QualifiedName
802
828
  fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o})
803
829
  end
804
830
  name = name.value # the string function name
805
- call_function_with_block(name, unfold([receiver], o.arguments || [], scope), o, scope)
831
+ call_function_with_block(name, unfold(receiver, o.arguments || [], scope), o, scope)
806
832
  end
807
833
 
808
834
  def call_function_with_block(name, evaluated_arguments, o, scope)
@@ -824,9 +850,10 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
824
850
  #
825
851
  with_guarded_scope(scope) do
826
852
  test = evaluate(o.left_expr, scope)
853
+
827
854
  the_default = nil
828
855
  selected = o.selectors.find do |s|
829
- me = s.matching_expr
856
+ me = unwind_parentheses(s.matching_expr)
830
857
  case me
831
858
  when Puppet::Pops::Model::LiteralDefault
832
859
  the_default = s.value_expr
@@ -834,9 +861,9 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
834
861
  when Puppet::Pops::Model::UnfoldExpression
835
862
  # not ideal for error reporting, since it is not known which unfolded result
836
863
  # that caused an error - the entire unfold expression is blamed (i.e. the var c, passed to is_match?)
837
- evaluate(me, scope).any? {|v| is_match?(test, v, me, scope) }
864
+ evaluate(me, scope).any? {|v| is_match?(test, v, me, s, scope) }
838
865
  else
839
- is_match?(test, evaluate(me, scope), me, scope)
866
+ is_match?(test, evaluate(me, scope), me, s, scope)
840
867
  end
841
868
  end
842
869
  if selected
@@ -864,7 +891,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
864
891
  # Evaluates Puppet DSL `if`
865
892
  def eval_IfExpression o, scope
866
893
  with_guarded_scope(scope) do
867
- if is_true?(evaluate(o.test, scope))
894
+ if is_true?(evaluate(o.test, scope), o.test)
868
895
  evaluate(o.then_expr, scope)
869
896
  else
870
897
  evaluate(o.else_expr, scope)
@@ -875,7 +902,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
875
902
  # Evaluates Puppet DSL `unless`
876
903
  def eval_UnlessExpression o, scope
877
904
  with_guarded_scope(scope) do
878
- unless is_true?(evaluate(o.test, scope))
905
+ unless is_true?(evaluate(o.test, scope), o.test)
879
906
  evaluate(o.then_expr, scope)
880
907
  else
881
908
  evaluate(o.else_expr, scope)
@@ -1076,7 +1103,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
1076
1103
  # This is the type of matching performed in a case option, using == for every type
1077
1104
  # of value except regular expression where a match is performed.
1078
1105
  #
1079
- def is_match? left, right, o, scope
1106
+ def is_match?(left, right, o, option_expr, scope)
1080
1107
  if right.is_a?(Regexp)
1081
1108
  return false unless left.is_a? String
1082
1109
  matched = right.match(left)
@@ -1092,6 +1119,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
1092
1119
  # Handle equality the same way as the language '==' operator (case insensitive etc.)
1093
1120
  @@compare_operator.equals(left,right)
1094
1121
  end
1122
+ @@compare_operator.match(left, right, scope)
1095
1123
  end
1096
1124
 
1097
1125
  def with_guarded_scope(scope)
@@ -1112,6 +1140,7 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
1112
1140
  #
1113
1141
  def unfold(result, array, scope)
1114
1142
  array.each do |x|
1143
+ x = unwind_parentheses(x)
1115
1144
  if x.is_a?(Puppet::Pops::Model::UnfoldExpression)
1116
1145
  result.concat(evaluate(x, scope))
1117
1146
  else
@@ -1122,4 +1151,9 @@ class Puppet::Pops::Evaluator::EvaluatorImpl
1122
1151
  end
1123
1152
  private :unfold
1124
1153
 
1154
+ def unwind_parentheses(o)
1155
+ return o unless o.is_a?(Puppet::Pops::Model::ParenthesizedExpression)
1156
+ unwind_parentheses(o.expr)
1157
+ end
1158
+ private :unwind_parentheses
1125
1159
  end