puppet 3.5.1-x86-mingw32 → 3.6.0.rc1-x86-mingw32
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 +5 -0
- data/Gemfile +17 -9
- data/README.md +1 -0
- data/conf/fileserver.conf +4 -3
- data/ext/README.environment +8 -0
- data/ext/build_defaults.yaml +1 -1
- data/ext/debian/control +2 -2
- data/ext/debian/puppet-common.dirs +4 -0
- data/ext/debian/rules +4 -0
- data/ext/emacs/puppet-mode-init.el +1 -1
- data/ext/emacs/puppet-mode.el +36 -17
- data/ext/redhat/client.init +3 -3
- data/ext/redhat/puppet.spec.erb +9 -0
- data/ext/systemd/puppet.service +3 -4
- data/ext/systemd/puppetmaster.service +1 -3
- data/install.rb +1 -1
- data/lib/puppet.rb +2 -1
- data/lib/puppet/agent.rb +1 -1
- data/lib/puppet/application.rb +17 -17
- data/lib/puppet/application/doc.rb +1 -1
- data/lib/puppet/configurer.rb +4 -1
- data/lib/puppet/configurer/downloader.rb +13 -12
- data/lib/puppet/configurer/plugin_handler.rb +3 -3
- data/lib/puppet/context.rb +6 -1
- data/lib/puppet/defaults.rb +82 -12
- data/lib/puppet/environments.rb +169 -13
- data/lib/puppet/external/nagios/grammar.ry +2 -0
- data/lib/puppet/external/nagios/parser.rb +28 -19
- data/lib/puppet/face/config.rb +19 -6
- data/lib/puppet/face/module/generate.rb +209 -7
- data/lib/puppet/face/module/install.rb +17 -16
- data/lib/puppet/face/module/list.rb +83 -82
- data/lib/puppet/face/module/search.rb +1 -1
- data/lib/puppet/face/module/upgrade.rb +10 -9
- data/lib/puppet/face/parser.rb +3 -2
- data/lib/puppet/face/plugin.rb +8 -4
- data/lib/puppet/file_bucket/dipper.rb +6 -3
- data/lib/puppet/file_bucket/file.rb +4 -2
- data/lib/puppet/file_serving/metadata.rb +1 -1
- data/lib/puppet/file_system/memory_file.rb +27 -1
- data/lib/puppet/file_system/memory_impl.rb +15 -1
- data/lib/puppet/forge.rb +148 -52
- data/lib/puppet/forge/cache.rb +5 -1
- data/lib/puppet/forge/errors.rb +10 -0
- data/lib/puppet/forge/repository.rb +61 -26
- data/lib/puppet/functions.rb +548 -0
- data/lib/puppet/functions/assert_type.rb +42 -0
- data/lib/puppet/functions/import.rb +7 -0
- data/lib/puppet/indirector/facts/facter.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
- data/lib/puppet/indirector/rest.rb +18 -0
- data/lib/puppet/loaders.rb +20 -0
- data/lib/puppet/module.rb +2 -2
- data/lib/puppet/module_tool.rb +40 -14
- data/lib/puppet/module_tool/applications.rb +0 -1
- data/lib/puppet/module_tool/applications/application.rb +35 -26
- data/lib/puppet/module_tool/applications/builder.rb +16 -6
- data/lib/puppet/module_tool/applications/checksummer.rb +25 -19
- data/lib/puppet/module_tool/applications/installer.rb +196 -35
- data/lib/puppet/module_tool/applications/searcher.rb +1 -0
- data/lib/puppet/module_tool/applications/uninstaller.rb +7 -1
- data/lib/puppet/module_tool/applications/unpacker.rb +57 -31
- data/lib/puppet/module_tool/applications/upgrader.rb +221 -65
- data/lib/puppet/module_tool/checksums.rb +5 -8
- data/lib/puppet/module_tool/errors/installer.rb +12 -44
- data/lib/puppet/module_tool/errors/shared.rb +84 -11
- data/lib/puppet/module_tool/errors/upgrader.rb +16 -45
- data/lib/puppet/module_tool/install_directory.rb +7 -6
- data/lib/puppet/module_tool/installed_modules.rb +92 -0
- data/lib/puppet/module_tool/local_tarball.rb +91 -0
- data/lib/puppet/module_tool/metadata.rb +119 -115
- data/lib/puppet/module_tool/modulefile.rb +9 -9
- data/lib/puppet/module_tool/shared_behaviors.rb +19 -7
- data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +79 -0
- data/lib/puppet/module_tool/skeleton/templates/generator/Rakefile +18 -0
- data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json.erb +1 -0
- data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +7 -0
- data/lib/puppet/module_tool/tar.rb +3 -7
- data/lib/puppet/module_tool/tar/gnu.rb +21 -9
- data/lib/puppet/module_tool/tar/mini.rb +2 -8
- data/lib/puppet/network/http/api/v1.rb +1 -1
- data/lib/puppet/network/http/api/v2/authorization.rb +4 -2
- data/lib/puppet/network/http/issues.rb +1 -0
- data/lib/puppet/network/http_pool.rb +15 -6
- data/lib/puppet/node/environment.rb +91 -20
- data/lib/puppet/parser/ast/pops_bridge.rb +44 -3
- data/lib/puppet/parser/collector.rb +1 -1
- data/lib/puppet/parser/compiler.rb +50 -7
- data/lib/puppet/parser/functions.rb +6 -0
- data/lib/puppet/parser/functions/generate.rb +1 -1
- data/lib/puppet/parser/resource.rb +1 -1
- data/lib/puppet/pops.rb +22 -1
- data/lib/puppet/pops/adapters.rb +8 -1
- data/lib/puppet/pops/binder/bindings_composer.rb +1 -1
- data/lib/puppet/pops/binder/bindings_factory.rb +1 -1
- data/lib/puppet/pops/binder/config/binder_config_checker.rb +1 -1
- data/lib/puppet/pops/binder/producers.rb +2 -2
- data/lib/puppet/pops/evaluator/access_operator.rb +65 -25
- data/lib/puppet/pops/evaluator/callable_signature.rb +101 -0
- data/lib/puppet/pops/evaluator/closure.rb +57 -2
- data/lib/puppet/pops/evaluator/compare_operator.rb +1 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -11
- data/lib/puppet/pops/evaluator/runtime3_support.rb +72 -21
- data/lib/puppet/pops/functions/dispatch.rb +71 -0
- data/lib/puppet/pops/functions/dispatcher.rb +237 -0
- data/lib/puppet/pops/functions/function.rb +77 -0
- data/lib/puppet/pops/issues.rb +12 -0
- data/lib/puppet/pops/loader/base_loader.rb +102 -0
- data/lib/puppet/pops/loader/dependency_loader.rb +60 -0
- data/lib/puppet/pops/loader/gem_support.rb +49 -0
- data/lib/puppet/pops/loader/loader.rb +180 -0
- data/lib/puppet/pops/loader/loader_paths.rb +137 -0
- data/lib/puppet/pops/loader/module_loaders.rb +242 -0
- data/lib/puppet/pops/loader/null_loader.rb +44 -0
- data/lib/puppet/pops/loader/ruby_function_instantiator.rb +34 -0
- data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +109 -0
- data/lib/puppet/pops/loader/simple_environment_loader.rb +20 -0
- data/lib/puppet/pops/loader/static_loader.rb +69 -0
- data/lib/puppet/pops/loader/uri_helper.rb +22 -0
- data/lib/puppet/pops/loaders.rb +240 -0
- data/lib/puppet/pops/model/factory.rb +13 -5
- data/lib/puppet/pops/model/model_tree_dumper.rb +12 -4
- data/lib/puppet/pops/parser/egrammar.ra +31 -18
- data/lib/puppet/pops/parser/eparser.rb +1137 -1106
- data/lib/puppet/pops/parser/lexer2.rb +17 -16
- data/lib/puppet/pops/semantic_error.rb +17 -0
- data/lib/puppet/pops/types/type_calculator.rb +150 -15
- data/lib/puppet/pops/types/type_factory.rb +69 -0
- data/lib/puppet/pops/types/type_parser.rb +9 -0
- data/lib/puppet/pops/types/types.rb +65 -4
- data/lib/puppet/pops/validation/checker4_0.rb +1 -1
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -1
- data/lib/puppet/property/list.rb +1 -1
- data/lib/puppet/provider/augeas/augeas.rb +2 -2
- data/lib/puppet/provider/cron/crontab.rb +13 -2
- data/lib/puppet/provider/package.rb +24 -0
- data/lib/puppet/provider/package/apt.rb +6 -1
- data/lib/puppet/provider/package/gem.rb +8 -2
- data/lib/puppet/provider/package/msi.rb +0 -15
- data/lib/puppet/provider/package/openbsd.rb +0 -24
- data/lib/puppet/provider/package/rpm.rb +3 -29
- data/lib/puppet/provider/package/windows.rb +0 -15
- data/lib/puppet/provider/package/yum.rb +101 -24
- data/lib/puppet/provider/package/yumhelper.py +31 -1
- data/lib/puppet/provider/package/zypper.rb +10 -28
- data/lib/puppet/provider/service/debian.rb +1 -1
- data/lib/puppet/provider/service/init.rb +3 -0
- data/lib/puppet/provider/service/openbsd.rb +318 -0
- data/lib/puppet/provider/service/redhat.rb +6 -3
- data/lib/puppet/provider/service/systemd.rb +2 -2
- data/lib/puppet/provider/yumrepo/inifile.rb +115 -42
- data/lib/puppet/resource.rb +13 -9
- data/lib/puppet/resource/catalog.rb +12 -6
- data/lib/puppet/resource/type_collection.rb +3 -3
- data/lib/puppet/settings.rb +57 -36
- data/lib/puppet/settings/config_file.rb +5 -0
- data/lib/puppet/settings/environment_conf.rb +147 -0
- data/lib/puppet/settings/ttl_setting.rb +48 -0
- data/lib/puppet/ssl/certificate_authority.rb +2 -3
- data/lib/puppet/ssl/certificate_authority/autosign_command.rb +1 -1
- data/lib/puppet/ssl/certificate_request.rb +4 -4
- data/lib/puppet/ssl/validator/default_validator.rb +2 -2
- data/lib/puppet/status.rb +1 -1
- data/lib/puppet/test/test_helper.rb +1 -0
- data/lib/puppet/type/augeas.rb +13 -1
- data/lib/puppet/type/cron.rb +32 -18
- data/lib/puppet/type/file.rb +4 -2
- data/lib/puppet/type/file/checksum.rb +15 -5
- data/lib/puppet/type/file/content.rb +3 -1
- data/lib/puppet/type/file/source.rb +5 -5
- data/lib/puppet/type/package.rb +12 -17
- data/lib/puppet/type/resources.rb +3 -1
- data/lib/puppet/type/scheduled_task.rb +4 -5
- data/lib/puppet/type/service.rb +12 -2
- data/lib/puppet/type/user.rb +106 -0
- data/lib/puppet/type/yumrepo.rb +9 -1
- data/lib/puppet/util/checksums.rb +60 -1
- data/lib/puppet/util/diff.rb +3 -1
- data/lib/puppet/util/execution.rb +20 -16
- data/lib/puppet/util/feature.rb +3 -0
- data/lib/puppet/util/logging.rb +19 -12
- data/lib/puppet/util/rubygems.rb +10 -0
- data/lib/puppet/util/watched_file.rb +1 -1
- data/lib/puppet/util/windows/security.rb +5 -3
- data/lib/puppet/vendor/load_semantic.rb +1 -0
- data/lib/puppet/vendor/require_vendored.rb +2 -0
- data/lib/puppet/vendor/semantic/Gemfile +20 -0
- data/lib/puppet/vendor/semantic/Rakefile +69 -0
- data/lib/puppet/vendor/semantic/lib/semantic.rb +7 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency.rb +181 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph.rb +60 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph_node.rb +117 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency/module_release.rb +46 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency/source.rb +25 -0
- data/lib/puppet/vendor/semantic/lib/semantic/dependency/unsatisfiable_graph.rb +31 -0
- data/lib/puppet/vendor/semantic/lib/semantic/version.rb +168 -0
- data/lib/puppet/vendor/semantic/lib/semantic/version_range.rb +424 -0
- data/lib/puppet/vendor/semantic/spec/spec_helper.rb +24 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_node_spec.rb +141 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_spec.rb +162 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/module_release_spec.rb +143 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/source_spec.rb +5 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/unsatisfiable_graph_spec.rb +44 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency_spec.rb +383 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/version_range_spec.rb +307 -0
- data/lib/puppet/vendor/semantic/spec/unit/semantic/version_spec.rb +608 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/java.tgz +0 -0
- data/spec/fixtures/stdlib.tgz +0 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/usee/lib/puppet/functions/usee/callee.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/lib/puppet/functions/user/caller.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/metadata.json +9 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/modulea/rb_func_a.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/rb_func_a.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/manifests/init.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +19 -0
- data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/lib/puppet/functions/moduleb/rb_func_b.rb +6 -0
- data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/manifests/init.pp +3 -0
- data/spec/fixtures/unit/provider/naginator/define_empty_param +6 -0
- data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +7 -0
- data/spec/fixtures/unit/type/user/authorized_keys +5 -0
- data/spec/integration/application/apply_spec.rb +1 -2
- data/spec/integration/configurer_spec.rb +2 -2
- data/spec/integration/faces/plugin_spec.rb +62 -0
- data/spec/integration/indirector/catalog/compiler_spec.rb +1 -1
- data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
- data/spec/integration/node/environment_spec.rb +2 -2
- data/spec/integration/parser/future_compiler_spec.rb +96 -142
- data/spec/integration/parser/ruby_manifest_spec.rb +0 -5
- data/spec/integration/provider/cron/crontab_spec.rb +35 -0
- data/spec/integration/type/file_spec.rb +74 -72
- data/spec/integration/util/windows/security_spec.rb +17 -0
- data/spec/lib/matchers/resource.rb +45 -13
- data/spec/lib/puppet_spec/files.rb +18 -0
- data/spec/lib/puppet_spec/module_tool/shared_functions.rb +56 -0
- data/spec/lib/puppet_spec/module_tool/stub_source.rb +133 -0
- data/spec/shared_contexts/checksums.rb +55 -0
- data/spec/unit/application/apply_spec.rb +10 -7
- data/spec/unit/application/doc_spec.rb +17 -10
- data/spec/unit/application/indirection_base_spec.rb +18 -10
- data/spec/unit/application/inspect_spec.rb +22 -20
- data/spec/unit/configurer/downloader_spec.rb +7 -6
- data/spec/unit/configurer/plugin_handler_spec.rb +5 -8
- data/spec/unit/configurer_spec.rb +1 -1
- data/spec/unit/context_spec.rb +23 -0
- data/spec/unit/environments_spec.rb +274 -16
- data/spec/unit/face/config_spec.rb +111 -11
- data/spec/unit/face/module/install_spec.rb +14 -85
- data/spec/unit/face/module/list_spec.rb +108 -62
- data/spec/unit/face/module/search_spec.rb +1 -1
- data/spec/unit/face/module/uninstall_spec.rb +21 -42
- data/spec/unit/face/parser_spec.rb +5 -2
- data/spec/unit/file_bucket/dipper_spec.rb +92 -86
- data/spec/unit/file_bucket/file_spec.rb +23 -75
- data/spec/unit/file_serving/metadata_spec.rb +74 -74
- data/spec/unit/forge/module_release_spec.rb +131 -0
- data/spec/unit/forge/repository_spec.rb +21 -20
- data/spec/unit/forge_spec.rb +99 -23
- data/spec/unit/functions/assert_type_spec.rb +59 -0
- data/spec/unit/functions4_spec.rb +671 -0
- data/spec/unit/indirector/catalog/static_compiler_spec.rb +2 -2
- data/spec/unit/indirector/facts/facter_spec.rb +9 -3
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +156 -155
- data/spec/unit/indirector/rest_spec.rb +8 -0
- data/spec/unit/interface/face_collection_spec.rb +35 -23
- data/spec/unit/module_spec.rb +20 -8
- data/spec/unit/module_tool/applications/builder_spec.rb +40 -12
- data/spec/unit/module_tool/applications/checksummer_spec.rb +86 -105
- data/spec/unit/module_tool/applications/installer_spec.rb +293 -261
- data/spec/unit/module_tool/applications/searcher_spec.rb +1 -1
- data/spec/unit/module_tool/applications/uninstaller_spec.rb +90 -154
- data/spec/unit/module_tool/applications/unpacker_spec.rb +12 -12
- data/spec/unit/module_tool/applications/upgrader_spec.rb +286 -18
- data/spec/unit/module_tool/metadata_spec.rb +223 -14
- data/spec/unit/module_tool/tar/gnu_spec.rb +12 -9
- data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
- data/spec/unit/module_tool/tar_spec.rb +4 -18
- data/spec/unit/module_tool_spec.rb +123 -27
- data/spec/unit/network/formats_spec.rb +2 -2
- data/spec/unit/network/http_pool_spec.rb +21 -0
- data/spec/unit/network/rights_spec.rb +10 -8
- data/spec/unit/node/environment_spec.rb +27 -2
- data/spec/unit/parser/collector_spec.rb +1 -1
- data/spec/unit/parser/compiler_spec.rb +1 -1
- data/spec/unit/parser/functions/generate_spec.rb +4 -0
- data/spec/unit/pops/evaluator/access_ops_spec.rb +50 -11
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +25 -0
- data/spec/unit/pops/loaders/dependency_loader_spec.rb +44 -0
- data/spec/unit/pops/loaders/loader_paths_spec.rb +66 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +105 -0
- data/spec/unit/pops/loaders/module_loaders_spec.rb +119 -0
- data/spec/unit/pops/loaders/static_loader_spec.rb +46 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +145 -10
- data/spec/unit/pops/types/type_factory_spec.rb +101 -0
- data/spec/unit/pops/types/type_parser_spec.rb +22 -0
- data/spec/unit/property/list_spec.rb +9 -1
- data/spec/unit/provider/augeas/augeas_spec.rb +58 -11
- data/spec/unit/provider/cron/crontab_spec.rb +1 -0
- data/spec/unit/provider/cron/parsed_spec.rb +15 -0
- data/spec/unit/provider/naginator_spec.rb +14 -0
- data/spec/unit/provider/package/apt_spec.rb +78 -64
- data/spec/unit/provider/package/gem_spec.rb +15 -0
- data/spec/unit/provider/package/rpm_spec.rb +6 -6
- data/spec/unit/provider/package/windows_spec.rb +1 -1
- data/spec/unit/provider/package/yum_spec.rb +199 -104
- data/spec/unit/provider/package/zypper_spec.rb +41 -15
- data/spec/unit/provider/service/openbsd_spec.rb +129 -22
- data/spec/unit/provider/service/redhat_spec.rb +18 -4
- data/spec/unit/provider/service/systemd_spec.rb +5 -9
- data/spec/unit/provider/service/upstart_spec.rb +1 -1
- data/spec/unit/provider/user/directoryservice_spec.rb +10 -0
- data/spec/unit/provider/yumrepo/inifile_spec.rb +171 -15
- data/spec/unit/resource/catalog_spec.rb +20 -104
- data/spec/unit/resource/type_collection_spec.rb +10 -9
- data/spec/unit/settings/config_file_spec.rb +29 -6
- data/spec/unit/settings/environment_conf_spec.rb +51 -0
- data/spec/unit/settings_spec.rb +97 -12
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -0
- data/spec/unit/type/augeas_spec.rb +1 -1
- data/spec/unit/type/cron_spec.rb +6 -7
- data/spec/unit/type/file/checksum_spec.rb +6 -0
- data/spec/unit/type/file/content_spec.rb +277 -207
- data/spec/unit/type/file_spec.rb +9 -7
- data/spec/unit/type/user_spec.rb +106 -18
- data/spec/unit/type/yumrepo_spec.rb +8 -0
- data/spec/unit/util/checksums_spec.rb +12 -5
- data/spec/unit/util/diff_spec.rb +8 -0
- data/spec/unit/util/execution_spec.rb +4 -4
- data/spec/unit/util/feature_spec.rb +2 -0
- data/spec/unit/util/logging_spec.rb +14 -4
- data/spec/unit/util/rdoc/parser_spec.rb +5 -4
- data/spec/unit/util/rubygems_spec.rb +14 -0
- data/tasks/parallel.rake +2 -2
- metadata +154 -21
- checksums.yaml +0 -7
- data/lib/puppet/module_tool/applications/generator.rb +0 -142
- data/lib/puppet/module_tool/skeleton.rb +0 -37
- data/lib/puppet/module_tool/skeleton/templates/generator/Modulefile.erb +0 -11
- data/lib/puppet/module_tool/skeleton/templates/generator/README.erb +0 -16
- data/lib/puppet/module_tool/tar/solaris.rb +0 -5
- data/spec/fixtures/unit/provider/service/systemd/list_units_services +0 -17
- data/spec/unit/module_tool/tar/solaris_spec.rb +0 -22
data/lib/puppet/forge/cache.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
|
+
require 'puppet/forge'
|
4
|
+
|
3
5
|
class Puppet::Forge
|
4
6
|
# = Cache
|
5
7
|
#
|
@@ -44,7 +46,9 @@ class Puppet::Forge
|
|
44
46
|
|
45
47
|
# Return the base Pathname for all the caches.
|
46
48
|
def self.base_path
|
47
|
-
Pathname(Puppet.settings[:module_working_dir]) + 'cache'
|
49
|
+
(Pathname(Puppet.settings[:module_working_dir]) + 'cache').tap do |o|
|
50
|
+
o.mkpath unless o.exist?
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
54
|
# Clean out all the caches.
|
data/lib/puppet/forge/errors.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'puppet/error'
|
3
|
+
require 'puppet/forge'
|
2
4
|
|
3
5
|
# Puppet::Forge specific exceptions
|
4
6
|
module Puppet::Forge::Errors
|
@@ -80,6 +82,14 @@ Could not connect to #{@uri}
|
|
80
82
|
response = options[:response]
|
81
83
|
@response = "#{response.code} #{response.message.strip}"
|
82
84
|
|
85
|
+
begin
|
86
|
+
body = JSON.parse(response.body)
|
87
|
+
if body['message']
|
88
|
+
@message ||= body['message'].strip
|
89
|
+
end
|
90
|
+
rescue JSON::ParserError
|
91
|
+
end
|
92
|
+
|
83
93
|
message = "Could not execute operation for '#{@input}'. Detail: "
|
84
94
|
message << @message << " / " if @message
|
85
95
|
message << @response << "."
|
@@ -2,6 +2,8 @@ require 'net/https'
|
|
2
2
|
require 'digest/sha1'
|
3
3
|
require 'uri'
|
4
4
|
require 'puppet/util/http_proxy'
|
5
|
+
require 'puppet/forge'
|
6
|
+
require 'puppet/forge/errors'
|
5
7
|
|
6
8
|
if Puppet.features.zlib? && Puppet[:zlib]
|
7
9
|
require 'zlib'
|
@@ -35,21 +37,39 @@ class Puppet::Forge
|
|
35
37
|
end
|
36
38
|
|
37
39
|
# Instantiate a new repository instance rooted at the +url+.
|
38
|
-
# The
|
39
|
-
|
40
|
-
|
41
|
-
@
|
40
|
+
# The library will report +for_agent+ in the User-Agent to the repository.
|
41
|
+
def initialize(host, for_agent)
|
42
|
+
@host = host
|
43
|
+
@agent = for_agent
|
42
44
|
@cache = Cache.new(self)
|
43
|
-
@
|
45
|
+
@uri = URI.parse(host)
|
44
46
|
end
|
45
47
|
|
46
|
-
# Return a Net::HTTPResponse read for this +
|
47
|
-
def make_http_request(
|
48
|
-
|
49
|
-
|
48
|
+
# Return a Net::HTTPResponse read for this +path+.
|
49
|
+
def make_http_request(path, io = nil)
|
50
|
+
Puppet.debug "HTTP GET #{@host}#{path}"
|
51
|
+
request = get_request_object(path)
|
52
|
+
return read_response(request, io)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_request_object(path)
|
56
|
+
headers = {
|
57
|
+
"User-Agent" => user_agent,
|
58
|
+
}
|
59
|
+
|
60
|
+
if Puppet.features.zlib? && Puppet[:zlib] && RUBY_VERSION >= "1.9"
|
61
|
+
headers = headers.merge({
|
62
|
+
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
request = Net::HTTP::Get.new(URI.escape(path), headers)
|
67
|
+
|
68
|
+
unless @uri.user.nil? || @uri.password.nil?
|
50
69
|
request.basic_auth(@uri.user, @uri.password)
|
51
70
|
end
|
52
|
-
|
71
|
+
|
72
|
+
return request
|
53
73
|
end
|
54
74
|
|
55
75
|
# Return a Net::HTTPResponse read from this HTTPRequest +request+.
|
@@ -60,11 +80,27 @@ class Puppet::Forge
|
|
60
80
|
# related error
|
61
81
|
# @raise [Puppet::Forge::Errors::SSLVerifyError] if there is a problem
|
62
82
|
# verifying the remote SSL certificate
|
63
|
-
def read_response(request)
|
83
|
+
def read_response(request, io = nil)
|
64
84
|
http_object = get_http_object
|
65
85
|
|
66
86
|
http_object.start do |http|
|
67
|
-
http.request(request)
|
87
|
+
response = http.request(request)
|
88
|
+
|
89
|
+
if Puppet.features.zlib? && Puppet[:zlib]
|
90
|
+
if response && response.key?("content-encoding")
|
91
|
+
case response["content-encoding"]
|
92
|
+
when "gzip"
|
93
|
+
response.body = Zlib::GzipReader.new(StringIO.new(response.read_body), :encoding => "ASCII-8BIT").read
|
94
|
+
response.delete("content-encoding")
|
95
|
+
when "deflate"
|
96
|
+
response.body = Zlib::Inflate.inflate(response.read_body)
|
97
|
+
response.delete("content-encoding")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
io.write(response.body) if io.respond_to? :write
|
103
|
+
response
|
68
104
|
end
|
69
105
|
rescue *NET_HTTP_EXCEPTIONS => e
|
70
106
|
raise CommunicationError.new(:uri => @uri.to_s, :original => e)
|
@@ -103,33 +139,32 @@ class Puppet::Forge
|
|
103
139
|
# Return the local file name containing the data downloaded from the
|
104
140
|
# repository at +release+ (e.g. "myuser-mymodule").
|
105
141
|
def retrieve(release)
|
106
|
-
|
107
|
-
|
108
|
-
return cache.retrieve(uri)
|
142
|
+
path = @host.chomp('/') + release
|
143
|
+
return cache.retrieve(path)
|
109
144
|
end
|
110
145
|
|
111
146
|
# Return the URI string for this repository.
|
112
147
|
def to_s
|
113
|
-
|
148
|
+
"#<#{self.class} #{@host}>"
|
114
149
|
end
|
115
150
|
|
116
151
|
# Return the cache key for this repository, this a hashed string based on
|
117
152
|
# the URI.
|
118
153
|
def cache_key
|
119
154
|
return @cache_key ||= [
|
120
|
-
@
|
121
|
-
Digest::SHA1.hexdigest(@
|
122
|
-
].join('-')
|
155
|
+
@host.to_s.gsub(/[^[:alnum:]]+/, '_').sub(/_$/, ''),
|
156
|
+
Digest::SHA1.hexdigest(@host.to_s)
|
157
|
+
].join('-').freeze
|
123
158
|
end
|
124
159
|
|
125
|
-
|
126
|
-
"#{@consumer_version} Puppet/#{Puppet.version} (#{Facter.value(:operatingsystem)} #{Facter.value(:operatingsystemrelease)}) #{ruby_version}"
|
127
|
-
end
|
128
|
-
private :user_agent
|
160
|
+
private
|
129
161
|
|
130
|
-
def
|
131
|
-
|
162
|
+
def user_agent
|
163
|
+
@user_agent ||= [
|
164
|
+
@agent,
|
165
|
+
"Puppet/#{Puppet.version}",
|
166
|
+
"Ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})",
|
167
|
+
].join(' ').freeze
|
132
168
|
end
|
133
|
-
private :ruby_version
|
134
169
|
end
|
135
170
|
end
|
@@ -0,0 +1,548 @@
|
|
1
|
+
# @note WARNING: This new function API is still under development and may change at any time
|
2
|
+
#
|
3
|
+
# Functions in the puppet language can be written in Ruby and distributed in
|
4
|
+
# puppet modules. The function is written by creating a file in the module's
|
5
|
+
# `lib/puppet/functions/<modulename>` directory, where `<modulename>` is
|
6
|
+
# replaced with the module's name. The file should have the name of the function.
|
7
|
+
# For example, to create a function named `min` in a module named `math` create
|
8
|
+
# a file named `lib/puppet/functions/math/min.rb` in the module.
|
9
|
+
#
|
10
|
+
# A function is implemented by calling {Puppet::Functions.create_function}, and
|
11
|
+
# passing it a block that defines the implementation of the function.
|
12
|
+
#
|
13
|
+
# Functions are namespaced inside the module that contains them. The name of
|
14
|
+
# the function is prefixed with the name of the module. For example,
|
15
|
+
# `math::min`.
|
16
|
+
#
|
17
|
+
# @example A simple function
|
18
|
+
# Puppet::Functions.create_function('math::min') do
|
19
|
+
# def min(a, b)
|
20
|
+
# a <= b ? a : b
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Anatomy of a function
|
25
|
+
# ---
|
26
|
+
#
|
27
|
+
# Functions are composed of four parts: the name, the implementation methods,
|
28
|
+
# the signatures, and the dispatches.
|
29
|
+
#
|
30
|
+
# The name is the string given to the {Puppet::Functions.create_function}
|
31
|
+
# method. It specifies the name to use when calling the function in the puppet
|
32
|
+
# language, or from other functions.
|
33
|
+
#
|
34
|
+
# The implementation methods are ruby methods (there can be one or more) that
|
35
|
+
# provide that actual implementation of the function's behavior. In the
|
36
|
+
# simplest case the name of the function (excluding any namespace) and the name
|
37
|
+
# of the method are the same. When that is done no other parts (signatures and
|
38
|
+
# dispatches) need to be used.
|
39
|
+
#
|
40
|
+
# Signatures are a way of specifying the types of the function's parameters.
|
41
|
+
# The types of any arguments will be checked against the types declared in the
|
42
|
+
# signature and an error will be produced if they don't match. The types are
|
43
|
+
# defined by using the same syntax for types as in the puppet language.
|
44
|
+
#
|
45
|
+
# Dispatches are how signatures and implementation methods are tied together.
|
46
|
+
# When the function is called, puppet searches the signatures for one that
|
47
|
+
# matches the supplied arguments. Each signature is part of a dispatch, which
|
48
|
+
# specifies the method that should be called for that signature. When a
|
49
|
+
# matching signature is found, the corrosponding method is called.
|
50
|
+
#
|
51
|
+
# Documentation for the function should be placed as comments to the
|
52
|
+
# implementation method(s).
|
53
|
+
#
|
54
|
+
# @todo Documentation for individual instances of these new functions is not
|
55
|
+
# yet tied into the puppet doc system.
|
56
|
+
#
|
57
|
+
# @example Dispatching to different methods by type
|
58
|
+
# Puppet::Functions.create_function('math::min') do
|
59
|
+
# dispatch :numeric_min do
|
60
|
+
# param 'Numeric', 'a'
|
61
|
+
# param 'Numeric', 'b'
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# dispatch :string_min do
|
65
|
+
# param 'String', 'a'
|
66
|
+
# param 'String', 'b'
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# def numeric_min(a, b)
|
70
|
+
# a <= b ? a : b
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# def string_min(a, b)
|
74
|
+
# a.downcase <= b.downcase ? a : b
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# Specifying Signatures
|
79
|
+
# ---
|
80
|
+
#
|
81
|
+
# If nothing is specified, the number of arguments given to the function must
|
82
|
+
# be the same as the number of parameters, and all of the parameters are of
|
83
|
+
# type 'Object'.
|
84
|
+
#
|
85
|
+
# To express that the last parameter captures the rest, the method
|
86
|
+
# `last_captures_rest` can be called. This indicates that the last parameter is
|
87
|
+
# a varargs parameter and will be passed to the implementing method as an array
|
88
|
+
# of the given type.
|
89
|
+
#
|
90
|
+
# When defining a dispatch for a function, the resulting dispatch matches
|
91
|
+
# against the specified argument types and min/max occurrence of optional
|
92
|
+
# entries. When the dispatch makes the call to the implementation method the
|
93
|
+
# arguments are simply passed and it is the responsibility of the method's
|
94
|
+
# implementor to ensure it can handle those arguments (i.e. there is no check
|
95
|
+
# that what was declared as optional actually has a default value, and that
|
96
|
+
# a "captures rest" is declared using a `*`).
|
97
|
+
#
|
98
|
+
# @example Varargs
|
99
|
+
# Puppet::Functions.create_function('foo') do
|
100
|
+
# dispatch :foo do
|
101
|
+
# param 'Numeric', 'first'
|
102
|
+
# param 'Numeric', 'values'
|
103
|
+
# last_captures_rest
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# def foo(first, *values)
|
107
|
+
# # do something
|
108
|
+
# end
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# Access to Scope
|
112
|
+
# ---
|
113
|
+
# In general, functions should not need access to scope; they should be
|
114
|
+
# written to act on their given input only. If they absolutely must look up
|
115
|
+
# variable values, they should do so via the closure scope (the scope where
|
116
|
+
# they are defined) - this is done by calling `closure_scope()`.
|
117
|
+
#
|
118
|
+
# Calling other Functions
|
119
|
+
# ---
|
120
|
+
# Calling other functions by name is directly supported via
|
121
|
+
# {Puppet::Pops::Functions::Function#call_function}. This allows a function to
|
122
|
+
# call other functions visible from its loader.
|
123
|
+
#
|
124
|
+
# @api public
|
125
|
+
module Puppet::Functions
|
126
|
+
# @param func_name [String, Symbol] a simple or qualified function name
|
127
|
+
# @param block [Proc] the block that defines the methods and dispatch of the
|
128
|
+
# Function to create
|
129
|
+
# @return [Class<Function>] the newly created Function class
|
130
|
+
#
|
131
|
+
# @api public
|
132
|
+
def self.create_function(func_name, function_base = Function, &block)
|
133
|
+
if function_base.ancestors.none? { |s| s == Puppet::Pops::Functions::Function }
|
134
|
+
raise ArgumentError, "Functions must be based on Puppet::Pops::Functions::Function. Got #{function_base}"
|
135
|
+
end
|
136
|
+
|
137
|
+
func_name = func_name.to_s
|
138
|
+
# Creates an anonymous class to represent the function
|
139
|
+
# The idea being that it is garbage collected when there are no more
|
140
|
+
# references to it.
|
141
|
+
#
|
142
|
+
the_class = Class.new(function_base, &block)
|
143
|
+
|
144
|
+
# Make the anonymous class appear to have the class-name <func_name>
|
145
|
+
# Even if this class is not bound to such a symbol in a global ruby scope and
|
146
|
+
# must be resolved via the loader.
|
147
|
+
# This also overrides any attempt to define a name method in the given block
|
148
|
+
# (Since it redefines it)
|
149
|
+
#
|
150
|
+
# TODO, enforce name in lower case (to further make it stand out since Ruby
|
151
|
+
# class names are upper case)
|
152
|
+
#
|
153
|
+
the_class.instance_eval do
|
154
|
+
@func_name = func_name
|
155
|
+
def name
|
156
|
+
@func_name
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Automatically create an object dispatcher based on introspection if the
|
161
|
+
# loaded user code did not define any dispatchers. Fail if function name
|
162
|
+
# does not match a given method name in user code.
|
163
|
+
#
|
164
|
+
if the_class.dispatcher.empty?
|
165
|
+
simple_name = func_name.split(/::/)[-1]
|
166
|
+
type, names = default_dispatcher(the_class, simple_name)
|
167
|
+
last_captures_rest = (type.size_range[1] == Puppet::Pops::Types::INFINITY)
|
168
|
+
the_class.dispatcher.add_dispatch(type, simple_name, names, nil, nil, nil, last_captures_rest)
|
169
|
+
end
|
170
|
+
|
171
|
+
# The function class is returned as the result of the create function method
|
172
|
+
the_class
|
173
|
+
end
|
174
|
+
|
175
|
+
# Creates a default dispatcher configured from a method with the same name as the function
|
176
|
+
#
|
177
|
+
# @api private
|
178
|
+
def self.default_dispatcher(the_class, func_name)
|
179
|
+
unless the_class.method_defined?(func_name)
|
180
|
+
raise ArgumentError, "Function Creation Error, cannot create a default dispatcher for function '#{func_name}', no method with this name found"
|
181
|
+
end
|
182
|
+
object_signature(*min_max_param(the_class.instance_method(func_name)))
|
183
|
+
end
|
184
|
+
|
185
|
+
# @api private
|
186
|
+
def self.min_max_param(method)
|
187
|
+
# Ruby 1.8.7 does not have support for details about parameters
|
188
|
+
if method.respond_to?(:parameters)
|
189
|
+
result = {:req => 0, :opt => 0, :rest => 0 }
|
190
|
+
# TODO: Optimize into one map iteration that produces names map, and sets
|
191
|
+
# count as side effect
|
192
|
+
method.parameters.each { |p| result[p[0]] += 1 }
|
193
|
+
from = result[:req]
|
194
|
+
to = result[:rest] > 0 ? :default : from + result[:opt]
|
195
|
+
names = method.parameters.map {|p| p[1].to_s }
|
196
|
+
else
|
197
|
+
# Cannot correctly compute the signature in Ruby 1.8.7 because arity for
|
198
|
+
# optional values is screwed up (there is no way to get the upper limit),
|
199
|
+
# an optional looks the same as a varargs In this case - the failure will
|
200
|
+
# simply come later when the call fails
|
201
|
+
#
|
202
|
+
arity = method.arity
|
203
|
+
from = arity >= 0 ? arity : -arity -1
|
204
|
+
to = arity >= 0 ? arity : :default # i.e. infinite (which is wrong when there are optional - flaw in 1.8.7)
|
205
|
+
names = [] # no names available
|
206
|
+
end
|
207
|
+
[from, to, names]
|
208
|
+
end
|
209
|
+
|
210
|
+
# Construct a signature consisting of Object type, with min, and max, and given names.
|
211
|
+
# (there is only one type entry). Note that this signature is Object, not Optional[Object].
|
212
|
+
#
|
213
|
+
# @api private
|
214
|
+
def self.object_signature(from, to, names)
|
215
|
+
# Construct the type for the signature
|
216
|
+
# Tuple[Object, from, to]
|
217
|
+
factory = Puppet::Pops::Types::TypeFactory
|
218
|
+
[factory.callable(factory.object, from, to), names]
|
219
|
+
end
|
220
|
+
|
221
|
+
# Function
|
222
|
+
# ===
|
223
|
+
# This class is the base class for all Puppet 4x Function API functions. A
|
224
|
+
# specialized class is created for each puppet function.
|
225
|
+
#
|
226
|
+
# @api public
|
227
|
+
class Function < Puppet::Pops::Functions::Function
|
228
|
+
|
229
|
+
# @api private
|
230
|
+
def self.builder
|
231
|
+
@type_parser ||= Puppet::Pops::Types::TypeParser.new
|
232
|
+
@all_callables ||= Puppet::Pops::Types::TypeFactory.all_callables
|
233
|
+
DispatcherBuilder.new(dispatcher, @type_parser, @all_callables)
|
234
|
+
end
|
235
|
+
|
236
|
+
# Dispatch any calls that match the signature to the provided method name.
|
237
|
+
#
|
238
|
+
# @param meth_name [Symbol] The name of the implementation method to call
|
239
|
+
# when the signature defined in the block matches the arguments to a call
|
240
|
+
# to the function.
|
241
|
+
# @return [Void]
|
242
|
+
#
|
243
|
+
# @api public
|
244
|
+
def self.dispatch(meth_name, &block)
|
245
|
+
builder().instance_eval do
|
246
|
+
dispatch(meth_name, &block)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Public api methods of the DispatcherBuilder are available within dispatch()
|
252
|
+
# blocks declared in a Puppet::Function.create_function() call.
|
253
|
+
#
|
254
|
+
# @api public
|
255
|
+
class DispatcherBuilder
|
256
|
+
# @api private
|
257
|
+
def initialize(dispatcher, type_parser, all_callables)
|
258
|
+
@type_parser = type_parser
|
259
|
+
@all_callables = all_callables
|
260
|
+
@dispatcher = dispatcher
|
261
|
+
end
|
262
|
+
|
263
|
+
# Defines a positional parameter with type and name
|
264
|
+
#
|
265
|
+
# @param type [String] The type specification for the parameter.
|
266
|
+
# @param name [String] The name of the parameter. This is primarily used
|
267
|
+
# for error message output and does not have to match the name of the
|
268
|
+
# parameter on the implementation method.
|
269
|
+
# @return [Void]
|
270
|
+
#
|
271
|
+
# @api public
|
272
|
+
def param(type, name)
|
273
|
+
if type.is_a?(String)
|
274
|
+
@types << type
|
275
|
+
@names << name
|
276
|
+
# mark what should be picked for this position when dispatching
|
277
|
+
@weaving << @names.size()-1
|
278
|
+
else
|
279
|
+
raise ArgumentError, "Type signature argument must be a String reference to a Puppet Data Type. Got #{type.class}"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# Defines one required block parameter that may appear last. If type and name is missing the
|
284
|
+
# default type is "Callable", and the name is "block". If only one
|
285
|
+
# parameter is given, then that is the name and the type is "Callable".
|
286
|
+
#
|
287
|
+
# @api public
|
288
|
+
def required_block_param(*type_and_name)
|
289
|
+
case type_and_name.size
|
290
|
+
when 0
|
291
|
+
type = @all_callables
|
292
|
+
name = 'block'
|
293
|
+
when 1
|
294
|
+
type = @all_callables
|
295
|
+
name = type_and_name[0]
|
296
|
+
when 2
|
297
|
+
type_string, name = type_and_name
|
298
|
+
type = @type_parser.parse(type_string)
|
299
|
+
else
|
300
|
+
raise ArgumentError, "block_param accepts max 2 arguments (type, name), got #{type_and_name.size}."
|
301
|
+
end
|
302
|
+
|
303
|
+
unless type.is_a?(Puppet::Pops::Types::PCallableType)
|
304
|
+
raise ArgumentError, "Expected PCallableType, got #{type.class}"
|
305
|
+
end
|
306
|
+
|
307
|
+
unless name.is_a?(String)
|
308
|
+
raise ArgumentError, "Expected block_param name to be a String, got #{name.class}"
|
309
|
+
end
|
310
|
+
|
311
|
+
if @block_type.nil?
|
312
|
+
@block_type = type
|
313
|
+
@block_name = name
|
314
|
+
else
|
315
|
+
raise ArgumentError, "Attempt to redefine block"
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Defines one optional block parameter that may appear last. If type or name is missing the
|
320
|
+
# defaults are "any callable", and the name is "block". The implementor of the dispatch target
|
321
|
+
# must use block = nil when it is optional (or an error is raised when the call is made).
|
322
|
+
#
|
323
|
+
# @api public
|
324
|
+
def optional_block_param(*type_and_name)
|
325
|
+
# same as required, only wrap the result in an optional type
|
326
|
+
required_block_param(*type_and_name)
|
327
|
+
@block_type = Puppet::Pops::Types::TypeFactory.optional(@block_type)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Specifies the min and max occurance of arguments (of the specified types)
|
331
|
+
# if something other than the exact count from the number of specified
|
332
|
+
# types). The max value may be specified as -1 if an infinite number of
|
333
|
+
# arguments are supported. When max is > than the number of specified
|
334
|
+
# types, the last specified type repeats.
|
335
|
+
#
|
336
|
+
# @api public
|
337
|
+
def arg_count(min_occurs, max_occurs)
|
338
|
+
@min = min_occurs
|
339
|
+
@max = max_occurs
|
340
|
+
unless min_occurs.is_a?(Integer) && min_occurs >= 0
|
341
|
+
raise ArgumentError, "min arg_count of function parameter must be an Integer >=0, got #{min_occurs.class} '#{min_occurs}'"
|
342
|
+
end
|
343
|
+
unless max_occurs == :default || (max_occurs.is_a?(Integer) && max_occurs >= 0)
|
344
|
+
raise ArgumentError, "max arg_count of function parameter must be an Integer >= 0, or :default, got #{max_occurs.class} '#{max_occurs}'"
|
345
|
+
end
|
346
|
+
unless max_occurs == :default || (max_occurs.is_a?(Integer) && max_occurs >= min_occurs)
|
347
|
+
raise ArgumentError, "max arg_count must be :default (infinite) or >= min arg_count, got min: '#{min_occurs}, max: '#{max_occurs}'"
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# Specifies that the last argument captures the rest.
|
352
|
+
#
|
353
|
+
# @api public
|
354
|
+
def last_captures_rest
|
355
|
+
@last_captures = true
|
356
|
+
end
|
357
|
+
|
358
|
+
private
|
359
|
+
|
360
|
+
# @api private
|
361
|
+
def dispatch(meth_name, &block)
|
362
|
+
# an array of either an index into names/types, or an array with
|
363
|
+
# injection information [type, name, injection_name] used when the call
|
364
|
+
# is being made to weave injections into the given arguments.
|
365
|
+
#
|
366
|
+
@types = []
|
367
|
+
@names = []
|
368
|
+
@weaving = []
|
369
|
+
@injections = []
|
370
|
+
@min = nil
|
371
|
+
@max = nil
|
372
|
+
@last_captures = false
|
373
|
+
@block_type = nil
|
374
|
+
@block_name = nil
|
375
|
+
self.instance_eval &block
|
376
|
+
callable_t = create_callable(@types, @block_type, @min, @max)
|
377
|
+
@dispatcher.add_dispatch(callable_t, meth_name, @names, @block_name, @injections, @weaving, @last_captures)
|
378
|
+
end
|
379
|
+
|
380
|
+
# Handles creation of a callable type from strings specifications of puppet
|
381
|
+
# types and allows the min/max occurs of the given types to be given as one
|
382
|
+
# or two integer values at the end. The given block_type should be
|
383
|
+
# Optional[Callable], Callable, or nil.
|
384
|
+
#
|
385
|
+
# @api private
|
386
|
+
def create_callable(types, block_type, from, to)
|
387
|
+
mapped_types = types.map do |t|
|
388
|
+
@type_parser.parse(t)
|
389
|
+
end
|
390
|
+
|
391
|
+
if !(from.nil? && to.nil?)
|
392
|
+
mapped_types << from
|
393
|
+
mapped_types << to
|
394
|
+
end
|
395
|
+
|
396
|
+
if block_type
|
397
|
+
mapped_types << block_type
|
398
|
+
end
|
399
|
+
|
400
|
+
Puppet::Pops::Types::TypeFactory.callable(*mapped_types)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
private
|
405
|
+
|
406
|
+
# @note WARNING: This style of creating functions is not public. It is a system
|
407
|
+
# under development that will be used for creating "system" functions.
|
408
|
+
#
|
409
|
+
# This is a private, internal, system for creating functions. It supports
|
410
|
+
# everything that the public function definition system supports as well as a
|
411
|
+
# few extra features.
|
412
|
+
#
|
413
|
+
# Injection Support
|
414
|
+
# ===
|
415
|
+
# The Function API supports injection of data and services. It is possible to
|
416
|
+
# make injection that takes effect when the function is loaded (for services
|
417
|
+
# and runtime configuration that does not change depending on how/from where
|
418
|
+
# in what context the function is called. It is also possible to inject and
|
419
|
+
# weave argument values into a call.
|
420
|
+
#
|
421
|
+
# Injection of attributes
|
422
|
+
# ---
|
423
|
+
# Injection of attributes is performed by one of the methods `attr_injected`,
|
424
|
+
# and `attr_injected_producer`. The injected attributes are available via
|
425
|
+
# accessor method calls.
|
426
|
+
#
|
427
|
+
# @example using injected attributes
|
428
|
+
# Puppet::Functions.create_function('test') do
|
429
|
+
# attr_injected String, :larger, 'message_larger'
|
430
|
+
# attr_injected String, :smaller, 'message_smaller'
|
431
|
+
# def test(a, b)
|
432
|
+
# a > b ? larger() : smaller()
|
433
|
+
# end
|
434
|
+
# end
|
435
|
+
#
|
436
|
+
# @api private
|
437
|
+
class InternalFunction < Function
|
438
|
+
# @api private
|
439
|
+
def self.builder
|
440
|
+
@type_parser ||= Puppet::Pops::Types::TypeParser.new
|
441
|
+
@all_callables ||= Puppet::Pops::Types::TypeFactory.all_callables
|
442
|
+
InternalDispatchBuilder.new(dispatcher, @type_parser, @all_callables)
|
443
|
+
end
|
444
|
+
|
445
|
+
# Defines class level injected attribute with reader method
|
446
|
+
#
|
447
|
+
# @api private
|
448
|
+
def self.attr_injected(type, attribute_name, injection_name = nil)
|
449
|
+
define_method(attribute_name) do
|
450
|
+
ivar = :"@#{attribute_name.to_s}"
|
451
|
+
unless instance_variable_defined?(ivar)
|
452
|
+
injector = Puppet.lookup(:injector)
|
453
|
+
instance_variable_set(ivar, injector.lookup(closure_scope, type, injection_name))
|
454
|
+
end
|
455
|
+
instance_variable_get(ivar)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
# Defines class level injected producer attribute with reader method
|
460
|
+
#
|
461
|
+
# @api private
|
462
|
+
def self.attr_injected_producer(type, attribute_name, injection_name = nil)
|
463
|
+
define_method(attribute_name) do
|
464
|
+
ivar = :"@#{attribute_name.to_s}"
|
465
|
+
unless instance_variable_defined?(ivar)
|
466
|
+
injector = Puppet.lookup(:injector)
|
467
|
+
instance_variable_set(ivar, injector.lookup_producer(closure_scope, type, injection_name))
|
468
|
+
end
|
469
|
+
instance_variable_get(ivar)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
# @note WARNING: This style of creating functions is not public. It is a system
|
475
|
+
# under development that will be used for creating "system" functions.
|
476
|
+
#
|
477
|
+
# Injection and Weaving of parameters
|
478
|
+
# ---
|
479
|
+
# It is possible to inject and weave parameters into a call. These extra
|
480
|
+
# parameters are not part of the parameters passed from the Puppet logic, and
|
481
|
+
# they can not be overridden by parameters given as arguments in the call.
|
482
|
+
# They are invisible to the Puppet Language.
|
483
|
+
#
|
484
|
+
# @example using injected parameters
|
485
|
+
# Puppet::Functions.create_function('test') do
|
486
|
+
# dispatch :test do
|
487
|
+
# param 'Scalar', 'a'
|
488
|
+
# param 'Scalar', 'b'
|
489
|
+
# injected_param 'String', 'larger', 'message_larger'
|
490
|
+
# injected_param 'String', 'smaller', 'message_smaller'
|
491
|
+
# end
|
492
|
+
# def test(a, b, larger, smaller)
|
493
|
+
# a > b ? larger : smaller
|
494
|
+
# end
|
495
|
+
# end
|
496
|
+
#
|
497
|
+
# The function in the example above is called like this:
|
498
|
+
#
|
499
|
+
# test(10, 20)
|
500
|
+
#
|
501
|
+
# Using injected value as default
|
502
|
+
# ---
|
503
|
+
# Default value assignment is handled by using the regular Ruby mechanism (a
|
504
|
+
# value is assigned to the variable). The dispatch simply indicates that the
|
505
|
+
# value is optional. If the default value should be injected, it can be
|
506
|
+
# handled different ways depending on what is desired:
|
507
|
+
#
|
508
|
+
# * by calling the accessor method for an injected Function class attribute.
|
509
|
+
# This is suitable if the value is constant across all instantiations of the
|
510
|
+
# function, and across all calls.
|
511
|
+
# * by injecting a parameter into the call
|
512
|
+
# to the left of the parameter, and then assigning that as the default value.
|
513
|
+
# * One of the above forms, but using an injected producer instead of a
|
514
|
+
# directly injected value.
|
515
|
+
#
|
516
|
+
# @example method with injected default values
|
517
|
+
# Puppet::Functions.create_function('test') do
|
518
|
+
# dispatch :test do
|
519
|
+
# injected_param String, 'b_default', 'b_default_value_key'
|
520
|
+
# param 'Scalar', 'a'
|
521
|
+
# param 'Scalar', 'b'
|
522
|
+
# end
|
523
|
+
# def test(b_default, a, b = b_default)
|
524
|
+
# # ...
|
525
|
+
# end
|
526
|
+
# end
|
527
|
+
#
|
528
|
+
# @api private
|
529
|
+
class InternalDispatchBuilder < DispatcherBuilder
|
530
|
+
# TODO: is param name really needed? Perhaps for error messages? (it is unused now)
|
531
|
+
#
|
532
|
+
# @api private
|
533
|
+
def injected_param(type, name, injection_name = '')
|
534
|
+
@injections << [type, name, injection_name]
|
535
|
+
# mark what should be picked for this position when dispatching
|
536
|
+
@weaving << [@injections.size() -1]
|
537
|
+
end
|
538
|
+
|
539
|
+
# TODO: is param name really needed? Perhaps for error messages? (it is unused now)
|
540
|
+
#
|
541
|
+
# @api private
|
542
|
+
def injected_producer_param(type, name, injection_name = '')
|
543
|
+
@injections << [type, name, injection_name, :producer]
|
544
|
+
# mark what should be picked for this position when dispatching
|
545
|
+
@weaving << [@injections.size()-1]
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|