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.
- checksums.yaml +4 -4
- data/ext/build_defaults.yaml +8 -35
- data/ext/debian/puppet.default +0 -5
- data/ext/debian/puppet.init +1 -15
- data/lib/hiera/puppet_function.rb +15 -4
- data/lib/puppet/application/agent.rb +5 -0
- data/lib/puppet/application/apply.rb +23 -2
- data/lib/puppet/application/device.rb +8 -3
- data/lib/puppet/application/master.rb +16 -5
- data/lib/puppet/configurer.rb +7 -5
- data/lib/puppet/defaults.rb +18 -0
- data/lib/puppet/environments.rb +1 -1
- data/lib/puppet/error.rb +27 -1
- data/lib/puppet/file_serving/metadata.rb +13 -8
- data/lib/puppet/file_serving/terminus_helper.rb +7 -8
- data/lib/puppet/file_system.rb +13 -0
- data/lib/puppet/file_system/file_impl.rb +4 -0
- data/lib/puppet/file_system/memory_impl.rb +4 -0
- data/lib/puppet/file_system/windows.rb +8 -0
- data/lib/puppet/functions.rb +33 -3
- data/lib/puppet/functions/defined.rb +130 -0
- data/lib/puppet/functions/regsubst.rb +1 -1
- data/lib/puppet/functions/split.rb +1 -1
- data/lib/puppet/indirector/catalog/compiler.rb +1 -1
- data/lib/puppet/indirector/facts/facter.rb +11 -0
- data/lib/puppet/loaders.rb +1 -0
- data/lib/puppet/node.rb +17 -1
- data/lib/puppet/node/environment.rb +4 -0
- data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
- data/lib/puppet/parser/compiler.rb +9 -0
- data/lib/puppet/parser/functions/defined.rb +25 -1
- data/lib/puppet/parser/functions/file.rb +3 -1
- data/lib/puppet/parser/scope.rb +11 -2
- data/lib/puppet/parser/templatewrapper.rb +2 -1
- data/lib/puppet/pops.rb +4 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
- data/lib/puppet/pops/evaluator/closure.rb +28 -2
- data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
- data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
- data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
- data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
- data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
- data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
- data/lib/puppet/pops/functions/dispatch.rb +6 -1
- data/lib/puppet/pops/functions/dispatcher.rb +7 -1
- data/lib/puppet/pops/issue_reporter.rb +42 -16
- data/lib/puppet/pops/issues.rb +116 -2
- data/lib/puppet/pops/loader/loader.rb +11 -0
- data/lib/puppet/pops/loader/loader_paths.rb +67 -6
- data/lib/puppet/pops/loader/module_loaders.rb +19 -8
- data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
- data/lib/puppet/pops/loaders.rb +6 -4
- data/lib/puppet/pops/migration/migration_checker.rb +54 -0
- data/lib/puppet/pops/model/factory.rb +5 -1
- data/lib/puppet/pops/model/model_label_provider.rb +2 -0
- data/lib/puppet/pops/model/model_meta.rb +5 -1
- data/lib/puppet/pops/parser/egrammar.ra +9 -10
- data/lib/puppet/pops/parser/eparser.rb +1061 -1047
- data/lib/puppet/pops/parser/epp_support.rb +18 -9
- data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
- data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
- data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
- data/lib/puppet/pops/parser/lexer2.rb +29 -12
- data/lib/puppet/pops/parser/lexer_support.rb +52 -23
- data/lib/puppet/pops/parser/parser_support.rb +11 -14
- data/lib/puppet/pops/parser/slurp_support.rb +22 -6
- data/lib/puppet/pops/types/type_calculator.rb +156 -55
- data/lib/puppet/pops/types/type_factory.rb +66 -13
- data/lib/puppet/pops/types/type_parser.rb +22 -13
- data/lib/puppet/pops/types/types.rb +23 -4
- data/lib/puppet/pops/types/types_meta.rb +13 -2
- data/lib/puppet/pops/validation.rb +25 -2
- data/lib/puppet/pops/validation/checker4_0.rb +63 -31
- data/lib/puppet/provider/group/windows_adsi.rb +8 -4
- data/lib/puppet/provider/mount/parsed.rb +145 -2
- data/lib/puppet/provider/package/apt.rb +1 -1
- data/lib/puppet/provider/package/pip.rb +11 -2
- data/lib/puppet/provider/package/pkgng.rb +134 -0
- data/lib/puppet/provider/package/portage.rb +1 -1
- data/lib/puppet/provider/package/ports.rb +0 -3
- data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
- data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
- data/lib/puppet/provider/package/zypper.rb +50 -15
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
- data/lib/puppet/provider/service/debian.rb +1 -1
- data/lib/puppet/provider/service/init.rb +7 -0
- data/lib/puppet/provider/user/openbsd.rb +1 -0
- data/lib/puppet/provider/user/windows_adsi.rb +45 -2
- data/lib/puppet/reference/indirection.rb +1 -1
- data/lib/puppet/resource.rb +1 -1
- data/lib/puppet/resource/catalog.rb +0 -4
- data/lib/puppet/settings.rb +19 -0
- data/lib/puppet/type/file.rb +1 -0
- data/lib/puppet/type/file/ensure.rb +1 -1
- data/lib/puppet/type/mount.rb +9 -1
- data/lib/puppet/type/scheduled_task.rb +13 -0
- data/lib/puppet/type/tidy.rb +3 -1
- data/lib/puppet/type/user.rb +32 -0
- data/lib/puppet/type/yumrepo.rb +5 -5
- data/lib/puppet/util/log.rb +50 -8
- data/lib/puppet/util/log/destinations.rb +23 -2
- data/lib/puppet/util/logging.rb +37 -1
- data/lib/puppet/util/run_mode.rb +1 -14
- data/lib/puppet/util/windows/adsi.rb +130 -58
- data/lib/puppet/version.rb +1 -1
- data/man/man5/puppet.conf.5 +48 -6
- data/man/man8/extlookup2hiera.8 +1 -1
- data/man/man8/puppet-agent.8 +4 -1
- data/man/man8/puppet-apply.8 +4 -1
- data/man/man8/puppet-ca.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-cert.8 +1 -1
- data/man/man8/puppet-certificate.8 +1 -1
- data/man/man8/puppet-certificate_request.8 +1 -1
- data/man/man8/puppet-certificate_revocation_list.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +6 -3
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-file.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-inspect.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-master.8 +4 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-resource_type.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +1 -1
- data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
- data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
- data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
- data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
- data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
- data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
- data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
- data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
- data/spec/integration/application/apply_spec.rb +49 -0
- data/spec/integration/faces/plugin_spec.rb +0 -4
- data/spec/integration/indirector/facts/facter_spec.rb +59 -0
- data/spec/integration/parser/compiler_spec.rb +850 -0
- data/spec/integration/parser/resource_expressions_spec.rb +3 -0
- data/spec/integration/parser/scope_spec.rb +26 -5
- data/spec/integration/transaction_spec.rb +1 -1
- data/spec/integration/type/file_spec.rb +318 -41
- data/spec/integration/util/windows/security_spec.rb +14 -5
- data/spec/lib/matchers/resource.rb +22 -1
- data/spec/lib/puppet_spec/matchers.rb +6 -4
- data/spec/unit/application/master_spec.rb +33 -7
- data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
- data/spec/unit/file_serving/metadata_spec.rb +1 -1
- data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
- data/spec/unit/file_system_spec.rb +38 -0
- data/spec/unit/functions/defined_spec.rb +289 -0
- data/spec/unit/functions/hiera_spec.rb +8 -6
- data/spec/unit/functions/regsubst_spec.rb +4 -0
- data/spec/unit/functions/split_spec.rb +8 -0
- data/spec/unit/functions4_spec.rb +97 -2
- data/spec/unit/indirector/facts/facter_spec.rb +7 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/parser/functions/file_spec.rb +7 -1
- data/spec/unit/parser/functions/template_spec.rb +1 -1
- data/spec/unit/parser/scope_spec.rb +2 -2
- data/spec/unit/parser/templatewrapper_spec.rb +1 -1
- data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
- data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
- data/spec/unit/pops/issues_spec.rb +16 -16
- data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
- data/spec/unit/pops/migration_spec.rb +53 -0
- data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
- data/spec/unit/pops/validation_spec.rb +66 -0
- data/spec/unit/pops/validator/validator_spec.rb +1 -1
- data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
- data/spec/unit/provider/mount/parsed_spec.rb +31 -5
- data/spec/unit/provider/package/apt_spec.rb +5 -0
- data/spec/unit/provider/package/pip_spec.rb +9 -0
- data/spec/unit/provider/package/pkgng_spec.rb +172 -0
- data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
- data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
- data/spec/unit/provider/package/zypper_spec.rb +50 -19
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
- data/spec/unit/provider/service/base_spec.rb +38 -27
- data/spec/unit/provider/service/debian_spec.rb +8 -0
- data/spec/unit/provider/service/freebsd_spec.rb +1 -0
- data/spec/unit/provider/service/gentoo_spec.rb +1 -0
- data/spec/unit/provider/service/init_spec.rb +18 -0
- data/spec/unit/provider/service/openbsd_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +1 -0
- data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
- data/spec/unit/settings_spec.rb +11 -0
- data/spec/unit/util/log_spec.rb +113 -0
- data/spec/unit/util/windows/adsi_spec.rb +135 -41
- data/spec/unit/util/windows/sid_spec.rb +0 -10
- metadata +48 -2
data/lib/puppet/parser/scope.rb
CHANGED
@@ -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
|
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
|
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 =
|
74
|
+
string = Puppet::FileSystem.read_preserve_line_endings(@__file__)
|
74
75
|
template_source = @__file__
|
75
76
|
end
|
76
77
|
|
data/lib/puppet/pops.rb
CHANGED
@@ -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
|
-
|
255
|
-
|
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
|
-
|
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, "
|
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, "
|
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|
|
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
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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(
|
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?
|
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
|