puppet 3.4.3 → 3.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CONTRIBUTING.md +6 -6
- data/Gemfile +22 -16
- data/LICENSE +1 -1
- data/README.md +33 -11
- data/Rakefile +1 -1
- data/conf/auth.conf +4 -0
- data/ext/build_defaults.yaml +1 -1
- data/ext/debian/control +6 -6
- data/ext/ips/transforms +1 -1
- data/ext/nagios/naggen +1 -1
- data/ext/project_data.yaml +21 -1
- data/ext/puppet-test +3 -3
- data/ext/redhat/puppet.spec.erb +28 -2
- data/ext/suse/puppet.spec +1 -1
- data/ext/upload_facts.rb +1 -1
- data/ext/windows/service/daemon.rb +99 -20
- data/lib/hiera_puppet.rb +2 -2
- data/lib/puppet.rb +68 -5
- data/lib/puppet/agent.rb +5 -1
- data/lib/puppet/application.rb +20 -11
- data/lib/puppet/application/agent.rb +1 -1
- data/lib/puppet/application/apply.rb +61 -41
- data/lib/puppet/application/cert.rb +3 -3
- data/lib/puppet/application/device.rb +7 -8
- data/lib/puppet/application/doc.rb +1 -1
- data/lib/puppet/application/filebucket.rb +3 -3
- data/lib/puppet/application/kick.rb +2 -2
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/application/queue.rb +9 -9
- data/lib/puppet/application/resource.rb +2 -2
- data/lib/puppet/bindings.rb +6 -6
- data/lib/puppet/configurer.rb +17 -14
- data/lib/puppet/configurer/fact_handler.rb +1 -1
- data/lib/puppet/confine/any.rb +26 -0
- data/lib/puppet/confine/exists.rb +1 -1
- data/lib/puppet/confiner.rb +1 -0
- data/lib/puppet/context.rb +55 -0
- data/lib/puppet/context/trusted_information.rb +56 -0
- data/lib/puppet/defaults.rb +97 -26
- data/lib/puppet/environments.rb +187 -0
- data/lib/puppet/error.rb +2 -1
- data/lib/puppet/external/pson/common.rb +1 -1
- data/lib/puppet/external/pson/pure/generator.rb +1 -1
- data/lib/puppet/external/pson/pure/parser.rb +1 -1
- data/lib/puppet/face/config.rb +73 -15
- data/lib/puppet/face/file/store.rb +1 -1
- data/lib/puppet/face/help.rb +2 -1
- data/lib/puppet/face/help/action.erb +1 -0
- data/lib/puppet/face/help/face.erb +1 -0
- data/lib/puppet/face/help/global.erb +1 -0
- data/lib/puppet/face/help/man.erb +9 -8
- data/lib/puppet/face/module/list.rb +13 -7
- data/lib/puppet/face/node/clean.rb +2 -2
- data/lib/puppet/face/parser.rb +11 -5
- data/lib/puppet/face/status.rb +1 -1
- data/lib/puppet/feature/external_facts.rb +2 -2
- data/lib/puppet/feature/libuser.rb +1 -1
- data/lib/puppet/feature/msgpack.rb +2 -0
- data/lib/puppet/feature/rails.rb +2 -2
- data/lib/puppet/file_bucket/dipper.rb +9 -9
- data/lib/puppet/file_bucket/file.rb +9 -5
- data/lib/puppet/file_serving/base.rb +1 -1
- data/lib/puppet/file_serving/configuration.rb +1 -1
- data/lib/puppet/file_serving/configuration/parser.rb +3 -3
- data/lib/puppet/file_serving/content.rb +2 -2
- data/lib/puppet/file_serving/fileset.rb +4 -4
- data/lib/puppet/file_serving/metadata.rb +69 -15
- data/lib/puppet/file_serving/mount/file.rb +1 -1
- data/lib/puppet/file_system.rb +361 -1
- data/lib/puppet/file_system/file18.rb +3 -3
- data/lib/puppet/file_system/file19.rb +3 -3
- data/lib/puppet/file_system/file19windows.rb +18 -23
- data/lib/puppet/file_system/file_impl.rb +145 -0
- data/lib/puppet/file_system/memory_file.rb +23 -9
- data/lib/puppet/file_system/memory_impl.rb +64 -0
- data/lib/puppet/forge.rb +4 -3
- data/lib/puppet/forge/repository.rb +0 -1
- data/lib/puppet/graph/relationship_graph.rb +7 -7
- data/lib/puppet/indirector.rb +1 -0
- data/lib/puppet/indirector/catalog/compiler.rb +3 -30
- data/lib/puppet/indirector/catalog/msgpack.rb +6 -0
- data/lib/puppet/indirector/catalog/static_compiler.rb +3 -7
- data/lib/puppet/indirector/data_binding/hiera.rb +1 -1
- data/lib/puppet/indirector/direct_file_server.rb +2 -2
- data/lib/puppet/indirector/exec.rb +1 -1
- data/lib/puppet/indirector/face.rb +3 -2
- data/lib/puppet/indirector/facts/facter.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +25 -15
- data/lib/puppet/indirector/file_metadata/file.rb +1 -1
- data/lib/puppet/indirector/file_server.rb +1 -1
- data/lib/puppet/indirector/indirection.rb +1 -1
- data/lib/puppet/indirector/json.rb +4 -4
- data/lib/puppet/indirector/key/file.rb +8 -5
- data/lib/puppet/indirector/ldap.rb +1 -1
- data/lib/puppet/indirector/memory.rb +4 -0
- data/lib/puppet/indirector/msgpack.rb +82 -0
- data/lib/puppet/indirector/node/exec.rb +1 -1
- data/lib/puppet/indirector/node/ldap.rb +3 -3
- data/lib/puppet/indirector/node/msgpack.rb +7 -0
- data/lib/puppet/indirector/node/yaml.rb +15 -0
- data/lib/puppet/indirector/queue.rb +3 -2
- data/lib/puppet/indirector/report/msgpack.rb +11 -0
- data/lib/puppet/indirector/request.rb +17 -20
- data/lib/puppet/indirector/resource/rest.rb +1 -1
- data/lib/puppet/indirector/resource_type/parser.rb +3 -13
- data/lib/puppet/indirector/rest.rb +6 -7
- data/lib/puppet/indirector/ssl_file.rb +7 -7
- data/lib/puppet/indirector/yaml.rb +9 -13
- data/lib/puppet/metatype/manager.rb +12 -7
- data/lib/puppet/module.rb +14 -9
- data/lib/puppet/module_tool.rb +21 -26
- data/lib/puppet/module_tool/applications/application.rb +1 -1
- data/lib/puppet/module_tool/applications/generator.rb +2 -1
- data/lib/puppet/module_tool/applications/installer.rb +9 -4
- data/lib/puppet/module_tool/applications/uninstaller.rb +10 -7
- data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
- data/lib/puppet/module_tool/applications/upgrader.rb +11 -8
- data/lib/puppet/module_tool/checksums.rb +1 -1
- data/lib/puppet/module_tool/contents_description.rb +2 -0
- data/lib/puppet/module_tool/dependency.rb +4 -5
- data/lib/puppet/module_tool/errors.rb +2 -0
- data/lib/puppet/module_tool/install_directory.rb +3 -0
- data/lib/puppet/module_tool/metadata.rb +3 -5
- data/lib/puppet/module_tool/modulefile.rb +3 -0
- data/lib/puppet/module_tool/shared_behaviors.rb +6 -1
- data/lib/puppet/module_tool/skeleton.rb +3 -0
- data/lib/puppet/module_tool/tar.rb +3 -0
- data/lib/puppet/network/auth_config_parser.rb +1 -1
- data/lib/puppet/network/authconfig.rb +5 -2
- data/lib/puppet/network/authentication.rb +7 -2
- data/lib/puppet/network/authorization.rb +2 -2
- data/lib/puppet/network/format_support.rb +4 -0
- data/lib/puppet/network/formats.rb +9 -14
- data/lib/puppet/network/http.rb +11 -0
- data/lib/puppet/network/http/api.rb +0 -2
- data/lib/puppet/network/http/api/v1.rb +146 -11
- data/lib/puppet/network/http/api/v2.rb +32 -0
- data/lib/puppet/network/http/api/v2/authorization.rb +13 -0
- data/lib/puppet/network/http/api/v2/environments.rb +21 -0
- data/lib/puppet/network/http/connection.rb +94 -37
- data/lib/puppet/network/http/error.rb +69 -0
- data/lib/puppet/network/http/handler.rb +28 -196
- data/lib/puppet/network/http/issues.rb +9 -0
- data/lib/puppet/network/http/memory_response.rb +13 -0
- data/lib/puppet/network/http/rack/rest.rb +10 -18
- data/lib/puppet/network/http/request.rb +56 -0
- data/lib/puppet/network/http/response.rb +11 -0
- data/lib/puppet/network/http/route.rb +91 -0
- data/lib/puppet/network/http/webrick.rb +1 -1
- data/lib/puppet/network/http/webrick/rest.rb +7 -12
- data/lib/puppet/network/http_pool.rb +3 -3
- data/lib/puppet/network/rights.rb +4 -4
- data/lib/puppet/node.rb +23 -14
- data/lib/puppet/node/environment.rb +149 -125
- data/lib/puppet/node/facts.rb +6 -5
- data/lib/puppet/parameter.rb +1 -1
- data/lib/puppet/parser/ast.rb +1 -1
- data/lib/puppet/parser/ast/block_expression.rb +1 -6
- data/lib/puppet/parser/ast/collexpr.rb +54 -2
- data/lib/puppet/parser/ast/lambda.rb +9 -0
- data/lib/puppet/parser/ast/leaf.rb +15 -0
- data/lib/puppet/parser/ast/pops_bridge.rb +168 -0
- data/lib/puppet/parser/code_merger.rb +13 -0
- data/lib/puppet/parser/collector.rb +1 -1
- data/lib/puppet/parser/compiler.rb +28 -30
- data/lib/puppet/parser/e4_parser_adapter.rb +81 -0
- data/lib/puppet/parser/e_parser_adapter.rb +0 -1
- data/lib/puppet/parser/files.rb +12 -7
- data/lib/puppet/parser/functions.rb +36 -29
- data/lib/puppet/parser/functions/collect.rb +1 -1
- data/lib/puppet/parser/functions/defined.rb +40 -16
- data/lib/puppet/parser/functions/each.rb +55 -41
- data/lib/puppet/parser/functions/epp.rb +41 -0
- data/lib/puppet/parser/functions/extlookup.rb +2 -2
- data/lib/puppet/parser/functions/file.rb +1 -1
- data/lib/puppet/parser/functions/filter.rb +68 -16
- data/lib/puppet/parser/functions/generate.rb +1 -1
- data/lib/puppet/parser/functions/include.rb +3 -2
- data/lib/puppet/parser/functions/inline_epp.rb +79 -0
- data/lib/puppet/parser/functions/inline_template.rb +1 -1
- data/lib/puppet/parser/functions/lookup.rb +127 -27
- data/lib/puppet/parser/functions/map.rb +64 -12
- data/lib/puppet/parser/functions/reduce.rb +40 -16
- data/lib/puppet/parser/functions/select.rb +1 -1
- data/lib/puppet/parser/functions/slice.rb +42 -23
- data/lib/puppet/parser/grammar.ra +3 -0
- data/lib/puppet/parser/lexer.rb +10 -9
- data/lib/puppet/parser/parser.rb +15 -12
- data/lib/puppet/parser/parser_factory.rb +26 -1
- data/lib/puppet/parser/parser_support.rb +13 -4
- data/lib/puppet/parser/resource.rb +1 -1
- data/lib/puppet/parser/scope.rb +246 -97
- data/lib/puppet/parser/templatewrapper.rb +1 -1
- data/lib/puppet/parser/type_loader.rb +13 -2
- data/lib/puppet/pops.rb +15 -1
- data/lib/puppet/pops/adapters.rb +64 -32
- data/lib/puppet/pops/binder/binder.rb +122 -150
- data/lib/puppet/pops/binder/binder_issues.rb +1 -21
- data/lib/puppet/pops/binder/bindings_checker.rb +0 -20
- data/lib/puppet/pops/binder/bindings_composer.rb +4 -70
- data/lib/puppet/pops/binder/bindings_factory.rb +16 -58
- data/lib/puppet/pops/binder/bindings_label_provider.rb +0 -3
- data/lib/puppet/pops/binder/bindings_loader.rb +13 -4
- data/lib/puppet/pops/binder/bindings_model.rb +17 -31
- data/lib/puppet/pops/binder/bindings_model_dumper.rb +2 -20
- data/lib/puppet/pops/binder/config/binder_config.rb +8 -40
- data/lib/puppet/pops/binder/config/binder_config_checker.rb +2 -43
- data/lib/puppet/pops/binder/config/issues.rb +1 -21
- data/lib/puppet/pops/binder/injector.rb +86 -7
- data/lib/puppet/pops/binder/injector_entry.rb +6 -2
- data/lib/puppet/pops/binder/key_factory.rb +7 -1
- data/lib/puppet/pops/binder/lookup.rb +191 -0
- data/lib/puppet/pops/binder/producers.rb +5 -5
- data/lib/puppet/pops/binder/scheme_handler/symbolic_scheme.rb +2 -3
- data/lib/puppet/pops/binder/system_bindings.rb +4 -16
- data/lib/puppet/pops/containment.rb +72 -5
- data/lib/puppet/pops/evaluator/access_operator.rb +548 -0
- data/lib/puppet/pops/evaluator/closure.rb +57 -0
- data/lib/puppet/pops/evaluator/compare_operator.rb +168 -0
- data/lib/puppet/pops/evaluator/epp_evaluator.rb +87 -0
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1069 -0
- data/lib/puppet/pops/evaluator/external_syntax_support.rb +49 -0
- data/lib/puppet/pops/evaluator/relationship_operator.rb +156 -0
- data/lib/puppet/pops/evaluator/runtime3_support.rb +489 -0
- data/lib/puppet/pops/issue_reporter.rb +8 -4
- data/lib/puppet/pops/issues.rb +199 -4
- data/lib/puppet/pops/label_provider.rb +5 -0
- data/lib/puppet/pops/model/ast_transformer.rb +55 -31
- data/lib/puppet/pops/model/ast_tree_dumper.rb +9 -1
- data/lib/puppet/pops/model/factory.rb +265 -111
- data/lib/puppet/pops/model/model.rb +179 -140
- data/lib/puppet/pops/model/model_label_provider.rb +38 -9
- data/lib/puppet/pops/model/model_tree_dumper.rb +38 -13
- data/lib/puppet/pops/parser/code_merger.rb +17 -0
- data/lib/puppet/pops/parser/egrammar.ra +110 -61
- data/lib/puppet/pops/parser/eparser.rb +1415 -1092
- data/lib/puppet/pops/parser/epp_parser.rb +51 -0
- data/lib/puppet/pops/parser/epp_support.rb +247 -0
- data/lib/puppet/pops/parser/evaluating_parser.rb +53 -15
- data/lib/puppet/pops/parser/heredoc_support.rb +139 -0
- data/lib/puppet/pops/parser/interpolation_support.rb +227 -0
- data/lib/puppet/pops/parser/lexer.rb +83 -192
- data/lib/puppet/pops/parser/lexer2.rb +684 -0
- data/lib/puppet/pops/parser/lexer_support.rb +107 -0
- data/lib/puppet/pops/parser/locatable.rb +23 -0
- data/lib/puppet/pops/parser/locator.rb +291 -0
- data/lib/puppet/pops/parser/makefile +1 -8
- data/lib/puppet/pops/parser/parser_support.rb +76 -48
- data/lib/puppet/pops/parser/slurp_support.rb +95 -0
- data/lib/puppet/pops/patterns.rb +13 -4
- data/lib/puppet/pops/types/class_loader.rb +2 -2
- data/lib/puppet/pops/types/enumeration.rb +34 -0
- data/lib/puppet/pops/types/type_calculator.rb +983 -58
- data/lib/puppet/pops/types/type_factory.rb +203 -15
- data/lib/puppet/pops/types/type_parser.rb +355 -12
- data/lib/puppet/pops/types/types.rb +314 -24
- data/lib/puppet/pops/utils.rb +23 -7
- data/lib/puppet/pops/validation.rb +14 -8
- data/lib/puppet/pops/validation/checker3_1.rb +17 -12
- data/lib/puppet/pops/validation/checker4_0.rb +514 -0
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +31 -0
- data/lib/puppet/pops/visitor.rb +146 -4
- data/lib/puppet/property.rb +1 -1
- data/lib/puppet/property/ensure.rb +1 -1
- data/lib/puppet/provider.rb +47 -26
- data/lib/puppet/provider/aixobject.rb +3 -3
- data/lib/puppet/provider/augeas/augeas.rb +11 -11
- data/lib/puppet/provider/cron/crontab.rb +10 -1
- data/lib/puppet/provider/exec.rb +1 -1
- data/lib/puppet/provider/exec/posix.rb +1 -1
- data/lib/puppet/provider/exec/windows.rb +1 -1
- data/lib/puppet/provider/file/posix.rb +2 -2
- data/lib/puppet/provider/file/windows.rb +15 -9
- data/lib/puppet/provider/group/aix.rb +2 -2
- data/lib/puppet/provider/macauthorization/macauthorization.rb +3 -3
- data/lib/puppet/provider/mount.rb +7 -0
- data/lib/puppet/provider/mount/parsed.rb +0 -1
- data/lib/puppet/provider/naginator.rb +1 -1
- data/lib/puppet/provider/nameservice.rb +3 -3
- data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
- data/lib/puppet/provider/package/aix.rb +1 -1
- data/lib/puppet/provider/package/appdmg.rb +1 -4
- data/lib/puppet/provider/package/apple.rb +1 -1
- data/lib/puppet/provider/package/apt.rb +1 -1
- data/lib/puppet/provider/package/blastwave.rb +1 -1
- data/lib/puppet/provider/package/fink.rb +1 -1
- data/lib/puppet/provider/package/gem.rb +3 -3
- data/lib/puppet/provider/package/openbsd.rb +6 -4
- data/lib/puppet/provider/package/pacman.rb +58 -5
- data/lib/puppet/provider/package/pip.rb +2 -2
- data/lib/puppet/provider/package/pkgdmg.rb +25 -10
- data/lib/puppet/provider/package/pkgin.rb +48 -23
- data/lib/puppet/provider/package/pkgutil.rb +1 -1
- data/lib/puppet/provider/package/ports.rb +1 -1
- data/lib/puppet/provider/package/portupgrade.rb +7 -7
- data/lib/puppet/provider/package/rpm.rb +16 -8
- data/lib/puppet/provider/package/windows.rb +1 -1
- data/lib/puppet/provider/package/windows/package.rb +1 -1
- data/lib/puppet/provider/parsedfile.rb +1 -1
- data/lib/puppet/provider/selboolean/getsetsebool.rb +1 -1
- data/lib/puppet/provider/selmodule/semodule.rb +5 -5
- data/lib/puppet/provider/service/base.rb +1 -1
- data/lib/puppet/provider/service/bsd.rb +3 -3
- data/lib/puppet/provider/service/daemontools.rb +20 -20
- data/lib/puppet/provider/service/debian.rb +1 -1
- data/lib/puppet/provider/service/freebsd.rb +3 -3
- data/lib/puppet/provider/service/gentoo.rb +2 -2
- data/lib/puppet/provider/service/init.rb +5 -5
- data/lib/puppet/provider/service/launchd.rb +4 -4
- data/lib/puppet/provider/service/redhat.rb +2 -2
- data/lib/puppet/provider/service/runit.rb +4 -4
- data/lib/puppet/provider/service/service.rb +3 -4
- data/lib/puppet/provider/service/smf.rb +1 -1
- data/lib/puppet/provider/service/src.rb +3 -3
- data/lib/puppet/provider/service/systemd.rb +4 -4
- data/lib/puppet/provider/service/upstart.rb +22 -7
- data/lib/puppet/provider/service/windows.rb +7 -7
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +3 -3
- data/lib/puppet/provider/user/aix.rb +5 -5
- data/lib/puppet/provider/user/directoryservice.rb +8 -5
- data/lib/puppet/provider/user/ldap.rb +1 -1
- data/lib/puppet/provider/user/pw.rb +1 -1
- data/lib/puppet/provider/user/user_role_add.rb +2 -2
- data/lib/puppet/provider/user/useradd.rb +19 -5
- data/lib/puppet/provider/yumrepo/inifile.rb +187 -0
- data/lib/puppet/provider/zone/solaris.rb +4 -4
- data/lib/puppet/rails.rb +16 -11
- data/lib/puppet/rails/benchmark.rb +1 -1
- data/lib/puppet/rails/resource.rb +5 -1
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/reference/report.rb +1 -1
- data/lib/puppet/relationship.rb +10 -5
- data/lib/puppet/reports/http.rb +8 -2
- data/lib/puppet/reports/rrdgraph.rb +1 -1
- data/lib/puppet/reports/store.rb +3 -3
- data/lib/puppet/reports/tagmail.rb +4 -4
- data/lib/puppet/resource.rb +37 -44
- data/lib/puppet/resource/catalog.rb +18 -20
- data/lib/puppet/resource/status.rb +7 -6
- data/lib/puppet/resource/type.rb +6 -5
- data/lib/puppet/resource/type_collection.rb +2 -2
- data/lib/puppet/run.rb +9 -8
- data/lib/puppet/settings.rb +395 -244
- data/lib/puppet/settings/base_setting.rb +10 -4
- data/lib/puppet/settings/config_file.rb +81 -44
- data/lib/puppet/settings/directory_setting.rb +1 -2
- data/lib/puppet/settings/file_setting.rb +12 -5
- data/lib/puppet/settings/ini_file.rb +171 -0
- data/lib/puppet/ssl/base.rb +4 -0
- data/lib/puppet/ssl/certificate_authority.rb +16 -11
- data/lib/puppet/ssl/certificate_authority/interface.rb +3 -2
- data/lib/puppet/ssl/certificate_factory.rb +50 -5
- data/lib/puppet/ssl/certificate_request.rb +2 -2
- data/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
- data/lib/puppet/ssl/certificate_revocation_list.rb +3 -1
- data/lib/puppet/ssl/host.rb +9 -8
- data/lib/puppet/ssl/inventory.rb +1 -1
- data/lib/puppet/ssl/key.rb +1 -1
- data/lib/puppet/ssl/validator/default_validator.rb +1 -1
- data/lib/puppet/status.rb +8 -7
- data/lib/puppet/test/test_helper.rb +35 -4
- data/lib/puppet/transaction/event.rb +6 -5
- data/lib/puppet/transaction/report.rb +10 -10
- data/lib/puppet/type.rb +1 -3
- data/lib/puppet/type/augeas.rb +2 -1
- data/lib/puppet/type/cron.rb +41 -11
- data/lib/puppet/type/exec.rb +5 -5
- data/lib/puppet/type/file.rb +42 -4
- data/lib/puppet/type/file/content.rb +5 -6
- data/lib/puppet/type/file/ensure.rb +3 -3
- data/lib/puppet/type/file/source.rb +12 -6
- data/lib/puppet/type/file/target.rb +5 -5
- data/lib/puppet/type/k5login.rb +4 -4
- data/lib/puppet/type/mount.rb +1 -1
- data/lib/puppet/type/package.rb +79 -3
- data/lib/puppet/type/resources.rb +34 -5
- data/lib/puppet/type/selboolean.rb +1 -1
- data/lib/puppet/type/selmodule.rb +1 -1
- data/lib/puppet/type/ssh_authorized_key.rb +2 -1
- data/lib/puppet/type/sshkey.rb +2 -1
- data/lib/puppet/type/tidy.rb +1 -1
- data/lib/puppet/type/user.rb +4 -1
- data/lib/puppet/type/yumrepo.rb +219 -344
- data/lib/puppet/type/zone.rb +15 -5
- data/lib/puppet/util.rb +14 -13
- data/lib/puppet/util/adsi.rb +19 -3
- data/lib/puppet/util/autoload.rb +27 -24
- data/lib/puppet/util/backups.rb +6 -6
- data/lib/puppet/util/checksums.rb +2 -2
- data/lib/puppet/util/classgen.rb +1 -1
- data/lib/puppet/util/colors.rb +4 -12
- data/lib/puppet/util/command_line.rb +2 -2
- data/lib/puppet/util/command_line/trollop.rb +3 -3
- data/lib/puppet/util/docs.rb +2 -2
- data/lib/puppet/util/errors.rb +8 -1
- data/lib/puppet/util/execution.rb +12 -5
- data/lib/puppet/util/filetype.rb +5 -5
- data/lib/puppet/util/inifile.rb +19 -4
- data/lib/puppet/util/instrumentation/data.rb +5 -0
- data/lib/puppet/util/instrumentation/indirection_probe.rb +6 -1
- data/lib/puppet/util/instrumentation/listener.rb +6 -1
- data/lib/puppet/util/json_lockfile.rb +4 -1
- data/lib/puppet/util/ldap/connection.rb +1 -1
- data/lib/puppet/util/lockfile.rb +10 -6
- data/lib/puppet/util/log.rb +6 -1
- data/lib/puppet/util/log/destinations.rb +2 -2
- data/lib/puppet/util/metric.rb +9 -4
- data/lib/puppet/util/nagios_maker.rb +26 -1
- data/lib/puppet/util/network_device.rb +1 -1
- data/lib/puppet/util/network_device/config.rb +1 -1
- data/lib/puppet/util/network_device/transport/ssh.rb +3 -3
- data/lib/puppet/util/plugins.rb +1 -1
- data/lib/puppet/util/profiler.rb +13 -1
- data/lib/puppet/util/pson.rb +1 -1
- data/lib/puppet/util/queue/stomp.rb +2 -2
- data/lib/puppet/util/rdoc.rb +1 -1
- data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
- data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +19 -19
- data/lib/puppet/util/reference.rb +1 -1
- data/lib/puppet/util/resource_template.rb +1 -1
- data/lib/puppet/util/retryaction.rb +1 -1
- data/lib/puppet/util/selinux.rb +2 -2
- data/lib/puppet/util/storage.rb +3 -3
- data/lib/puppet/util/symbolic_file_mode.rb +1 -1
- data/lib/puppet/util/tag_set.rb +15 -3
- data/lib/puppet/util/tagging.rb +12 -17
- data/lib/puppet/util/watched_file.rb +1 -1
- data/lib/puppet/util/watcher.rb +1 -1
- data/lib/puppet/util/windows/error.rb +2 -2
- data/lib/puppet/util/windows/file.rb +20 -4
- data/lib/puppet/util/windows/registry.rb +2 -2
- data/lib/puppet/vendor/safe_yaml/CHANGES.md +1 -1
- data/lib/puppet/version.rb +1 -1
- data/lib/puppetx.rb +1 -21
- data/lib/puppetx/puppet/syntax_checker.rb +1 -1
- data/lib/puppetx/puppetlabs/syntax_checkers/json.rb +9 -11
- data/spec/fixtures/integration/node/environment/sitedir/00_a.pp +2 -0
- data/spec/fixtures/integration/node/environment/sitedir/01_b.pp +6 -0
- data/spec/fixtures/{unit/pops/binder/hiera2/yaml_backend/empty/common.yaml → integration/node/environment/sitedir/03_empty.pp} +0 -0
- data/spec/fixtures/integration/node/environment/sitedir/04_include.pp +2 -0
- data/spec/fixtures/integration/provider/cron/crontab/purged +8 -0
- data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +1 -1
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/binder_config.yaml +3 -12
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/lib/puppet/bindings/confdirtest.rb +10 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome2/lib/puppet/bindings/awesome2/default.rb +20 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/{awesome/lib/puppetx/awesome → awesome2/lib/puppetx/awesome2}/echo_scheme_handler.rb +2 -2
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/lib/puppet/bindings/bad/default.rb +5 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/lib/puppet/bindings/good/default.rb +6 -0
- data/spec/fixtures/unit/pops/binder/config/binder_config/ok/binder_config.yaml +2 -2
- data/spec/fixtures/unit/provider/service/systemd/{list_units → list_units_services} +0 -1
- data/spec/integration/agent/logging_spec.rb +1 -1
- data/spec/integration/application/apply_spec.rb +78 -3
- data/spec/integration/application/doc_spec.rb +3 -2
- data/spec/integration/configurer_spec.rb +5 -3
- data/spec/integration/directory_environments_spec.rb +50 -0
- data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
- data/spec/integration/indirector/file_content/file_server_spec.rb +4 -5
- data/spec/integration/network/authconfig_spec.rb +4 -4
- data/spec/integration/network/formats_spec.rb +1 -1
- data/spec/integration/node/environment_spec.rb +67 -15
- data/spec/integration/node/facts_spec.rb +1 -1
- data/spec/integration/node_spec.rb +1 -1
- data/spec/integration/parser/catalog_spec.rb +100 -60
- data/spec/integration/parser/compiler_spec.rb +102 -13
- data/spec/integration/parser/future_compiler_spec.rb +416 -0
- data/spec/integration/parser/parser_spec.rb +44 -105
- data/spec/integration/parser/scope_spec.rb +614 -528
- data/spec/integration/provider/cron/crontab_spec.rb +21 -0
- data/spec/integration/provider/mount_spec.rb +15 -2
- data/spec/integration/resource/catalog_spec.rb +1 -1
- data/spec/integration/resource/type_collection_spec.rb +3 -4
- data/spec/integration/ssl/autosign_spec.rb +1 -1
- data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -1
- data/spec/integration/ssl/host_spec.rb +1 -1
- data/spec/integration/transaction_spec.rb +13 -13
- data/spec/integration/type/exec_spec.rb +2 -2
- data/spec/integration/type/file_spec.rb +114 -41
- data/spec/integration/type/nagios_spec.rb +80 -0
- data/spec/integration/type/tidy_spec.rb +2 -2
- data/spec/integration/util/execution_spec.rb +17 -0
- data/spec/integration/util/rdoc/parser_spec.rb +1 -1
- data/spec/integration/util/settings_spec.rb +1 -1
- data/spec/integration/util/windows/security_spec.rb +27 -2
- data/spec/lib/matchers/include.rb +27 -0
- data/spec/lib/matchers/include_spec.rb +32 -0
- data/spec/lib/matchers/json.rb +135 -79
- data/spec/lib/matchers/match_tokens2.rb +74 -0
- data/spec/lib/matchers/resource.rb +35 -0
- data/spec/lib/puppet/indirector/indirector_testing/memory.rb +7 -0
- data/spec/lib/puppet/indirector/indirector_testing/msgpack.rb +6 -0
- data/spec/lib/puppet/indirector_testing.rb +12 -2
- data/spec/lib/puppet_spec/files.rb +1 -0
- data/spec/lib/puppet_spec/matchers.rb +5 -0
- data/spec/lib/puppet_spec/modules.rb +1 -1
- data/spec/lib/puppet_spec/scope.rb +14 -0
- data/spec/shared_behaviours/file_server_terminus.rb +2 -2
- data/spec/spec_helper.rb +47 -17
- data/spec/unit/agent_spec.rb +8 -1
- data/spec/unit/application/agent_spec.rb +5 -4
- data/spec/unit/application/apply_spec.rb +34 -15
- data/spec/unit/application/device_spec.rb +27 -32
- data/spec/unit/application/doc_spec.rb +4 -4
- data/spec/unit/application/filebucket_spec.rb +1 -1
- data/spec/unit/application/master_spec.rb +2 -2
- data/spec/unit/application_spec.rb +1 -1
- data/spec/unit/configurer/downloader_spec.rb +1 -1
- data/spec/unit/configurer/fact_handler_spec.rb +5 -16
- data/spec/unit/configurer_spec.rb +2 -2
- data/spec/unit/confine/exists_spec.rb +5 -5
- data/spec/unit/context/trusted_information_spec.rb +124 -0
- data/spec/unit/context_spec.rb +74 -0
- data/spec/unit/environments_spec.rb +126 -0
- data/spec/unit/face/config_spec.rb +31 -16
- data/spec/unit/face/module/build_spec.rb +1 -0
- data/spec/unit/face/module/install_spec.rb +21 -104
- data/spec/unit/face/module/list_spec.rb +52 -36
- data/spec/unit/face/module/uninstall_spec.rb +18 -25
- data/spec/unit/face/parser_spec.rb +39 -23
- data/spec/unit/file_bucket/dipper_spec.rb +2 -2
- data/spec/unit/file_serving/base_spec.rb +9 -13
- data/spec/unit/file_serving/configuration/parser_spec.rb +8 -2
- data/spec/unit/file_serving/configuration_spec.rb +7 -7
- data/spec/unit/file_serving/content_spec.rb +7 -12
- data/spec/unit/file_serving/fileset_spec.rb +49 -53
- data/spec/unit/file_serving/metadata_spec.rb +83 -32
- data/spec/unit/file_serving/mount/file_spec.rb +10 -10
- data/spec/unit/file_system/tempfile_spec.rb +3 -3
- data/spec/unit/file_system_spec.rb +508 -0
- data/spec/unit/forge/errors_spec.rb +1 -1
- data/spec/unit/forge/repository_spec.rb +1 -3
- data/spec/unit/hiera/scope_spec.rb +6 -2
- data/spec/unit/hiera_puppet_spec.rb +13 -6
- data/spec/unit/indirector/catalog/msgpack_spec.rb +12 -0
- data/spec/unit/indirector/catalog/static_compiler_spec.rb +42 -11
- data/spec/unit/indirector/direct_file_server_spec.rb +6 -6
- data/spec/unit/indirector/facts/facter_spec.rb +5 -5
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +4 -4
- data/spec/unit/indirector/file_metadata/file_spec.rb +2 -2
- data/spec/unit/indirector/file_server_spec.rb +4 -4
- data/spec/unit/indirector/json_spec.rb +6 -6
- data/spec/unit/indirector/key/file_spec.rb +8 -8
- data/spec/unit/indirector/msgpack_spec.rb +191 -0
- data/spec/unit/indirector/node/active_record_spec.rb +1 -1
- data/spec/unit/indirector/node/ldap_spec.rb +16 -7
- data/spec/unit/indirector/node/msgpack_spec.rb +24 -0
- data/spec/unit/indirector/node/plain_spec.rb +1 -1
- data/spec/unit/indirector/queue_spec.rb +1 -1
- data/spec/unit/indirector/report/msgpack_spec.rb +28 -0
- data/spec/unit/indirector/request_spec.rb +16 -8
- data/spec/unit/indirector/rest_spec.rb +0 -4
- data/spec/unit/indirector/ssl_file_spec.rb +12 -11
- data/spec/unit/indirector/yaml_spec.rb +4 -4
- data/spec/unit/man_spec.rb +32 -0
- data/spec/unit/module_spec.rb +60 -46
- data/spec/unit/module_tool/applications/checksummer_spec.rb +1 -1
- data/spec/unit/module_tool/applications/installer_spec.rb +53 -16
- data/spec/unit/module_tool/applications/uninstaller_spec.rb +26 -25
- data/spec/unit/module_tool/tar_spec.rb +1 -1
- data/spec/unit/module_tool_spec.rb +17 -90
- data/spec/unit/network/authconfig_spec.rb +3 -4
- data/spec/unit/network/authentication_spec.rb +20 -6
- data/spec/unit/network/authorization_spec.rb +11 -1
- data/spec/unit/network/formats_spec.rb +32 -9
- data/spec/unit/network/http/api/v1_spec.rb +365 -62
- data/spec/unit/network/http/api/v2/authorization_spec.rb +57 -0
- data/spec/unit/network/http/api/v2/environments_spec.rb +42 -0
- data/spec/unit/network/http/api/v2_spec.rb +14 -0
- data/spec/unit/network/http/connection_spec.rb +39 -5
- data/spec/unit/network/http/error_spec.rb +30 -0
- data/spec/unit/network/http/handler_spec.rb +69 -419
- data/spec/unit/network/http/rack/rest_spec.rb +20 -28
- data/spec/unit/network/http/route_spec.rb +75 -0
- data/spec/unit/network/http/webrick/rest_spec.rb +21 -58
- data/spec/unit/network/http_pool_spec.rb +3 -3
- data/spec/unit/network/rights_spec.rb +2 -2
- data/spec/unit/node/environment_spec.rb +108 -89
- data/spec/unit/node/facts_spec.rb +5 -12
- data/spec/unit/node_spec.rb +22 -22
- data/spec/unit/parser/ast/collection_spec.rb +1 -1
- data/spec/unit/parser/ast/leaf_spec.rb +2 -0
- data/spec/unit/parser/ast/resource_spec.rb +1 -1
- data/spec/unit/parser/compiler_spec.rb +5 -3
- data/spec/unit/parser/files_spec.rb +40 -50
- data/spec/unit/parser/functions/defined_spec.rb +80 -18
- data/spec/unit/parser/functions/epp_spec.rb +88 -0
- data/spec/unit/parser/functions/fqdn_rand_spec.rb +4 -1
- data/spec/unit/parser/functions/generate_spec.rb +6 -2
- data/spec/unit/parser/functions/hiera_array_spec.rb +5 -2
- data/spec/unit/parser/functions/hiera_hash_spec.rb +4 -1
- data/spec/unit/parser/functions/hiera_include_spec.rb +6 -3
- data/spec/unit/parser/functions/hiera_spec.rb +5 -2
- data/spec/unit/parser/functions/include_spec.rb +0 -1
- data/spec/unit/parser/functions/inline_epp_spec.rb +82 -0
- data/spec/unit/parser/functions/lookup_spec.rb +66 -16
- data/spec/unit/parser/functions_spec.rb +25 -91
- data/spec/unit/parser/lexer_spec.rb +1 -1
- data/spec/unit/parser/methods/filter_spec.rb +56 -0
- data/spec/unit/parser/methods/map_spec.rb +94 -5
- data/spec/unit/parser/methods/reduce_spec.rb +10 -0
- data/spec/unit/parser/methods/shared.rb +2 -18
- data/spec/unit/parser/methods/slice_spec.rb +39 -1
- data/spec/unit/parser/parser_spec.rb +14 -10
- data/spec/unit/parser/resource_spec.rb +3 -9
- data/spec/unit/parser/scope_spec.rb +81 -78
- data/spec/unit/parser/type_loader_spec.rb +0 -4
- data/spec/unit/pops/benchmark_spec.rb +142 -0
- data/spec/unit/pops/binder/binder_spec.rb +15 -34
- data/spec/unit/pops/binder/bindings_checker_spec.rb +0 -41
- data/spec/unit/pops/binder/bindings_composer_spec.rb +6 -31
- data/spec/unit/pops/binder/config/binder_config_spec.rb +5 -18
- data/spec/unit/pops/binder/injector_spec.rb +76 -81
- data/spec/unit/pops/evaluator/access_ops_spec.rb +376 -0
- data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +77 -0
- data/spec/unit/pops/evaluator/basic_expressions_spec.rb +103 -0
- data/spec/unit/pops/evaluator/collections_ops_spec.rb +111 -0
- data/spec/unit/pops/evaluator/comparison_ops_spec.rb +256 -0
- data/spec/unit/pops/evaluator/conditionals_spec.rb +190 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +1045 -0
- data/spec/unit/pops/evaluator/evaluator_rspec_helper.rb +75 -0
- data/spec/unit/pops/evaluator/logical_ops_spec.rb +90 -0
- data/spec/unit/pops/evaluator/string_interpolation_spec.rb +44 -0
- data/spec/unit/pops/evaluator/variables_spec.rb +194 -0
- data/spec/unit/pops/factory_spec.rb +6 -29
- data/spec/unit/pops/issues_spec.rb +1 -1
- data/spec/unit/pops/model/ast_transformer_spec.rb +6 -9
- data/spec/unit/pops/model/model_spec.rb +2 -2
- data/spec/unit/pops/parser/epp_parser_spec.rb +86 -0
- data/spec/unit/pops/parser/evaluating_parser_spec.rb +4 -2
- data/spec/unit/pops/parser/lexer2_spec.rb +428 -0
- data/spec/unit/pops/parser/lexer_spec.rb +25 -86
- data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +29 -4
- data/spec/unit/pops/parser/parse_calls_spec.rb +10 -6
- data/spec/unit/pops/parser/parse_conditionals_spec.rb +0 -9
- data/spec/unit/pops/parser/parse_containers_spec.rb +43 -12
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +73 -0
- data/spec/unit/pops/parser/parse_resource_spec.rb +14 -0
- data/spec/unit/pops/parser/parser_spec.rb +3 -1
- data/spec/unit/pops/transformer/transform_basic_expressions_spec.rb +4 -4
- data/spec/unit/pops/transformer/transform_calls_spec.rb +41 -6
- data/spec/unit/pops/transformer/transform_conditionals_spec.rb +0 -9
- data/spec/unit/pops/transformer/transform_containers_spec.rb +12 -4
- data/spec/unit/pops/types/enumeration_spec.rb +50 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +1171 -196
- data/spec/unit/pops/types/type_factory_spec.rb +108 -4
- data/spec/unit/pops/types/type_parser_spec.rb +114 -10
- data/spec/unit/pops/validator/validator_spec.rb +36 -1
- data/spec/unit/provider/augeas/augeas_spec.rb +39 -16
- data/spec/unit/provider/cron/parsed_spec.rb +27 -31
- data/spec/unit/provider/file/posix_spec.rb +2 -2
- data/spec/unit/provider/group/windows_adsi_spec.rb +1 -0
- data/spec/unit/provider/mount_spec.rb +12 -1
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +3 -3
- data/spec/unit/provider/package/apt_spec.rb +1 -1
- data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
- data/spec/unit/provider/package/gem_spec.rb +12 -0
- data/spec/unit/provider/package/msi_spec.rb +4 -0
- data/spec/unit/provider/package/openbsd_spec.rb +10 -10
- data/spec/unit/provider/package/pacman_spec.rb +36 -7
- data/spec/unit/provider/package/pkgin_spec.rb +57 -55
- data/spec/unit/provider/package/rpm_spec.rb +51 -6
- data/spec/unit/provider/service/base_spec.rb +4 -4
- data/spec/unit/provider/service/daemontools_spec.rb +8 -13
- data/spec/unit/provider/service/freebsd_spec.rb +3 -3
- data/spec/unit/provider/service/gentoo_spec.rb +24 -24
- data/spec/unit/provider/service/init_spec.rb +15 -15
- data/spec/unit/provider/service/openbsd_spec.rb +16 -16
- data/spec/unit/provider/service/openrc_spec.rb +20 -20
- data/spec/unit/provider/service/openwrt_spec.rb +1 -1
- data/spec/unit/provider/service/runit_spec.rb +5 -8
- data/spec/unit/provider/service/src_spec.rb +4 -4
- data/spec/unit/provider/service/systemd_spec.rb +24 -14
- data/spec/unit/provider/service/upstart_spec.rb +12 -4
- data/spec/unit/provider/service/windows_spec.rb +1 -1
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +21 -23
- data/spec/unit/provider/user/directoryservice_spec.rb +7 -7
- data/spec/unit/provider/user/useradd_spec.rb +43 -15
- data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
- data/spec/unit/provider/yumrepo/inifile_spec.rb +105 -0
- data/spec/unit/provider/zone/solaris_spec.rb +1 -1
- data/spec/unit/provider_spec.rb +120 -62
- data/spec/unit/rails/host_spec.rb +1 -1
- data/spec/unit/rails/param_value_spec.rb +4 -0
- data/spec/unit/relationship_spec.rb +4 -4
- data/spec/unit/reports/http_spec.rb +14 -3
- data/spec/unit/reports/rrdgraph_spec.rb +0 -1
- data/spec/unit/reports/store_spec.rb +2 -2
- data/spec/unit/resource/catalog_spec.rb +17 -29
- data/spec/unit/resource/status_spec.rb +1 -1
- data/spec/unit/resource/type_collection_spec.rb +28 -47
- data/spec/unit/resource/type_spec.rb +12 -23
- data/spec/unit/resource_spec.rb +54 -93
- data/spec/unit/run_spec.rb +3 -3
- data/spec/unit/settings/autosign_setting_spec.rb +1 -1
- data/spec/unit/settings/config_file_spec.rb +68 -15
- data/spec/unit/settings/file_setting_spec.rb +2 -2
- data/spec/unit/settings/ini_file_spec.rb +184 -0
- data/spec/unit/settings_spec.rb +137 -79
- data/spec/unit/ssl/certificate_authority/interface_spec.rb +3 -1
- data/spec/unit/ssl/certificate_authority_spec.rb +11 -9
- data/spec/unit/ssl/certificate_factory_spec.rb +19 -4
- data/spec/unit/ssl/certificate_request_attributes_spec.rb +1 -1
- data/spec/unit/ssl/certificate_revocation_list_spec.rb +101 -72
- data/spec/unit/ssl/host_spec.rb +8 -20
- data/spec/unit/ssl/inventory_spec.rb +2 -2
- data/spec/unit/ssl/key_spec.rb +4 -4
- data/spec/unit/status_spec.rb +6 -4
- data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -11
- data/spec/unit/transaction/event_spec.rb +2 -2
- data/spec/unit/transaction/report_spec.rb +24 -15
- data/spec/unit/transaction/resource_harness_spec.rb +1 -1
- data/spec/unit/type/cron_spec.rb +39 -1
- data/spec/unit/type/file/content_spec.rb +4 -5
- data/spec/unit/type/file/ctime_spec.rb +1 -1
- data/spec/unit/type/file/mode_spec.rb +5 -4
- data/spec/unit/type/file/mtime_spec.rb +1 -1
- data/spec/unit/type/file/source_spec.rb +30 -7
- data/spec/unit/type/file_spec.rb +8 -8
- data/spec/unit/type/k5login_spec.rb +3 -3
- data/spec/unit/type/nagios_spec.rb +6 -0
- data/spec/unit/type/package/package_settings_spec.rb +135 -0
- data/spec/unit/type/package_spec.rb +13 -1
- data/spec/unit/type/resources_spec.rb +155 -0
- data/spec/unit/type/service_spec.rb +3 -3
- data/spec/unit/type/ssh_authorized_key_spec.rb +96 -93
- data/spec/unit/type/sshkey_spec.rb +39 -30
- data/spec/unit/type/tidy_spec.rb +19 -12
- data/spec/unit/type/user_spec.rb +47 -2
- data/spec/unit/type/whit_spec.rb +2 -2
- data/spec/unit/type/yumrepo_spec.rb +32 -177
- data/spec/unit/type/zone_spec.rb +2 -2
- data/spec/unit/type_spec.rb +11 -0
- data/spec/unit/util/adsi_spec.rb +48 -1
- data/spec/unit/util/autoload_spec.rb +24 -39
- data/spec/unit/util/backups_spec.rb +25 -28
- data/spec/unit/util/checksums_spec.rb +1 -3
- data/spec/unit/util/colors_spec.rb +14 -0
- data/spec/unit/util/docs_spec.rb +9 -0
- data/spec/unit/util/execution_spec.rb +1 -1
- data/spec/unit/util/filetype_spec.rb +7 -7
- data/spec/unit/util/instrumentation/data_spec.rb +3 -1
- data/spec/unit/util/instrumentation/indirection_probe_spec.rb +2 -0
- data/spec/unit/util/instrumentation/listener_spec.rb +3 -2
- data/spec/unit/util/json_lockfile_spec.rb +25 -4
- data/spec/unit/util/lockfile_spec.rb +49 -7
- data/spec/unit/util/log/destinations_spec.rb +1 -0
- data/spec/unit/util/log_spec.rb +1 -1
- data/spec/unit/util/metric_spec.rb +1 -1
- data/spec/unit/util/pidlock_spec.rb +6 -6
- data/spec/unit/util/pson_spec.rb +2 -2
- data/spec/unit/util/rdoc/parser_spec.rb +32 -29
- data/spec/unit/util/resource_template_spec.rb +3 -3
- data/spec/unit/util/selinux_spec.rb +5 -5
- data/spec/unit/util/storage_spec.rb +4 -4
- data/spec/unit/util/tag_set_spec.rb +1 -1
- data/spec/unit/util/watcher_spec.rb +1 -4
- data/spec/unit/util/yaml_spec.rb +2 -2
- data/spec/unit/util_spec.rb +7 -7
- data/tasks/benchmark.rake +0 -1
- data/tasks/parallel.rake +408 -0
- data/tasks/yard.rake +59 -0
- metadata +2889 -2782
- checksums.yaml +0 -7
- data/README_DEVELOPER.md +0 -809
- data/lib/puppet/file_system/file.rb +0 -271
- data/lib/puppet/network/http/rack/httphandler.rb +0 -13
- data/lib/puppet/pops/binder/hiera2.rb +0 -10
- data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +0 -148
- data/lib/puppet/pops/binder/hiera2/config.rb +0 -69
- data/lib/puppet/pops/binder/hiera2/config_checker.rb +0 -68
- data/lib/puppet/pops/binder/hiera2/diagnostic_producer.rb +0 -36
- data/lib/puppet/pops/binder/hiera2/issues.rb +0 -67
- data/lib/puppet/pops/binder/hiera2/json_backend.rb +0 -18
- data/lib/puppet/pops/binder/hiera2/yaml_backend.rb +0 -21
- data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +0 -67
- data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +0 -92
- data/lib/puppet/pops/parser/grammar.ra +0 -746
- data/lib/puppet/provider/port/parsed.rb +0 -173
- data/lib/puppet/type/port.rb +0 -119
- data/lib/puppetx/puppet/hiera2_backend.rb +0 -31
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/binder_config.yaml +0 -18
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/hiera.yaml +0 -8
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/common.yaml +0 -1
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/hiera.yaml +0 -10
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/common.yaml +0 -1
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/hiera.yaml +0 -11
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/localhost.yaml +0 -1
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/common.yaml +0 -3
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/hiera.yaml +0 -13
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppet/bindings/awesome/default.rb +0 -4
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_backend.rb +0 -11
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/localhost.yaml +0 -1
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/common.yaml +0 -3
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/hiera_config.yaml +0 -9
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/common.yaml +0 -2
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/hiera.yaml +0 -11
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/hiera.yaml +0 -9
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.json +0 -9
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.yaml +0 -5
- data/spec/fixtures/unit/pops/binder/hiera2/config/bad_syntax/hiera.yaml +0 -10
- data/spec/fixtures/unit/pops/binder/hiera2/config/malformed_hierarchy/hiera.yaml +0 -8
- data/spec/fixtures/unit/pops/binder/hiera2/config/missing/foo.txt +0 -1
- data/spec/fixtures/unit/pops/binder/hiera2/config/no_backends/hiera.yaml +0 -7
- data/spec/fixtures/unit/pops/binder/hiera2/config/no_hierarchy/hiera.yaml +0 -4
- data/spec/fixtures/unit/pops/binder/hiera2/config/not_a_hash/hiera.yaml +0 -2
- data/spec/fixtures/unit/pops/binder/hiera2/config/ok/hiera.yaml +0 -8
- data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/invalid/common.yaml +0 -1
- data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/ok/common.yaml +0 -2
- data/spec/unit/file_system/file_spec.rb +0 -486
- data/spec/unit/pops/binder/hiera2/bindings_provider_spec.rb +0 -74
- data/spec/unit/pops/binder/hiera2/config_spec.rb +0 -61
- data/spec/unit/pops/binder/hiera2/yaml_backend_spec.rb +0 -33
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
# A Closure represents logic bound to a particular scope.
|
3
|
+
# As long as the runtime (basically the scope implementation) has the behaviour of Puppet 3x it is not
|
4
|
+
# safe to use this closure when the scope given to it when initialized goes "out of scope".
|
5
|
+
#
|
6
|
+
# Note that the implementation is backwards compatible in that the call method accepts a scope, but this
|
7
|
+
# scope is not used.
|
8
|
+
#
|
9
|
+
class Puppet::Pops::Evaluator::Closure
|
10
|
+
attr_reader :evaluator
|
11
|
+
attr_reader :model
|
12
|
+
attr_reader :enclosing_scope
|
13
|
+
|
14
|
+
def initialize(evaluator, model, scope)
|
15
|
+
@evaluator = evaluator
|
16
|
+
@model = model
|
17
|
+
@enclosing_scope = scope
|
18
|
+
end
|
19
|
+
|
20
|
+
# marker method checked with respond_to :puppet_lambda
|
21
|
+
def puppet_lambda()
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
# compatible with 3x AST::Lambda
|
26
|
+
def call(scope, *args)
|
27
|
+
@evaluator.call(self, args, @enclosing_scope)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Call closure with argument assignment by name
|
31
|
+
def call_by_name(scope, args_hash, spill_over = false)
|
32
|
+
@evaluator.call_by_name(self, args_hash, @enclosing_scope, spill_over)
|
33
|
+
end
|
34
|
+
|
35
|
+
# incompatible with 3x except that it is an array of the same size
|
36
|
+
def parameters()
|
37
|
+
@model.parameters || []
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the number of parameters (required and optional)
|
41
|
+
# @return [Integer] the total number of accepted parameters
|
42
|
+
def parameter_count
|
43
|
+
# yes, this is duplication of code, but it saves a method call
|
44
|
+
(@model.parameters || []).size
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the number of optional parameters.
|
48
|
+
# @return [Integer] the number of optional accepted parameters
|
49
|
+
def optional_parameter_count
|
50
|
+
@model.parameters.count { |p| !p.value.nil? }
|
51
|
+
end
|
52
|
+
|
53
|
+
def parameter_names
|
54
|
+
@model.parameters.collect {|p| p.name }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# Compares the puppet DSL way
|
2
|
+
#
|
3
|
+
# ==Equality
|
4
|
+
# All string vs. numeric equalities check for numeric equality first, then string equality
|
5
|
+
# Arrays are equal to arrays if they have the same length, and each element #equals
|
6
|
+
# Hashes are equal to hashes if they have the same size and keys and values #equals.
|
7
|
+
# All other objects are equal if they are ruby #== equal
|
8
|
+
#
|
9
|
+
class Puppet::Pops::Evaluator::CompareOperator
|
10
|
+
include Puppet::Pops::Utils
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@@equals_visitor ||= Puppet::Pops::Visitor.new(self, "equals", 1, 1)
|
14
|
+
@@compare_visitor ||= Puppet::Pops::Visitor.new(self, "cmp", 1, 1)
|
15
|
+
@@include_visitor ||= Puppet::Pops::Visitor.new(self, "include", 1, 1)
|
16
|
+
@type_calculator = Puppet::Pops::Types::TypeCalculator.new()
|
17
|
+
end
|
18
|
+
|
19
|
+
def equals (a, b)
|
20
|
+
@@equals_visitor.visit_this_1(self, a, b)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Performs a comparison of a and b, and return > 0 if a is bigger, 0 if equal, and < 0 if b is bigger.
|
24
|
+
# Comparison of String vs. Numeric always compares using numeric.
|
25
|
+
def compare(a, b)
|
26
|
+
@@compare_visitor.visit_this_1(self, a, b)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Answers is b included in a
|
30
|
+
def include?(a, b)
|
31
|
+
@@include_visitor.visit_this_1(self, a, b)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def cmp_String(a, b)
|
37
|
+
# if both are numerics in string form, compare as number
|
38
|
+
n1 = Puppet::Pops::Utils.to_n(a)
|
39
|
+
n2 = Puppet::Pops::Utils.to_n(b)
|
40
|
+
|
41
|
+
# Numeric is always lexically smaller than a string, even if the string is empty.
|
42
|
+
return n1 <=> n2 if n1 && n2
|
43
|
+
return -1 if n1 && b.is_a?(String)
|
44
|
+
return 1 if n2
|
45
|
+
return a.casecmp(b) if b.is_a?(String)
|
46
|
+
|
47
|
+
raise ArgumentError.new("A String is not comparable to a non String or Number")
|
48
|
+
end
|
49
|
+
|
50
|
+
# Equality is case independent.
|
51
|
+
def equals_String(a, b)
|
52
|
+
if n1 = Puppet::Pops::Utils.to_n(a)
|
53
|
+
if n2 = Puppet::Pops::Utils.to_n(b)
|
54
|
+
n1 == n2
|
55
|
+
else
|
56
|
+
false
|
57
|
+
end
|
58
|
+
else
|
59
|
+
return false unless b.is_a?(String)
|
60
|
+
a.casecmp(b) == 0
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def cmp_Numeric(a, b)
|
65
|
+
if n2 = Puppet::Pops::Utils.to_n(b)
|
66
|
+
a <=> n2
|
67
|
+
elsif b.kind_of(String)
|
68
|
+
# Numeric is always lexiographically smaller than a string, even if the string is empty.
|
69
|
+
-1
|
70
|
+
else
|
71
|
+
raise ArgumentError.new("A Numeric is not comparable to non Numeric or String")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def equals_Numeric(a, b)
|
76
|
+
if n2 = Puppet::Pops::Utils.to_n(b)
|
77
|
+
a == n2
|
78
|
+
else
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def equals_Array(a, b)
|
84
|
+
return false unless b.is_a?(Array) && a.size == b.size
|
85
|
+
a.each_index {|i| return false unless equals(a.slice(i), b.slice(i)) }
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
def equals_Hash(a, b)
|
90
|
+
return false unless b.is_a?(Hash) && a.size == b.size
|
91
|
+
a.each {|ak, av| return false unless equals(b[ak], av)}
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
def cmp_Symbol(a, b)
|
96
|
+
if b.is_a?(Symbol)
|
97
|
+
a <=> b
|
98
|
+
else
|
99
|
+
raise ArgumentError.new("Symbol not comparable to non Symbol")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def cmp_Object(a, b)
|
104
|
+
raise ArgumentError.new("Only Strings and Numbers are comparable")
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def equals_Object(a, b)
|
109
|
+
a == b
|
110
|
+
end
|
111
|
+
|
112
|
+
def equals_NilClass(a, b)
|
113
|
+
b.nil? || b == :undef
|
114
|
+
end
|
115
|
+
|
116
|
+
def equals_Symbol(a, b)
|
117
|
+
a == b || a == :undef && b.nil?
|
118
|
+
end
|
119
|
+
|
120
|
+
def include_Object(a, b)
|
121
|
+
false
|
122
|
+
end
|
123
|
+
|
124
|
+
def include_String(a, b)
|
125
|
+
case b
|
126
|
+
when String
|
127
|
+
# subsstring search downcased
|
128
|
+
a.downcase.include?(b.downcase)
|
129
|
+
when Regexp
|
130
|
+
# match (convert to boolean)
|
131
|
+
!!(a =~ b)
|
132
|
+
when Numeric
|
133
|
+
# convert string to number, true if ==
|
134
|
+
equals(a, b)
|
135
|
+
when Puppet::Pops::Types::PStringType
|
136
|
+
# is there a string in a string? (yes, each char is a string, and an empty string contains an empty string)
|
137
|
+
true
|
138
|
+
else
|
139
|
+
if b == Puppet::Pops::Types::PDataType || b == Puppet::Pops::Types::PObjectType
|
140
|
+
# A String is Data and Object (but not of all subtypes of those types).
|
141
|
+
true
|
142
|
+
else
|
143
|
+
false
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def include_Array(a, b)
|
149
|
+
case b
|
150
|
+
when Regexp
|
151
|
+
a.each do |element|
|
152
|
+
next unless element.is_a? String
|
153
|
+
return true if element =~ b
|
154
|
+
end
|
155
|
+
return false
|
156
|
+
when Puppet::Pops::Types::PAbstractType
|
157
|
+
a.each {|element| return true if @type_calculator.instance?(b, element) }
|
158
|
+
return false
|
159
|
+
else
|
160
|
+
a.each {|element| return true if equals(element, b) }
|
161
|
+
return false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def include_Hash(a, b)
|
166
|
+
include?(a.keys, b)
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Handler of Epp call/evaluation from the epp and inline_epp functions
|
2
|
+
#
|
3
|
+
class Puppet::Pops::Evaluator::EppEvaluator
|
4
|
+
|
5
|
+
def self.inline_epp(scope, epp_source, template_args = nil)
|
6
|
+
unless epp_source.is_a? String
|
7
|
+
raise ArgumentError, "inline_epp(): the first argument must be a String with the epp source text, got a #{epp_source.class}"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Parse and validate the source
|
11
|
+
parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new
|
12
|
+
begin
|
13
|
+
result = parser.parse_string(epp_source, 'inlined-epp-text')
|
14
|
+
rescue Puppet::ParseError => e
|
15
|
+
raise ArgumentError, "inline_epp(): Invalid EPP: #{e.message}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Evaluate (and check template_args)
|
19
|
+
evaluate(parser, 'inline_epp', scope, false, result, template_args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.epp(scope, file, env_name, template_args = nil)
|
23
|
+
unless file.is_a? String
|
24
|
+
raise ArgumentError, "epp(): the first argument must be a String with the filename, got a #{file.class}"
|
25
|
+
end
|
26
|
+
|
27
|
+
file = file + ".epp" unless file =~ /\.epp$/
|
28
|
+
scope.debug "Retrieving epp template #{file}"
|
29
|
+
template_file = Puppet::Parser::Files.find_template(file, env_name)
|
30
|
+
unless template_file
|
31
|
+
raise Puppet::ParseError, "Could not find template '#{file}'"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Parse and validate the source
|
35
|
+
parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new
|
36
|
+
begin
|
37
|
+
result = parser.parse_file(template_file)
|
38
|
+
rescue Puppet::ParseError => e
|
39
|
+
raise ArgumentError, "epp(): Invalid EPP: #{e.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Evaluate (and check template_args)
|
43
|
+
evaluate(parser, 'epp', scope, true, result, template_args)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def self.evaluate(parser, func_name, scope, use_global_scope_only, parse_result, template_args)
|
49
|
+
template_args, template_args_set = handle_template_args(func_name, template_args)
|
50
|
+
|
51
|
+
body = parse_result.body
|
52
|
+
unless body.is_a?(Puppet::Pops::Model::LambdaExpression)
|
53
|
+
raise ArgumentError, "#{func_name}(): the parser did not produce a LambdaExpression, got '#{body.class}'"
|
54
|
+
end
|
55
|
+
unless body.body.is_a?(Puppet::Pops::Model::EppExpression)
|
56
|
+
raise ArgumentError, "#{func_name}(): the parser did not produce an EppExpression, got '#{body.body.class}'"
|
57
|
+
end
|
58
|
+
unless parse_result.definitions.empty?
|
59
|
+
raise ArgumentError, "#{func_name}(): The EPP template contains illegal expressions (definitions)"
|
60
|
+
end
|
61
|
+
|
62
|
+
see_scope = body.body.see_scope
|
63
|
+
if see_scope && !template_args_set
|
64
|
+
# no epp params and no arguments were given => inline_epp logic sees all local variables, epp all global
|
65
|
+
closure_scope = use_global_scope_only ? scope.find_global_scope : scope
|
66
|
+
spill_over = false
|
67
|
+
else
|
68
|
+
# no epp params or user provided arguments in a hash, epp logic only sees global + what was given
|
69
|
+
closure_scope = scope.find_global_scope
|
70
|
+
# given spill over if there are no params (e.g. replace closure scope by a new scope with the given args)
|
71
|
+
spill_over = see_scope
|
72
|
+
end
|
73
|
+
evaluated_result = parser.closure(body, closure_scope).call_by_name(scope, template_args, spill_over)
|
74
|
+
evaluated_result
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.handle_template_args(func_name, template_args)
|
78
|
+
if template_args.nil?
|
79
|
+
[{}, false]
|
80
|
+
else
|
81
|
+
unless template_args.is_a?(Hash)
|
82
|
+
raise ArgumentError, "#{func_name}(): the template_args must be a Hash, got a #{template_args.class}"
|
83
|
+
end
|
84
|
+
[template_args, true]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,1069 @@
|
|
1
|
+
require 'rgen/ecore/ecore'
|
2
|
+
require 'puppet/pops/evaluator/compare_operator'
|
3
|
+
require 'puppet/pops/evaluator/relationship_operator'
|
4
|
+
require 'puppet/pops/evaluator/access_operator'
|
5
|
+
require 'puppet/pops/evaluator/closure'
|
6
|
+
require 'puppet/pops/evaluator/external_syntax_support'
|
7
|
+
|
8
|
+
# This implementation of {Puppet::Pops::Evaluator} performs evaluation using the puppet 3.x runtime system
|
9
|
+
# in a manner largely compatible with Puppet 3.x, but adds new features and introduces constraints.
|
10
|
+
#
|
11
|
+
# The evaluation uses _polymorphic dispatch_ which works by dispatching to the first found method named after
|
12
|
+
# the class or one of its super-classes. The EvaluatorImpl itself mainly deals with evaluation (it currently
|
13
|
+
# also handles assignment), and it uses a delegation pattern to more specialized handlers of some operators
|
14
|
+
# that in turn use polymorphic dispatch; this to not clutter EvaluatorImpl with too much responsibility).
|
15
|
+
#
|
16
|
+
# Since a pattern is used, only the main entry points are fully documented. The parameters _o_ and _scope_ are
|
17
|
+
# the same in all the polymorphic methods, (the type of the parameter _o_ is reflected in the method's name;
|
18
|
+
# either the actual class, or one of its super classes). The _scope_ parameter is always the scope in which
|
19
|
+
# the evaluation takes place. If nothing else is mentioned, the return is always the result of evaluation.
|
20
|
+
#
|
21
|
+
# See {Puppet::Pops::Visitable} and {Puppet::Pops::Visitor} for more information about
|
22
|
+
# polymorphic calling.
|
23
|
+
#
|
24
|
+
class Puppet::Pops::Evaluator::EvaluatorImpl
|
25
|
+
include Puppet::Pops::Utils
|
26
|
+
|
27
|
+
# Provides access to the Puppet 3.x runtime (scope, etc.)
|
28
|
+
# This separation has been made to make it easier to later migrate the evaluator to an improved runtime.
|
29
|
+
#
|
30
|
+
include Puppet::Pops::Evaluator::Runtime3Support
|
31
|
+
include Puppet::Pops::Evaluator::ExternalSyntaxSupport
|
32
|
+
|
33
|
+
# This constant is not defined as Float::INFINITY in Ruby 1.8.7 (but is available in later version
|
34
|
+
# Refactor when support is dropped for Ruby 1.8.7.
|
35
|
+
#
|
36
|
+
INFINITY = 1.0 / 0.0
|
37
|
+
|
38
|
+
# Reference to Issues name space makes it easier to refer to issues
|
39
|
+
# (Issues are shared with the validator).
|
40
|
+
#
|
41
|
+
Issues = Puppet::Pops::Issues
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@@eval_visitor ||= Puppet::Pops::Visitor.new(self, "eval", 1, 1)
|
45
|
+
@@lvalue_visitor ||= Puppet::Pops::Visitor.new(self, "lvalue", 1, 1)
|
46
|
+
@@assign_visitor ||= Puppet::Pops::Visitor.new(self, "assign", 3, 3)
|
47
|
+
@@string_visitor ||= Puppet::Pops::Visitor.new(self, "string", 1, 1)
|
48
|
+
|
49
|
+
@@type_calculator ||= Puppet::Pops::Types::TypeCalculator.new()
|
50
|
+
@@type_parser ||= Puppet::Pops::Types::TypeParser.new()
|
51
|
+
|
52
|
+
@@compare_operator ||= Puppet::Pops::Evaluator::CompareOperator.new()
|
53
|
+
@@relationship_operator ||= Puppet::Pops::Evaluator::RelationshipOperator.new()
|
54
|
+
|
55
|
+
# Initialize the runtime module
|
56
|
+
Puppet::Pops::Evaluator::Runtime3Support.instance_method(:initialize).bind(self).call()
|
57
|
+
end
|
58
|
+
|
59
|
+
# @api private
|
60
|
+
def type_calculator
|
61
|
+
@@type_calculator
|
62
|
+
end
|
63
|
+
|
64
|
+
# Polymorphic evaluate - calls eval_TYPE
|
65
|
+
#
|
66
|
+
# ## Polymorphic evaluate
|
67
|
+
# Polymorphic evaluate calls a method on the format eval_TYPE where classname is the last
|
68
|
+
# part of the class of the given _target_. A search is performed starting with the actual class, continuing
|
69
|
+
# with each of the _target_ class's super classes until a matching method is found.
|
70
|
+
#
|
71
|
+
# # Description
|
72
|
+
# Evaluates the given _target_ object in the given scope, optionally passing a block which will be
|
73
|
+
# called with the result of the evaluation.
|
74
|
+
#
|
75
|
+
# @overload evaluate(target, scope, {|result| block})
|
76
|
+
# @param target [Object] evaluation target - see methods on the pattern assign_TYPE for actual supported types.
|
77
|
+
# @param scope [Object] the runtime specific scope class where evaluation should take place
|
78
|
+
# @return [Object] the result of the evaluation
|
79
|
+
#
|
80
|
+
# @api
|
81
|
+
#
|
82
|
+
def evaluate(target, scope)
|
83
|
+
begin
|
84
|
+
@@eval_visitor.visit_this_1(self, target, scope)
|
85
|
+
rescue StandardError => e
|
86
|
+
if e.is_a? Puppet::ParseError
|
87
|
+
raise e
|
88
|
+
end
|
89
|
+
fail(Issues::RUNTIME_ERROR, target, {:detail => e.message}, e)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Polymorphic assign - calls assign_TYPE
|
94
|
+
#
|
95
|
+
# ## Polymorphic assign
|
96
|
+
# Polymorphic assign calls a method on the format assign_TYPE where TYPE is the last
|
97
|
+
# part of the class of the given _target_. A search is performed starting with the actual class, continuing
|
98
|
+
# with each of the _target_ class's super classes until a matching method is found.
|
99
|
+
#
|
100
|
+
# # Description
|
101
|
+
# Assigns the given _value_ to the given _target_. The additional argument _o_ is the instruction that
|
102
|
+
# produced the target/value tuple and it is used to set the origin of the result.
|
103
|
+
# @param target [Object] assignment target - see methods on the pattern assign_TYPE for actual supported types.
|
104
|
+
# @param value [Object] the value to assign to `target`
|
105
|
+
# @param o [Puppet::Pops::Model::PopsObject] originating instruction
|
106
|
+
# @param scope [Object] the runtime specific scope where evaluation should take place
|
107
|
+
#
|
108
|
+
# @api
|
109
|
+
#
|
110
|
+
def assign(target, value, o, scope)
|
111
|
+
@@assign_visitor.visit_this_3(self, target, value, o, scope)
|
112
|
+
end
|
113
|
+
|
114
|
+
def lvalue(o, scope)
|
115
|
+
@@lvalue_visitor.visit_this_1(self, o, scope)
|
116
|
+
end
|
117
|
+
|
118
|
+
def string(o, scope)
|
119
|
+
@@string_visitor.visit_this_1(self, o, scope)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Call a closure matching arguments by name - Can only be called with a Closure (for now), may be refactored later
|
123
|
+
# to also handle other types of calls (function calls are also handled by CallNamedFunction and CallMethod, they
|
124
|
+
# could create similar objects to Closure, wait until other types of defines are instantiated - they may behave
|
125
|
+
# as special cases of calls - i.e. 'new').
|
126
|
+
#
|
127
|
+
# Call by name supports a "spill_over" mode where extra arguments in the given args_hash are introduced
|
128
|
+
# as variables in the resulting scope.
|
129
|
+
#
|
130
|
+
# @raise ArgumentError, if there are to many or too few arguments
|
131
|
+
# @raise ArgumentError, if given closure is not a Puppet::Pops::Evaluator::Closure
|
132
|
+
#
|
133
|
+
def call_by_name(closure, args_hash, scope, spill_over = false)
|
134
|
+
raise ArgumentError, "Can only call a Lambda" unless closure.is_a?(Puppet::Pops::Evaluator::Closure)
|
135
|
+
pblock = closure.model
|
136
|
+
parameters = pblock.parameters || []
|
137
|
+
|
138
|
+
if !spill_over && args_hash.size > parameters.size
|
139
|
+
raise ArgumentError, "Too many arguments: #{args_hash.size} for #{parameters.size}"
|
140
|
+
end
|
141
|
+
|
142
|
+
# associate values with parameters
|
143
|
+
scope_hash = {}
|
144
|
+
parameters.each do |p|
|
145
|
+
scope_hash[p.name] = args_hash[p.name] || evaluate(p.value, scope)
|
146
|
+
end
|
147
|
+
missing = scope_hash.reduce([]) {|memo, entry| memo << entry[0] if entry[1].nil?; memo }
|
148
|
+
unless missing.empty?
|
149
|
+
optional = parameters.count { |p| !p.value.nil? }
|
150
|
+
raise ArgumentError, "Too few arguments; no value given for required parameters #{missing.join(" ,")}"
|
151
|
+
end
|
152
|
+
if spill_over
|
153
|
+
# all args from given hash should be used, nil entries replaced by default values should win
|
154
|
+
scope_hash = args_hash.merge(scope_hash)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Store the evaluated name => value associations in a new inner/local/ephemeral scope
|
158
|
+
# (This is made complicated due to the fact that the implementation of scope is overloaded with
|
159
|
+
# functionality and an inner ephemeral scope must be used (as opposed to just pushing a local scope
|
160
|
+
# on a scope "stack").
|
161
|
+
|
162
|
+
# Ensure variable exists with nil value if error occurs.
|
163
|
+
# Some ruby implementations does not like creating variable on return
|
164
|
+
result = nil
|
165
|
+
begin
|
166
|
+
scope_memo = get_scope_nesting_level(scope)
|
167
|
+
# change to create local scope_from - cannot give it file and line - that is the place of the call, not
|
168
|
+
# "here"
|
169
|
+
create_local_scope_from(scope_hash, scope)
|
170
|
+
result = evaluate(pblock.body, scope)
|
171
|
+
ensure
|
172
|
+
set_scope_nesting_level(scope, scope_memo)
|
173
|
+
end
|
174
|
+
result
|
175
|
+
end
|
176
|
+
|
177
|
+
# Call a closure - Can only be called with a Closure (for now), may be refactored later
|
178
|
+
# to also handle other types of calls (function calls are also handled by CallNamedFunction and CallMethod, they
|
179
|
+
# could create similar objects to Closure, wait until other types of defines are instantiated - they may behave
|
180
|
+
# as special cases of calls - i.e. 'new')
|
181
|
+
#
|
182
|
+
# @raise ArgumentError, if there are to many or too few arguments
|
183
|
+
# @raise ArgumentError, if given closure is not a Puppet::Pops::Evaluator::Closure
|
184
|
+
#
|
185
|
+
def call(closure, args, scope)
|
186
|
+
raise ArgumentError, "Can only call a Lambda" unless closure.is_a?(Puppet::Pops::Evaluator::Closure)
|
187
|
+
pblock = closure.model
|
188
|
+
parameters = pblock.parameters || []
|
189
|
+
|
190
|
+
raise ArgumentError, "Too many arguments: #{args.size} for #{parameters.size}" unless args.size <= parameters.size
|
191
|
+
|
192
|
+
# associate values with parameters
|
193
|
+
merged = parameters.zip(args)
|
194
|
+
# calculate missing arguments
|
195
|
+
missing = parameters.slice(args.size, parameters.size - args.size).select {|p| p.value.nil? }
|
196
|
+
unless missing.empty?
|
197
|
+
optional = parameters.count { |p| !p.value.nil? }
|
198
|
+
raise ArgumentError, "Too few arguments; #{args.size} for #{optional > 0 ? ' min ' : ''}#{parameters.size - optional}"
|
199
|
+
end
|
200
|
+
|
201
|
+
evaluated = merged.collect do |m|
|
202
|
+
# m can be one of
|
203
|
+
# m = [Parameter{name => "name", value => nil], "given"]
|
204
|
+
# | [Parameter{name => "name", value => Expression}, "given"]
|
205
|
+
#
|
206
|
+
# "given" is always an optional entry. If a parameter was provided then
|
207
|
+
# the entry will be in the array, otherwise the m array will be a
|
208
|
+
# single element.a = []
|
209
|
+
given_argument = m[1]
|
210
|
+
argument_name = m[0].name
|
211
|
+
default_expression = m[0].value
|
212
|
+
|
213
|
+
value = if default_expression
|
214
|
+
evaluate(default_expression, scope)
|
215
|
+
else
|
216
|
+
given_argument
|
217
|
+
end
|
218
|
+
[argument_name, value]
|
219
|
+
end
|
220
|
+
|
221
|
+
# Store the evaluated name => value associations in a new inner/local/ephemeral scope
|
222
|
+
# (This is made complicated due to the fact that the implementation of scope is overloaded with
|
223
|
+
# functionality and an inner ephemeral scope must be used (as opposed to just pushing a local scope
|
224
|
+
# on a scope "stack").
|
225
|
+
|
226
|
+
# Ensure variable exists with nil value if error occurs.
|
227
|
+
# Some ruby implementations does not like creating variable on return
|
228
|
+
result = nil
|
229
|
+
begin
|
230
|
+
scope_memo = get_scope_nesting_level(scope)
|
231
|
+
# change to create local scope_from - cannot give it file and line - that is the place of the call, not
|
232
|
+
# "here"
|
233
|
+
create_local_scope_from(Hash[evaluated], scope)
|
234
|
+
result = evaluate(pblock.body, scope)
|
235
|
+
ensure
|
236
|
+
set_scope_nesting_level(scope, scope_memo)
|
237
|
+
end
|
238
|
+
result
|
239
|
+
end
|
240
|
+
|
241
|
+
protected
|
242
|
+
|
243
|
+
def lvalue_VariableExpression(o, scope)
|
244
|
+
# evaluate the name
|
245
|
+
evaluate(o.expr, scope)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Catches all illegal lvalues
|
249
|
+
#
|
250
|
+
def lvalue_Object(o, scope)
|
251
|
+
fail(Issues::ILLEGAL_ASSIGNMENT, o)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Assign value to named variable.
|
255
|
+
# The '$' sign is never part of the name.
|
256
|
+
# @example In Puppet DSL
|
257
|
+
# $name = value
|
258
|
+
# @param name [String] name of variable without $
|
259
|
+
# @param value [Object] value to assign to the variable
|
260
|
+
# @param o [Puppet::Pops::Model::PopsObject] originating instruction
|
261
|
+
# @param scope [Object] the runtime specific scope where evaluation should take place
|
262
|
+
# @return [value<Object>]
|
263
|
+
#
|
264
|
+
def assign_String(name, value, o, scope)
|
265
|
+
if name =~ /::/
|
266
|
+
fail(Issues::CROSS_SCOPE_ASSIGNMENT, o.left_expr, {:name => name})
|
267
|
+
end
|
268
|
+
set_variable(name, value, o, scope)
|
269
|
+
value
|
270
|
+
end
|
271
|
+
|
272
|
+
def assign_Numeric(n, value, o, scope)
|
273
|
+
fail(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o.left_expr, {:varname => n.to_s})
|
274
|
+
end
|
275
|
+
|
276
|
+
# Catches all illegal assignment (e.g. 1 = 2, {'a'=>1} = 2, etc)
|
277
|
+
#
|
278
|
+
def assign_Object(name, value, o, scope)
|
279
|
+
fail(Issues::ILLEGAL_ASSIGNMENT, o)
|
280
|
+
end
|
281
|
+
|
282
|
+
def eval_Factory(o, scope)
|
283
|
+
evaluate(o.current, scope)
|
284
|
+
end
|
285
|
+
|
286
|
+
# Evaluates any object not evaluated to something else to itself.
|
287
|
+
def eval_Object o, scope
|
288
|
+
o
|
289
|
+
end
|
290
|
+
|
291
|
+
# Allows nil to be used as a Nop.
|
292
|
+
# Evaluates to nil
|
293
|
+
# TODO: What is the difference between literal undef, nil, and nop?
|
294
|
+
#
|
295
|
+
def eval_NilClass(o, scope)
|
296
|
+
nil
|
297
|
+
end
|
298
|
+
|
299
|
+
# Evaluates Nop to nil.
|
300
|
+
# TODO: or is this the same as :undef
|
301
|
+
# TODO: is this even needed as a separate instruction when there is a literal undef?
|
302
|
+
def eval_Nop(o, scope)
|
303
|
+
nil
|
304
|
+
end
|
305
|
+
|
306
|
+
# Captures all LiteralValues not handled elsewhere.
|
307
|
+
#
|
308
|
+
def eval_LiteralValue(o, scope)
|
309
|
+
o.value
|
310
|
+
end
|
311
|
+
|
312
|
+
def eval_LiteralDefault(o, scope)
|
313
|
+
:default
|
314
|
+
end
|
315
|
+
|
316
|
+
def eval_LiteralUndef(o, scope)
|
317
|
+
:undef # TODO: or just use nil for this?
|
318
|
+
end
|
319
|
+
|
320
|
+
# A QualifiedReference (i.e. a capitalized qualified name such as Foo, or Foo::Bar) evaluates to a PType
|
321
|
+
#
|
322
|
+
def eval_QualifiedReference(o, scope)
|
323
|
+
@@type_parser.interpret(o)
|
324
|
+
end
|
325
|
+
|
326
|
+
def eval_NotExpression(o, scope)
|
327
|
+
! is_true?(evaluate(o.expr, scope))
|
328
|
+
end
|
329
|
+
|
330
|
+
def eval_UnaryMinusExpression(o, scope)
|
331
|
+
- coerce_numeric(evaluate(o.expr, scope), o, scope)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Abstract evaluation, returns array [left, right] with the evaluated result of left_expr and
|
335
|
+
# right_expr
|
336
|
+
# @return <Array<Object, Object>> array with result of evaluating left and right expressions
|
337
|
+
#
|
338
|
+
def eval_BinaryExpression o, scope
|
339
|
+
[ evaluate(o.left_expr, scope), evaluate(o.right_expr, scope) ]
|
340
|
+
end
|
341
|
+
|
342
|
+
# Evaluates assignment with operators =, +=, -= and
|
343
|
+
#
|
344
|
+
# @example Puppet DSL
|
345
|
+
# $a = 1
|
346
|
+
# $a += 1
|
347
|
+
# $a -= 1
|
348
|
+
#
|
349
|
+
def eval_AssignmentExpression(o, scope)
|
350
|
+
name = lvalue(o.left_expr, scope)
|
351
|
+
value = evaluate(o.right_expr, scope)
|
352
|
+
|
353
|
+
case o.operator
|
354
|
+
when :'=' # regular assignment
|
355
|
+
assign(name, value, o, scope)
|
356
|
+
|
357
|
+
when :'+='
|
358
|
+
# if value does not exist and strict is on, looking it up fails, else it is nil or :undef
|
359
|
+
existing_value = get_variable_value(name, o, scope)
|
360
|
+
begin
|
361
|
+
if existing_value.nil? || existing_value == :undef
|
362
|
+
assign(name, value, o, scope)
|
363
|
+
else
|
364
|
+
# Delegate to calculate function to deal with check of LHS, and perform ´+´ as arithmetic or concatenation the
|
365
|
+
# same way as ArithmeticExpression performs `+`.
|
366
|
+
assign(name, calculate(existing_value, value, :'+', o.left_expr, o.right_expr, scope), o, scope)
|
367
|
+
end
|
368
|
+
rescue ArgumentError => e
|
369
|
+
fail(Issues::APPEND_FAILED, o, {:message => e.message})
|
370
|
+
end
|
371
|
+
|
372
|
+
when :'-='
|
373
|
+
# If an attempt is made to delete values from something that does not exists, the value is :undef (it is guaranteed to not
|
374
|
+
# include any values the user wants deleted anyway :-)
|
375
|
+
#
|
376
|
+
# if value does not exist and strict is on, looking it up fails, else it is nil or :undef
|
377
|
+
existing_value = get_variable_value(name, o, scope)
|
378
|
+
begin
|
379
|
+
if existing_value.nil? || existing_value == :undef
|
380
|
+
assign(name, :undef, o, scope)
|
381
|
+
else
|
382
|
+
# Delegate to delete function to deal with check of LHS, and perform deletion
|
383
|
+
assign(name, delete(get_variable_value(name, o, scope), value), o, scope)
|
384
|
+
end
|
385
|
+
rescue ArgumentError => e
|
386
|
+
fail(Issues::APPEND_FAILED, o, {:message => e.message}, e)
|
387
|
+
end
|
388
|
+
else
|
389
|
+
fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator})
|
390
|
+
end
|
391
|
+
value
|
392
|
+
end
|
393
|
+
|
394
|
+
ARITHMETIC_OPERATORS = [:'+', :'-', :'*', :'/', :'%', :'<<', :'>>']
|
395
|
+
COLLECTION_OPERATORS = [:'+', :'-', :'<<']
|
396
|
+
|
397
|
+
# Handles binary expression where lhs and rhs are array/hash or numeric and operator is +, - , *, % / << >>
|
398
|
+
#
|
399
|
+
def eval_ArithmeticExpression(o, scope)
|
400
|
+
left, right = eval_BinaryExpression(o, scope)
|
401
|
+
begin
|
402
|
+
result = calculate(left, right, o.operator, o.left_expr, o.right_expr, scope)
|
403
|
+
rescue ArgumentError => e
|
404
|
+
fail(Issues::RUNTIME_ERROR, o, {:detail => e.message}, e)
|
405
|
+
end
|
406
|
+
result
|
407
|
+
end
|
408
|
+
|
409
|
+
|
410
|
+
# Handles binary expression where lhs and rhs are array/hash or numeric and operator is +, - , *, % / << >>
|
411
|
+
#
|
412
|
+
def calculate(left, right, operator, left_o, right_o, scope)
|
413
|
+
unless ARITHMETIC_OPERATORS.include?(operator)
|
414
|
+
fail(Issues::UNSUPPORTED_OPERATOR, left_o.eContainer, {:operator => o.operator})
|
415
|
+
end
|
416
|
+
|
417
|
+
if (left.is_a?(Array) || left.is_a?(Hash)) && COLLECTION_OPERATORS.include?(operator)
|
418
|
+
# Handle operation on collections
|
419
|
+
case operator
|
420
|
+
when :'+'
|
421
|
+
concatenate(left, right)
|
422
|
+
when :'-'
|
423
|
+
delete(left, right)
|
424
|
+
when :'<<'
|
425
|
+
unless left.is_a?(Array)
|
426
|
+
fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left})
|
427
|
+
end
|
428
|
+
left + [right]
|
429
|
+
end
|
430
|
+
else
|
431
|
+
# Handle operation on numeric
|
432
|
+
left = coerce_numeric(left, left_o, scope)
|
433
|
+
right = coerce_numeric(right, right_o, scope)
|
434
|
+
begin
|
435
|
+
if operator == :'%' && (left.is_a?(Float) || right.is_a?(Float))
|
436
|
+
# Deny users the fun of seeing severe rounding errors and confusing results
|
437
|
+
fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left})
|
438
|
+
end
|
439
|
+
result = left.send(operator, right)
|
440
|
+
rescue NoMethodError => e
|
441
|
+
fail(Issues::OPERATOR_NOT_APPLICABLE, left_o, {:operator => operator, :left_value => left})
|
442
|
+
rescue ZeroDivisionError => e
|
443
|
+
fail(Issues::DIV_BY_ZERO, right_o)
|
444
|
+
end
|
445
|
+
if result == INFINITY || result == -INFINITY
|
446
|
+
fail(Issues::RESULT_IS_INFINITY, left_o, {:operator => operator})
|
447
|
+
end
|
448
|
+
result
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
def eval_EppExpression(o, scope)
|
453
|
+
scope["@epp"] = []
|
454
|
+
evaluate(o.body, scope)
|
455
|
+
result = scope["@epp"].join('')
|
456
|
+
result
|
457
|
+
end
|
458
|
+
|
459
|
+
def eval_RenderStringExpression(o, scope)
|
460
|
+
scope["@epp"] << o.value.dup
|
461
|
+
nil
|
462
|
+
end
|
463
|
+
|
464
|
+
def eval_RenderExpression(o, scope)
|
465
|
+
scope["@epp"] << string(evaluate(o.expr, scope), scope)
|
466
|
+
nil
|
467
|
+
end
|
468
|
+
|
469
|
+
# Evaluates Puppet DSL ->, ~>, <-, and <~
|
470
|
+
def eval_RelationshipExpression(o, scope)
|
471
|
+
# First level evaluation, reduction to basic data types or puppet types, the relationship operator then translates this
|
472
|
+
# to the final set of references (turning strings into references, which can not naturally be done by the main evaluator since
|
473
|
+
# all strings should not be turned into references.
|
474
|
+
#
|
475
|
+
real = eval_BinaryExpression(o, scope)
|
476
|
+
@@relationship_operator.evaluate(real, o, scope)
|
477
|
+
end
|
478
|
+
|
479
|
+
# Evaluates x[key, key, ...]
|
480
|
+
#
|
481
|
+
def eval_AccessExpression(o, scope)
|
482
|
+
left = evaluate(o.left_expr, scope)
|
483
|
+
keys = o.keys.nil? ? [] : o.keys.collect {|key| evaluate(key, scope) }
|
484
|
+
Puppet::Pops::Evaluator::AccessOperator.new(o).access(left, scope, *keys)
|
485
|
+
end
|
486
|
+
|
487
|
+
# Evaluates <, <=, >, >=, and ==
|
488
|
+
#
|
489
|
+
def eval_ComparisonExpression o, scope
|
490
|
+
left, right = eval_BinaryExpression o, scope
|
491
|
+
|
492
|
+
begin
|
493
|
+
# Left is a type
|
494
|
+
if left.is_a?(Puppet::Pops::Types::PAbstractType)
|
495
|
+
case o.operator
|
496
|
+
when :'=='
|
497
|
+
@@type_calculator.equals(left,right)
|
498
|
+
|
499
|
+
when :'!='
|
500
|
+
!@@type_calculator.equals(left,right)
|
501
|
+
|
502
|
+
when :'<'
|
503
|
+
# left can be assigned to right, but they are not equal
|
504
|
+
@@type_calculator.assignable?(right, left) && ! @@type_calculator.equals(left,right)
|
505
|
+
when :'<='
|
506
|
+
# left can be assigned to right
|
507
|
+
@@type_calculator.assignable?(right, left)
|
508
|
+
when :'>'
|
509
|
+
# right can be assigned to left, but they are not equal
|
510
|
+
@@type_calculator.assignable?(left,right) && ! @@type_calculator.equals(left,right)
|
511
|
+
when :'>='
|
512
|
+
# right can be assigned to left
|
513
|
+
@@type_calculator.assignable?(left, right)
|
514
|
+
else
|
515
|
+
fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator})
|
516
|
+
end
|
517
|
+
else
|
518
|
+
case o.operator
|
519
|
+
when :'=='
|
520
|
+
@@compare_operator.equals(left,right)
|
521
|
+
when :'!='
|
522
|
+
! @@compare_operator.equals(left,right)
|
523
|
+
when :'<'
|
524
|
+
@@compare_operator.compare(left,right) < 0
|
525
|
+
when :'<='
|
526
|
+
@@compare_operator.compare(left,right) <= 0
|
527
|
+
when :'>'
|
528
|
+
@@compare_operator.compare(left,right) > 0
|
529
|
+
when :'>='
|
530
|
+
@@compare_operator.compare(left,right) >= 0
|
531
|
+
else
|
532
|
+
fail(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator})
|
533
|
+
end
|
534
|
+
end
|
535
|
+
rescue ArgumentError => e
|
536
|
+
fail(Issues::COMPARISON_NOT_POSSIBLE, o, {
|
537
|
+
:operator => o.operator,
|
538
|
+
:left_value => left,
|
539
|
+
:right_value => right,
|
540
|
+
:detail => e.message}, e)
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
# Evaluates matching expressions with type, string or regexp rhs expression.
|
545
|
+
# If RHS is a type, the =~ matches compatible (assignable?) type.
|
546
|
+
#
|
547
|
+
# @example
|
548
|
+
# x =~ /abc.*/
|
549
|
+
# @example
|
550
|
+
# x =~ "abc.*/"
|
551
|
+
# @example
|
552
|
+
# y = "abc"
|
553
|
+
# x =~ "${y}.*"
|
554
|
+
# @example
|
555
|
+
# [1,2,3] =~ Array[Integer[1,10]]
|
556
|
+
# @return [Boolean] if a match was made or not. Also sets $0..$n to matchdata in current scope.
|
557
|
+
#
|
558
|
+
def eval_MatchExpression o, scope
|
559
|
+
left, pattern = eval_BinaryExpression o, scope
|
560
|
+
# matches RHS types as instance of for all types except a parameterized Regexp[R]
|
561
|
+
if pattern.is_a?(Puppet::Pops::Types::PAbstractType)
|
562
|
+
if pattern.is_a?(Puppet::Pops::Types::PRegexpType) && pattern.pattern
|
563
|
+
# A qualified PRegexpType, get its ruby regexp
|
564
|
+
pattern = pattern.regexp
|
565
|
+
else
|
566
|
+
# evaluate as instance?
|
567
|
+
matched = @@type_calculator.instance?(pattern, left)
|
568
|
+
# convert match result to Boolean true, or false
|
569
|
+
return o.operator == :'=~' ? !!matched : !matched
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
begin
|
574
|
+
pattern = Regexp.new(pattern) unless pattern.is_a?(Regexp)
|
575
|
+
rescue StandardError => e
|
576
|
+
fail(Issues::MATCH_NOT_REGEXP, o.right_expr, {:detail => e.message}, e)
|
577
|
+
end
|
578
|
+
unless left.is_a?(String)
|
579
|
+
fail(Issues::MATCH_NOT_STRING, o.left_expr, {:left_value => left})
|
580
|
+
end
|
581
|
+
|
582
|
+
matched = pattern.match(left) # nil, or MatchData
|
583
|
+
set_match_data(matched, o, scope) # creates ephemeral
|
584
|
+
|
585
|
+
# convert match result to Boolean true, or false
|
586
|
+
o.operator == :'=~' ? !!matched : !matched
|
587
|
+
end
|
588
|
+
|
589
|
+
# Evaluates Puppet DSL `in` expression
|
590
|
+
#
|
591
|
+
def eval_InExpression o, scope
|
592
|
+
left, right = eval_BinaryExpression o, scope
|
593
|
+
@@compare_operator.include?(right, left)
|
594
|
+
end
|
595
|
+
|
596
|
+
# @example
|
597
|
+
# $a and $b
|
598
|
+
# b is only evaluated if a is true
|
599
|
+
#
|
600
|
+
def eval_AndExpression o, scope
|
601
|
+
is_true?(evaluate(o.left_expr, scope)) ? is_true?(evaluate(o.right_expr, scope)) : false
|
602
|
+
end
|
603
|
+
|
604
|
+
# @example
|
605
|
+
# a or b
|
606
|
+
# b is only evaluated if a is false
|
607
|
+
#
|
608
|
+
def eval_OrExpression o, scope
|
609
|
+
is_true?(evaluate(o.left_expr, scope)) ? true : is_true?(evaluate(o.right_expr, scope))
|
610
|
+
end
|
611
|
+
|
612
|
+
# Evaluates each entry of the literal list and creates a new Array
|
613
|
+
# @return [Array] with the evaluated content
|
614
|
+
#
|
615
|
+
def eval_LiteralList o, scope
|
616
|
+
o.values.collect {|expr| evaluate(expr, scope)}
|
617
|
+
end
|
618
|
+
|
619
|
+
# Evaluates each entry of the literal hash and creates a new Hash.
|
620
|
+
# @return [Hash] with the evaluated content
|
621
|
+
#
|
622
|
+
def eval_LiteralHash o, scope
|
623
|
+
h = Hash.new
|
624
|
+
o.entries.each {|entry| h[ evaluate(entry.key, scope)]= evaluate(entry.value, scope)}
|
625
|
+
h
|
626
|
+
end
|
627
|
+
|
628
|
+
# Evaluates all statements and produces the last evaluated value
|
629
|
+
#
|
630
|
+
def eval_BlockExpression o, scope
|
631
|
+
r = nil
|
632
|
+
o.statements.each {|s| r = evaluate(s, scope)}
|
633
|
+
r
|
634
|
+
end
|
635
|
+
|
636
|
+
# Performs optimized search over case option values, lazily evaluating each
|
637
|
+
# until there is a match. If no match is found, the case expression's default expression
|
638
|
+
# is evaluated (it may be nil or Nop if there is no default, thus producing nil).
|
639
|
+
# If an option matches, the result of evaluating that option is returned.
|
640
|
+
# @return [Object, nil] what a matched option returns, or nil if nothing matched.
|
641
|
+
#
|
642
|
+
def eval_CaseExpression(o, scope)
|
643
|
+
# memo scope level before evaluating test - don't want a match in the case test to leak $n match vars
|
644
|
+
# to expressions after the case expression.
|
645
|
+
#
|
646
|
+
with_guarded_scope(scope) do
|
647
|
+
test = evaluate(o.test, scope)
|
648
|
+
result = nil
|
649
|
+
the_default = nil
|
650
|
+
if o.options.find do |co|
|
651
|
+
# the first case option that matches
|
652
|
+
if co.values.find do |c|
|
653
|
+
the_default = co.then_expr if c.is_a? Puppet::Pops::Model::LiteralDefault
|
654
|
+
is_match?(test, evaluate(c, scope), c, scope)
|
655
|
+
end
|
656
|
+
result = evaluate(co.then_expr, scope)
|
657
|
+
true # the option was picked
|
658
|
+
end
|
659
|
+
end
|
660
|
+
result # an option was picked, and produced a result
|
661
|
+
else
|
662
|
+
evaluate(the_default, scope) # evaluate the default (should be a nop/nil) if there is no default).
|
663
|
+
end
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
# Evaluates a CollectExpression by transforming it into a 3x AST::Collection and then evaluating that.
|
668
|
+
# This is done because of the complex API between compiler, indirector, backends, and difference between
|
669
|
+
# collecting virtual resources and exported resources.
|
670
|
+
#
|
671
|
+
def eval_CollectExpression o, scope
|
672
|
+
# The Collect Expression and its contained query expressions are implemented in such a way in
|
673
|
+
# 3x that it is almost impossible to do anything about them (the AST objects are lazily evaluated,
|
674
|
+
# and the built structure consists of both higher order functions and arrays with query expressions
|
675
|
+
# that are either used as a predicate filter, or given to an indirection terminus (such as the Puppet DB
|
676
|
+
# resource terminus). Unfortunately, the 3x implementation has many inconsistencies that the implementation
|
677
|
+
# below carries forward.
|
678
|
+
#
|
679
|
+
collect_3x = Puppet::Pops::Model::AstTransformer.new().transform(o)
|
680
|
+
collected = collect_3x.evaluate(scope)
|
681
|
+
# the 3x returns an instance of Parser::Collector (but it is only registered with the compiler at this
|
682
|
+
# point and does not contain any valuable information (like the result)
|
683
|
+
# Dilemma: If this object is returned, it is a first class value in the Puppet Language and we
|
684
|
+
# need to be able to perform operations on it. We can forbid it from leaking by making CollectExpression
|
685
|
+
# a non R-value. This makes it possible for the evaluator logic to make use of the Collector.
|
686
|
+
collected
|
687
|
+
end
|
688
|
+
|
689
|
+
def eval_ParenthesizedExpression(o, scope)
|
690
|
+
evaluate(o.expr, scope)
|
691
|
+
end
|
692
|
+
|
693
|
+
# This evaluates classes, nodes and resource type definitions to nil, since 3x:
|
694
|
+
# instantiates them, and evaluates their parameters and body. This is achieved by
|
695
|
+
# providing bridge AST classes in Puppet::Parser::AST::PopsBridge that bridges a
|
696
|
+
# Pops Program and a Pops Expression.
|
697
|
+
#
|
698
|
+
# Since all Definitions are handled "out of band", they are treated as a no-op when
|
699
|
+
# evaluated.
|
700
|
+
#
|
701
|
+
def eval_Definition(o, scope)
|
702
|
+
nil
|
703
|
+
end
|
704
|
+
|
705
|
+
def eval_Program(o, scope)
|
706
|
+
evaluate(o.body, scope)
|
707
|
+
end
|
708
|
+
|
709
|
+
# Produces Array[PObjectType], an array of resource references
|
710
|
+
#
|
711
|
+
def eval_ResourceExpression(o, scope)
|
712
|
+
exported = o.exported
|
713
|
+
virtual = o.virtual
|
714
|
+
type_name = evaluate(o.type_name, scope)
|
715
|
+
o.bodies.map do |body|
|
716
|
+
titles = [evaluate(body.title, scope)].flatten
|
717
|
+
evaluated_parameters = body.operations.map {|op| evaluate(op, scope) }
|
718
|
+
create_resources(o, scope, virtual, exported, type_name, titles, evaluated_parameters)
|
719
|
+
end.flatten.compact
|
720
|
+
end
|
721
|
+
|
722
|
+
def eval_ResourceOverrideExpression(o, scope)
|
723
|
+
evaluated_resources = evaluate(o.resources, scope)
|
724
|
+
evaluated_parameters = o.operations.map { |op| evaluate(op, scope) }
|
725
|
+
create_resource_overrides(o, scope, [evaluated_resources].flatten, evaluated_parameters)
|
726
|
+
evaluated_resources
|
727
|
+
end
|
728
|
+
|
729
|
+
# Produces 3x array of parameters
|
730
|
+
def eval_AttributeOperation(o, scope)
|
731
|
+
create_resource_parameter(o, scope, o.attribute_name, evaluate(o.value_expr, scope), o.operator)
|
732
|
+
end
|
733
|
+
|
734
|
+
# Sets default parameter values for a type, produces the type
|
735
|
+
#
|
736
|
+
def eval_ResourceDefaultsExpression(o, scope)
|
737
|
+
type_name = o.type_ref.value # a QualifiedName's string value
|
738
|
+
evaluated_parameters = o.operations.map {|op| evaluate(op, scope) }
|
739
|
+
create_resource_defaults(o, scope, type_name, evaluated_parameters)
|
740
|
+
# Produce the type
|
741
|
+
evaluate(o.type_ref, scope)
|
742
|
+
end
|
743
|
+
|
744
|
+
# Evaluates function call by name.
|
745
|
+
#
|
746
|
+
def eval_CallNamedFunctionExpression(o, scope)
|
747
|
+
# The functor expression is not evaluated, it is not possible to select the function to call
|
748
|
+
# via an expression like $a()
|
749
|
+
case o.functor_expr
|
750
|
+
when Puppet::Pops::Model::QualifiedName
|
751
|
+
# ok
|
752
|
+
when Puppet::Pops::Model::RenderStringExpression
|
753
|
+
# helpful to point out this easy to make Epp error
|
754
|
+
fail(Issues::ILLEGAL_EPP_PARAMETERS, o)
|
755
|
+
else
|
756
|
+
fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o})
|
757
|
+
end
|
758
|
+
name = o.functor_expr.value
|
759
|
+
assert_function_available(name, o, scope)
|
760
|
+
evaluated_arguments = o.arguments.collect {|arg| evaluate(arg, scope) }
|
761
|
+
# wrap lambda in a callable block if it is present
|
762
|
+
evaluated_arguments << Puppet::Pops::Evaluator::Closure.new(self, o.lambda, scope) if o.lambda
|
763
|
+
call_function(name, evaluated_arguments, o, scope) do |result|
|
764
|
+
# prevent functions that are not r-value from leaking its return value
|
765
|
+
rvalue_function?(name, o, scope) ? result : nil
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
# Evaluation of CallMethodExpression handles a NamedAccessExpression functor (receiver.function_name)
|
770
|
+
#
|
771
|
+
def eval_CallMethodExpression(o, scope)
|
772
|
+
unless o.functor_expr.is_a? Puppet::Pops::Model::NamedAccessExpression
|
773
|
+
fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function accessor', :container => o})
|
774
|
+
end
|
775
|
+
receiver = evaluate(o.functor_expr.left_expr, scope)
|
776
|
+
name = o.functor_expr.right_expr
|
777
|
+
unless name.is_a? Puppet::Pops::Model::QualifiedName
|
778
|
+
fail(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o})
|
779
|
+
end
|
780
|
+
name = name.value # the string function name
|
781
|
+
assert_function_available(name, o, scope)
|
782
|
+
evaluated_arguments = [receiver] + (o.arguments || []).collect {|arg| evaluate(arg, scope) }
|
783
|
+
evaluated_arguments << Puppet::Pops::Evaluator::Closure.new(self, o.lambda, scope) if o.lambda
|
784
|
+
call_function(name, evaluated_arguments, o, scope) do |result|
|
785
|
+
# prevent functions that are not r-value from leaking its return value
|
786
|
+
rvalue_function?(name, o, scope) ? result : nil
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
# @example
|
791
|
+
# $x ? { 10 => true, 20 => false, default => 0 }
|
792
|
+
#
|
793
|
+
def eval_SelectorExpression o, scope
|
794
|
+
# memo scope level before evaluating test - don't want a match in the case test to leak $n match vars
|
795
|
+
# to expressions after the selector expression.
|
796
|
+
#
|
797
|
+
with_guarded_scope(scope) do
|
798
|
+
test = evaluate(o.left_expr, scope)
|
799
|
+
selected = o.selectors.find do |s|
|
800
|
+
candidate = evaluate(s.matching_expr, scope)
|
801
|
+
candidate == :default || is_match?(test, candidate, s.matching_expr, scope)
|
802
|
+
end
|
803
|
+
if selected
|
804
|
+
evaluate(selected.value_expr, scope)
|
805
|
+
else
|
806
|
+
nil
|
807
|
+
end
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
# SubLocatable is simply an expression that holds location information
|
812
|
+
def eval_SubLocatedExpression o, scope
|
813
|
+
evaluate(o.expr, scope)
|
814
|
+
end
|
815
|
+
|
816
|
+
# Evaluates Puppet DSL Heredoc
|
817
|
+
def eval_HeredocExpression o, scope
|
818
|
+
result = evaluate(o.text_expr, scope)
|
819
|
+
assert_external_syntax(scope, result, o.syntax, o.text_expr)
|
820
|
+
result
|
821
|
+
end
|
822
|
+
|
823
|
+
# Evaluates Puppet DSL `if`
|
824
|
+
def eval_IfExpression o, scope
|
825
|
+
with_guarded_scope(scope) do
|
826
|
+
if is_true?(evaluate(o.test, scope))
|
827
|
+
evaluate(o.then_expr, scope)
|
828
|
+
else
|
829
|
+
evaluate(o.else_expr, scope)
|
830
|
+
end
|
831
|
+
end
|
832
|
+
end
|
833
|
+
|
834
|
+
# Evaluates Puppet DSL `unless`
|
835
|
+
def eval_UnlessExpression o, scope
|
836
|
+
with_guarded_scope(scope) do
|
837
|
+
unless is_true?(evaluate(o.test, scope))
|
838
|
+
evaluate(o.then_expr, scope)
|
839
|
+
else
|
840
|
+
evaluate(o.else_expr, scope)
|
841
|
+
end
|
842
|
+
end
|
843
|
+
end
|
844
|
+
|
845
|
+
# Evaluates a variable (getting its value)
|
846
|
+
# The evaluator is lenient; any expression producing a String is used as a name
|
847
|
+
# of a variable.
|
848
|
+
#
|
849
|
+
def eval_VariableExpression o, scope
|
850
|
+
# Evaluator is not too fussy about what constitutes a name as long as the result
|
851
|
+
# is a String and a valid variable name
|
852
|
+
#
|
853
|
+
name = evaluate(o.expr, scope)
|
854
|
+
|
855
|
+
# Should be caught by validation, but make this explicit here as well, or mysterious evaluation issues
|
856
|
+
# may occur.
|
857
|
+
case name
|
858
|
+
when String
|
859
|
+
when Numeric
|
860
|
+
else
|
861
|
+
fail(Issues::ILLEGAL_VARIABLE_EXPRESSION, o.expr)
|
862
|
+
end
|
863
|
+
# TODO: Check for valid variable name (Task for validator)
|
864
|
+
# TODO: semantics of undefined variable in scope, this just returns what scope does == value or nil
|
865
|
+
get_variable_value(name, o, scope)
|
866
|
+
end
|
867
|
+
|
868
|
+
# Evaluates double quoted strings that may contain interpolation
|
869
|
+
#
|
870
|
+
def eval_ConcatenatedString o, scope
|
871
|
+
o.segments.collect {|expr| string(evaluate(expr, scope), scope)}.join
|
872
|
+
end
|
873
|
+
|
874
|
+
|
875
|
+
# If the wrapped expression is a QualifiedName, it is taken as the name of a variable in scope.
|
876
|
+
# Note that this is different from the 3.x implementation, where an initial qualified name
|
877
|
+
# is accepted. (e.g. `"---${var + 1}---"` is legal. This implementation requires such concrete
|
878
|
+
# syntax to be expressed in a model as `(TextExpression (+ (Variable var) 1)` - i.e. moving the decision to
|
879
|
+
# the parser.
|
880
|
+
#
|
881
|
+
# Semantics; the result of an expression is turned into a string, nil is silently transformed to empty
|
882
|
+
# string.
|
883
|
+
# @return [String] the interpolated result
|
884
|
+
#
|
885
|
+
def eval_TextExpression o, scope
|
886
|
+
if o.expr.is_a?(Puppet::Pops::Model::QualifiedName)
|
887
|
+
# TODO: formalize, when scope returns nil, vs error
|
888
|
+
string(get_variable_value(o.expr.value, o, scope), scope)
|
889
|
+
else
|
890
|
+
string(evaluate(o.expr, scope), scope)
|
891
|
+
end
|
892
|
+
end
|
893
|
+
|
894
|
+
def string_Object(o, scope)
|
895
|
+
o.to_s
|
896
|
+
end
|
897
|
+
|
898
|
+
def string_Symbol(o, scope)
|
899
|
+
case o
|
900
|
+
when :undef
|
901
|
+
''
|
902
|
+
else
|
903
|
+
o.to_s
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
def string_Array(o, scope)
|
908
|
+
['[', o.map {|e| string(e, scope)}.join(', '), ']'].join()
|
909
|
+
end
|
910
|
+
|
911
|
+
def string_Hash(o, scope)
|
912
|
+
['{', o.map {|k,v| string(k, scope) + " => " + string(v, scope)}.join(', '), '}'].join()
|
913
|
+
end
|
914
|
+
|
915
|
+
def string_Regexp(o, scope)
|
916
|
+
['/', o.source, '/'].join()
|
917
|
+
end
|
918
|
+
|
919
|
+
def string_PAbstractType(o, scope)
|
920
|
+
@@type_calculator.string(o)
|
921
|
+
end
|
922
|
+
|
923
|
+
# Produces concatenation / merge of x and y.
|
924
|
+
#
|
925
|
+
# When x is an Array, y of type produces:
|
926
|
+
#
|
927
|
+
# * Array => concatenation `[1,2], [3,4] => [1,2,3,4]`
|
928
|
+
# * Hash => concatenation of hash as array `[key, value, key, value, ...]`
|
929
|
+
# * any other => concatenation of single value
|
930
|
+
#
|
931
|
+
# When x is a Hash, y of type produces:
|
932
|
+
#
|
933
|
+
# * Array => merge of array interpreted as `[key, value, key, value,...]`
|
934
|
+
# * Hash => a merge, where entries in `y` overrides
|
935
|
+
# * any other => error
|
936
|
+
#
|
937
|
+
# When x is something else, wrap it in an array first.
|
938
|
+
#
|
939
|
+
# When x is nil, an empty array is used instead.
|
940
|
+
#
|
941
|
+
# @note to concatenate an Array, nest the array - i.e. `[1,2], [[2,3]]`
|
942
|
+
#
|
943
|
+
# @overload concatenate(obj_x, obj_y)
|
944
|
+
# @param obj_x [Object] object to wrap in an array and concatenate to; see other overloaded methods for return type
|
945
|
+
# @param ary_y [Object] array to concatenate at end of `ary_x`
|
946
|
+
# @return [Object] wraps obj_x in array before using other overloaded option based on type of obj_y
|
947
|
+
# @overload concatenate(ary_x, ary_y)
|
948
|
+
# @param ary_x [Array] array to concatenate to
|
949
|
+
# @param ary_y [Array] array to concatenate at end of `ary_x`
|
950
|
+
# @return [Array] new array with `ary_x` + `ary_y`
|
951
|
+
# @overload concatenate(ary_x, hsh_y)
|
952
|
+
# @param ary_x [Array] array to concatenate to
|
953
|
+
# @param hsh_y [Hash] converted to array form, and concatenated to array
|
954
|
+
# @return [Array] new array with `ary_x` + `hsh_y` converted to array
|
955
|
+
# @overload concatenate (ary_x, obj_y)
|
956
|
+
# @param ary_x [Array] array to concatenate to
|
957
|
+
# @param obj_y [Object] non array or hash object to add to array
|
958
|
+
# @return [Array] new array with `ary_x` + `obj_y` added as last entry
|
959
|
+
# @overload concatenate(hsh_x, ary_y)
|
960
|
+
# @param hsh_x [Hash] the hash to merge with
|
961
|
+
# @param ary_y [Array] array interpreted as even numbered sequence of key, value merged with `hsh_x`
|
962
|
+
# @return [Hash] new hash with `hsh_x` merged with `ary_y` interpreted as hash in array form
|
963
|
+
# @overload concatenate(hsh_x, hsh_y)
|
964
|
+
# @param hsh_x [Hash] the hash to merge to
|
965
|
+
# @param hsh_y [Hash] hash merged with `hsh_x`
|
966
|
+
# @return [Hash] new hash with `hsh_x` merged with `hsh_y`
|
967
|
+
# @raise [ArgumentError] when `xxx_x` is neither an Array nor a Hash
|
968
|
+
# @raise [ArgumentError] when `xxx_x` is a Hash, and `xxx_y` is neither Array nor Hash.
|
969
|
+
#
|
970
|
+
def concatenate(x, y)
|
971
|
+
x = [x] unless x.is_a?(Array) || x.is_a?(Hash)
|
972
|
+
case x
|
973
|
+
when Array
|
974
|
+
y = case y
|
975
|
+
when Array then y
|
976
|
+
when Hash then y.to_a
|
977
|
+
else
|
978
|
+
[y]
|
979
|
+
end
|
980
|
+
x + y # new array with concatenation
|
981
|
+
when Hash
|
982
|
+
y = case y
|
983
|
+
when Hash then y
|
984
|
+
when Array
|
985
|
+
# Hash[[a, 1, b, 2]] => {}
|
986
|
+
# Hash[a,1,b,2] => {a => 1, b => 2}
|
987
|
+
# Hash[[a,1], [b,2]] => {[a,1] => [b,2]}
|
988
|
+
# Hash[[[a,1], [b,2]]] => {a => 1, b => 2}
|
989
|
+
# Use type calcultor to determine if array is Array[Array[?]], and if so use second form
|
990
|
+
# of call
|
991
|
+
t = @@type_calculator.infer(y)
|
992
|
+
if t.element_type.is_a? Puppet::Pops::Types::PArrayType
|
993
|
+
Hash[y]
|
994
|
+
else
|
995
|
+
Hash[*y]
|
996
|
+
end
|
997
|
+
else
|
998
|
+
raise ArgumentError.new("Can only append Array or Hash to a Hash")
|
999
|
+
end
|
1000
|
+
x.merge y # new hash with overwrite
|
1001
|
+
else
|
1002
|
+
raise ArgumentError.new("Can only append to an Array or a Hash.")
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
# Produces the result x \ y (set difference)
|
1007
|
+
# When `x` is an Array, `y` is transformed to an array and then all matching elements removed from x.
|
1008
|
+
# When `x` is a Hash, all contained keys are removed from x as listed in `y` if it is an Array, or all its keys if it is a Hash.
|
1009
|
+
# The difference is returned. The given `x` and `y` are not modified by this operation.
|
1010
|
+
# @raise [ArgumentError] when `x` is neither an Array nor a Hash
|
1011
|
+
#
|
1012
|
+
def delete(x, y)
|
1013
|
+
result = x.dup
|
1014
|
+
case x
|
1015
|
+
when Array
|
1016
|
+
y = case y
|
1017
|
+
when Array then y
|
1018
|
+
when Hash then y.to_a
|
1019
|
+
else
|
1020
|
+
[y]
|
1021
|
+
end
|
1022
|
+
y.each {|e| result.delete(e) }
|
1023
|
+
when Hash
|
1024
|
+
y = case y
|
1025
|
+
when Array then y
|
1026
|
+
when Hash then y.keys
|
1027
|
+
else
|
1028
|
+
[y]
|
1029
|
+
end
|
1030
|
+
y.each {|e| result.delete(e) }
|
1031
|
+
else
|
1032
|
+
raise ArgumentError.new("Can only delete from an Array or Hash.")
|
1033
|
+
end
|
1034
|
+
result
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
# Implementation of case option matching.
|
1038
|
+
#
|
1039
|
+
# This is the type of matching performed in a case option, using == for every type
|
1040
|
+
# of value except regular expression where a match is performed.
|
1041
|
+
#
|
1042
|
+
def is_match? left, right, o, scope
|
1043
|
+
if right.is_a?(Regexp)
|
1044
|
+
return false unless left.is_a? String
|
1045
|
+
matched = right.match(left)
|
1046
|
+
set_match_data(matched, o, scope) # creates or clears ephemeral
|
1047
|
+
!!matched # convert to boolean
|
1048
|
+
elsif right.is_a?(Puppet::Pops::Types::PAbstractType)
|
1049
|
+
# right is a type and left is not - check if left is an instance of the given type
|
1050
|
+
# (The reverse is not terribly meaningful - computing which of the case options that first produces
|
1051
|
+
# an instance of a given type).
|
1052
|
+
#
|
1053
|
+
@@type_calculator.instance?(right, left)
|
1054
|
+
else
|
1055
|
+
# Handle equality the same way as the language '==' operator (case insensitive etc.)
|
1056
|
+
@@compare_operator.equals(left,right)
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
def with_guarded_scope(scope)
|
1061
|
+
scope_memo = get_scope_nesting_level(scope)
|
1062
|
+
begin
|
1063
|
+
yield
|
1064
|
+
ensure
|
1065
|
+
set_scope_nesting_level(scope, scope_memo)
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
end
|