puppet 5.1.0-x64-mingw32 → 5.2.0-x64-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.

Files changed (108) hide show
  1. data/lib/puppet.rb +6 -53
  2. data/lib/puppet/application.rb +14 -7
  3. data/lib/puppet/application/agent.rb +6 -2
  4. data/lib/puppet/application/apply.rb +6 -2
  5. data/lib/puppet/application/cert.rb +6 -2
  6. data/lib/puppet/application/describe.rb +6 -2
  7. data/lib/puppet/application/device.rb +40 -29
  8. data/lib/puppet/application/doc.rb +6 -2
  9. data/lib/puppet/application/filebucket.rb +6 -2
  10. data/lib/puppet/application/lookup.rb +6 -2
  11. data/lib/puppet/application/master.rb +6 -2
  12. data/lib/puppet/application/resource.rb +6 -2
  13. data/lib/puppet/face/catalog.rb +1 -1
  14. data/lib/puppet/face/certificate_request.rb +1 -1
  15. data/lib/puppet/face/certificate_revocation_list.rb +1 -1
  16. data/lib/puppet/face/help.rb +17 -13
  17. data/lib/puppet/file_serving/configuration.rb +3 -0
  18. data/lib/puppet/file_serving/configuration/parser.rb +2 -0
  19. data/lib/puppet/file_serving/mount/tasks.rb +21 -0
  20. data/lib/puppet/functions/epp.rb +3 -0
  21. data/lib/puppet/functions/lookup.rb +2 -1
  22. data/lib/puppet/generate/models/type/property.rb +1 -1
  23. data/lib/puppet/gettext/config.rb +70 -0
  24. data/lib/puppet/gettext/stubs.rb +11 -0
  25. data/lib/puppet/indirector/request.rb +4 -4
  26. data/lib/puppet/info_service.rb +10 -0
  27. data/lib/puppet/info_service/task_information_service.rb +32 -0
  28. data/lib/puppet/module.rb +43 -12
  29. data/lib/puppet/module/task.rb +90 -0
  30. data/lib/puppet/parser/ast/leaf.rb +1 -1
  31. data/lib/puppet/parser/functions/dig.rb +11 -2
  32. data/lib/puppet/parser/functions/epp.rb +3 -0
  33. data/lib/puppet/parser/functions/new.rb +8 -8
  34. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  35. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -0
  36. data/lib/puppet/pops/issues.rb +11 -5
  37. data/lib/puppet/pops/loader/static_loader.rb +1 -1
  38. data/lib/puppet/pops/model/factory.rb +42 -2
  39. data/lib/puppet/pops/model/model_tree_dumper.rb +1 -1
  40. data/lib/puppet/pops/parser/egrammar.ra +30 -9
  41. data/lib/puppet/pops/parser/eparser.rb +1094 -1043
  42. data/lib/puppet/pops/patterns.rb +1 -1
  43. data/lib/puppet/pops/serialization/from_data_converter.rb +1 -1
  44. data/lib/puppet/pops/serialization/json_path.rb +1 -1
  45. data/lib/puppet/pops/serialization/to_data_converter.rb +12 -3
  46. data/lib/puppet/pops/types/p_object_type.rb +31 -3
  47. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +3 -3
  48. data/lib/puppet/pops/types/p_timespan_type.rb +1 -1
  49. data/lib/puppet/pops/types/p_timestamp_type.rb +1 -1
  50. data/lib/puppet/pops/types/string_converter.rb +15 -12
  51. data/lib/puppet/pops/types/type_calculator.rb +1 -1
  52. data/lib/puppet/pops/types/type_factory.rb +7 -0
  53. data/lib/puppet/pops/types/type_formatter.rb +1 -1
  54. data/lib/puppet/pops/types/type_mismatch_describer.rb +86 -130
  55. data/lib/puppet/pops/types/type_parser.rb +10 -4
  56. data/lib/puppet/pops/types/types.rb +81 -22
  57. data/lib/puppet/provider/package/aix.rb +4 -4
  58. data/lib/puppet/provider/package/yum.rb +1 -0
  59. data/lib/puppet/type.rb +1 -1
  60. data/lib/puppet/type/mount.rb +1 -1
  61. data/lib/puppet/type/sshkey.rb +9 -1
  62. data/lib/puppet/util.rb +1 -1
  63. data/lib/puppet/util/command_line.rb +1 -1
  64. data/lib/puppet/util/log.rb +15 -10
  65. data/lib/puppet/util/windows/api_types.rb +9 -5
  66. data/lib/puppet/util/windows/process.rb +9 -1
  67. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -3
  68. data/lib/puppet/version.rb +1 -1
  69. data/locales/ja/puppet.po +9270 -0
  70. data/locales/puppet.pot +272 -212
  71. data/spec/fixtures/unit/provider/package/yum/yum-check-update-plugin-output.txt +36 -0
  72. data/spec/integration/indirector/file_content/file_server_spec.rb +17 -0
  73. data/spec/integration/indirector/file_metadata/file_server_spec.rb +10 -0
  74. data/spec/integration/util/windows/process_spec.rb +45 -0
  75. data/spec/lib/puppet_spec/modules.rb +10 -0
  76. data/spec/shared_contexts/types_setup.rb +19 -4
  77. data/spec/spec_helper.rb +6 -7
  78. data/spec/unit/face/help_spec.rb +2 -2
  79. data/spec/unit/file_serving/configuration_spec.rb +14 -4
  80. data/spec/unit/file_serving/mount/modules_spec.rb +1 -1
  81. data/spec/unit/file_serving/mount/tasks_spec.rb +72 -0
  82. data/spec/unit/functions/epp_spec.rb +5 -0
  83. data/spec/unit/functions/regsubst_spec.rb +1 -1
  84. data/spec/unit/gettext_config_spec.rb +57 -0
  85. data/spec/unit/indirector/request_spec.rb +41 -0
  86. data/spec/unit/info_service_spec.rb +66 -2
  87. data/spec/unit/module_spec.rb +81 -1
  88. data/spec/unit/parser/ast/leaf_spec.rb +3 -4
  89. data/spec/unit/pops/evaluator/access_ops_spec.rb +5 -0
  90. data/spec/unit/pops/factory_spec.rb +5 -1
  91. data/spec/unit/pops/parser/parser_spec.rb +138 -0
  92. data/spec/unit/pops/serialization/to_from_hr_spec.rb +74 -1
  93. data/spec/unit/pops/types/p_init_type_spec.rb +1 -1
  94. data/spec/unit/pops/types/p_object_type_spec.rb +217 -33
  95. data/spec/unit/pops/types/p_timespan_type_spec.rb +7 -0
  96. data/spec/unit/pops/types/p_timestamp_type_spec.rb +7 -0
  97. data/spec/unit/pops/types/string_converter_spec.rb +48 -11
  98. data/spec/unit/pops/types/type_calculator_spec.rb +37 -5
  99. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -0
  100. data/spec/unit/pops/types/type_parser_spec.rb +25 -0
  101. data/spec/unit/pops/validator/validator_spec.rb +2 -2
  102. data/spec/unit/provider/package/aix_spec.rb +26 -1
  103. data/spec/unit/provider/package/yum_spec.rb +10 -0
  104. data/spec/unit/task_spec.rb +102 -0
  105. data/spec/unit/util/log_spec.rb +32 -3
  106. data/spec/unit/util/windows/api_types_spec.rb +51 -0
  107. metadata +3488 -3452
  108. checksums.yaml +0 -7
@@ -5,6 +5,7 @@ require 'puppet/file_serving/mount/file'
5
5
  require 'puppet/file_serving/mount/modules'
6
6
  require 'puppet/file_serving/mount/plugins'
7
7
  require 'puppet/file_serving/mount/pluginfacts'
8
+ require 'puppet/file_serving/mount/tasks'
8
9
 
9
10
  class Puppet::FileServing::Configuration
10
11
  require 'puppet/file_serving/configuration/parser'
@@ -82,6 +83,8 @@ class Puppet::FileServing::Configuration
82
83
  @mounts["plugins"].allow('*') if @mounts["plugins"].empty?
83
84
  @mounts["pluginfacts"] ||= Mount::PluginFacts.new("pluginfacts")
84
85
  @mounts["pluginfacts"].allow('*') if @mounts["pluginfacts"].empty?
86
+ @mounts["tasks"] ||= Mount::Tasks.new("tasks")
87
+ @mounts["tasks"].allow('*') if @mounts["tasks"].empty?
85
88
  end
86
89
 
87
90
  # Read the configuration file.
@@ -92,6 +92,8 @@ class Puppet::FileServing::Configuration::Parser
92
92
  mount = Mount::Modules.new(name)
93
93
  when "plugins"
94
94
  mount = Mount::Plugins.new(name)
95
+ when "tasks"
96
+ mount = Mount::Tasks.new(name)
95
97
  else
96
98
  mount = Mount::File.new(name)
97
99
  end
@@ -0,0 +1,21 @@
1
+ require 'puppet/file_serving/mount'
2
+
3
+ class Puppet::FileServing::Mount::Tasks < Puppet::FileServing::Mount
4
+ def find(path, request)
5
+ raise _("No task specified") if path.to_s.empty?
6
+ module_name, task_path = path.split("/", 2)
7
+ return nil unless mod = request.environment.module(module_name)
8
+
9
+ mod.task_file(task_path)
10
+ end
11
+
12
+ def search(path, request)
13
+ if result = find(path, request)
14
+ [result]
15
+ end
16
+ end
17
+
18
+ def valid?
19
+ true
20
+ end
21
+ end
@@ -21,6 +21,9 @@
21
21
  # `epp('apache/vhost/_docroot.epp', { 'docroot' => '/var/www/html',
22
22
  # 'virtual_docroot' => '/var/www/example' })`
23
23
  #
24
+ # This function can also accept an absolute path, which can load a template file
25
+ # from anywhere on disk.
26
+ #
24
27
  # Puppet produces a syntax error if you pass more parameters than are declared in
25
28
  # the template's parameter tag. When passing parameters to a template that
26
29
  # contains a parameter tag, use the same names as the tag's declared parameters.
@@ -96,7 +96,8 @@
96
96
  # * `{'strategy' => 'deep', <DEEP OPTION> => <VALUE>, ...}` --- Same as `'deep'`,
97
97
  # but can adjust the merge with additional options. The available options are:
98
98
  # * `'knockout_prefix'` (string or undef) --- A string prefix to indicate a
99
- # value should be _removed_ from the final result. Defaults to `undef`, which
99
+ # value should be _removed_ from the final result. If a value is exactly equal
100
+ # to the prefix, it will knockout the entire element. Defaults to `undef`, which
100
101
  # disables this feature.
101
102
  # * `'sort_merged_arrays'` (boolean) --- Whether to sort all arrays that are
102
103
  # merged together. Defaults to `false`.
@@ -40,7 +40,7 @@ module Puppet
40
40
  values = property.value_collection.instance_variable_get('@values') || {}
41
41
  values.each do |_, value|
42
42
  if value.regex?
43
- regexes << "/#{value.name.source.gsub(/\//, '\/')}/"
43
+ regexes << Puppet::Pops::Types::StringConverter.convert(value.name, '%p')
44
44
  next
45
45
  end
46
46
 
@@ -0,0 +1,70 @@
1
+ require 'puppet/util/platform'
2
+
3
+ module Puppet::GettextConfig
4
+ LOCAL_PATH = File.absolute_path('../../../locales', File.dirname(__FILE__))
5
+ POSIX_PATH = File.absolute_path('../../../../../share/locale', File.dirname(__FILE__))
6
+ WINDOWS_PATH = File.absolute_path('../../../../../../../puppet/share/locale', File.dirname(__FILE__))
7
+
8
+ # Search for puppet gettext config files
9
+ # @return [String] path to the config, or nil if not found
10
+ def self.puppet_locale_path
11
+ if File.exist?(LOCAL_PATH)
12
+ return LOCAL_PATH
13
+ elsif Puppet::Util::Platform.windows? && File.exist?(WINDOWS_PATH)
14
+ return WINDOWS_PATH
15
+ elsif !Puppet::Util::Platform.windows? && File.exist?(POSIX_PATH)
16
+ return POSIX_PATH
17
+ else
18
+ nil
19
+ end
20
+ end
21
+
22
+ # Determine which translation file format to use
23
+ # @param conf_path [String] the path to the gettext config file
24
+ # @return [Symbol] :mo if in a package structure, :po otherwise
25
+ def self.translation_mode(conf_path)
26
+ if WINDOWS_PATH == conf_path || POSIX_PATH == conf_path
27
+ return :mo
28
+ else
29
+ return :po
30
+ end
31
+ end
32
+
33
+ # Attempt to initialize the gettext-setup gem
34
+ # @param path [String] to gettext config file
35
+ # @param file_format [Symbol] translation file format to use, either :po or :mo
36
+ # @return true if initialization succeeded, false otherwise
37
+ def self.initialize(conf_file_location, file_format)
38
+ unless file_format == :po || file_format == :mo
39
+ raise Puppet::Error, "Unsupported translation file format #{file_format}; please use :po or :mo"
40
+ end
41
+
42
+ begin
43
+ require 'gettext-setup'
44
+ require 'locale'
45
+
46
+ if conf_file_location && File.exists?(conf_file_location)
47
+ if GettextSetup.method(:initialize).parameters.count == 1
48
+ # For use with old gettext-setup gem versions, will load PO files only
49
+ GettextSetup.initialize(conf_file_location)
50
+ else
51
+ GettextSetup.initialize(conf_file_location, :file_format => file_format)
52
+ end
53
+ # Only change this once.
54
+ # Because negotiate_locales will only return a non-default locale if
55
+ # the system locale matches a translation set actually available for the
56
+ # given gettext project, we don't want this to get set back to default if
57
+ # we load a module that doesn't have translations, but Puppet does have
58
+ # translations for the user's locale.
59
+ if FastGettext.locale == GettextSetup.default_locale
60
+ FastGettext.locale = GettextSetup.negotiate_locale(Locale.current.language)
61
+ end
62
+ true
63
+ else
64
+ false
65
+ end
66
+ rescue LoadError
67
+ false
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ # These stub the translation methods noramlly brought in
2
+ # by FastGettext. Used when Gettext could not be properly
3
+ # initialized.
4
+ def _(msg)
5
+ msg
6
+ end
7
+
8
+ def n_(*args, &block)
9
+ plural = args[2] == 1 ? args[0] : args[1]
10
+ block ? block.call : plural
11
+ end
@@ -199,7 +199,7 @@ class Puppet::Indirector::Request
199
199
  if primary_server = Puppet.settings[:server_list][0]
200
200
  bound_server = primary_server[0]
201
201
  else
202
- bound_server = nil
202
+ bound_server = Puppet.settings[:server]
203
203
  end
204
204
  end
205
205
 
@@ -209,11 +209,11 @@ class Puppet::Indirector::Request
209
209
  if primary_server = Puppet.settings[:server_list][0]
210
210
  bound_port = primary_server[1]
211
211
  else
212
- bound_port = nil
212
+ bound_port = Puppet.settings[:masterport]
213
213
  end
214
214
  end
215
- self.server = default_server || bound_server || Puppet.settings[:server]
216
- self.port = default_port || bound_port || Puppet.settings[:masterport]
215
+ self.server = default_server || bound_server
216
+ self.port = default_port || bound_port
217
217
 
218
218
  Puppet.debug "No more servers left, falling back to #{self.server}:#{self.port}" if Puppet.settings[:use_srv_records]
219
219
 
@@ -1,7 +1,17 @@
1
1
 
2
2
  module Puppet::InfoService
3
3
  require 'puppet/info_service/class_information_service'
4
+ require 'puppet/info_service/task_information_service'
5
+
4
6
  def self.classes_per_environment(env_file_hash)
5
7
  Puppet::InfoService::ClassInformationService.new.classes_per_environment(env_file_hash)
6
8
  end
9
+
10
+ def self.tasks_per_environment(environment_name)
11
+ Puppet::InfoService::TaskInformationService.tasks_per_environment(environment_name)
12
+ end
13
+
14
+ def self.task_data(environment_name, module_name, task_name)
15
+ Puppet::InfoService::TaskInformationService.task_data(environment_name, module_name, task_name)
16
+ end
7
17
  end
@@ -0,0 +1,32 @@
1
+ class Puppet::InfoService::TaskInformationService
2
+ require 'puppet/module'
3
+
4
+ def self.tasks_per_environment(environment_name)
5
+ # get the actual environment object, raise error if the named env doesn't exist
6
+ env = Puppet.lookup(:environments).get!(environment_name)
7
+ env.modules.map do |mod|
8
+ mod.tasks.map do |task|
9
+ {:module => {:name => task.module.name}, :name => task.name}
10
+ end
11
+ end.flatten
12
+ end
13
+
14
+ def self.task_data(environment_name, module_name, task_name)
15
+ # raise EnvironmentNotFound if applicable
16
+ Puppet.lookup(:environments).get!(environment_name)
17
+
18
+ pup_module = Puppet::Module.find(module_name, environment_name)
19
+ if pup_module.nil?
20
+ raise Puppet::Module::MissingModule, _("Module %{module_name} not found in environment %{environment_name}.") %
21
+ {module_name: module_name, environment_name: environment_name}
22
+ end
23
+
24
+ task = pup_module.tasks.find { |t| t.name == task_name }
25
+ if task.nil?
26
+ raise Puppet::Module::Task::TaskNotFound, _("Task %{task_name} not found in module %{module_name}.") %
27
+ {task_name: task_name, module_name: module_name}
28
+ end
29
+
30
+ {:metadata_file => task.metadata_file, :files => task.files}
31
+ end
32
+ end
data/lib/puppet/module.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'puppet/util/logging'
2
+ require 'puppet/module/task'
2
3
  require 'json'
3
4
  require 'semantic_puppet/gem_version'
4
5
 
@@ -79,7 +80,7 @@ class Puppet::Module
79
80
  end
80
81
  end
81
82
 
82
- attr_reader :name, :environment, :path, :metadata
83
+ attr_reader :name, :environment, :path, :metadata, :tasks
83
84
  attr_writer :environment
84
85
 
85
86
  attr_accessor :dependencies, :forge_name
@@ -97,15 +98,7 @@ class Puppet::Module
97
98
  @absolute_path_to_manifests = Puppet::FileSystem::PathPattern.absolute(manifests)
98
99
 
99
100
  # i18n initialization for modules
100
- if Puppet::GETTEXT_AVAILABLE
101
- begin
102
- initialize_i18n
103
- rescue Exception => e
104
- Puppet.warning _("GettextSetup initialization for %{module_name} failed with: %{error_message}") % { module_name: name, error_message: e.message }
105
- end
106
- else
107
- Puppet.warning _("GettextSetup is not available, skipping GettextSetup initialization for %{module_name}.") % { module_name: name }
108
- end
101
+ initialize_i18n
109
102
  end
110
103
 
111
104
  # @deprecated The puppetversion module metadata field is no longer used.
@@ -169,6 +162,39 @@ class Puppet::Module
169
162
  end
170
163
  end
171
164
 
165
+ def tasks_directory
166
+ subpath("tasks")
167
+ end
168
+
169
+ def tasks
170
+ return @tasks if instance_variable_defined?(:@tasks)
171
+
172
+ if Puppet::FileSystem.exist?(tasks_directory)
173
+ @tasks = Puppet::Module::Task.tasks_in_module(self)
174
+ else
175
+ @tasks = []
176
+ end
177
+ end
178
+
179
+ # This is a re-implementation of the Filetypes singular type method (e.g.
180
+ # `manifest('my/manifest.pp')`. We don't implement the full filetype "API" for
181
+ # tasks since tasks don't map 1:1 onto files.
182
+ def task_file(name)
183
+ # If 'file' is nil then they're asking for the base path.
184
+ # This is used for things like fileserving.
185
+ if name
186
+ full_path = File.join(tasks_directory, name)
187
+ else
188
+ full_path = tasks_directory
189
+ end
190
+
191
+ if Puppet::FileSystem.exist?(full_path)
192
+ return full_path
193
+ else
194
+ return nil
195
+ end
196
+ end
197
+
172
198
  def license_file
173
199
  return @license_file if defined?(@license_file)
174
200
 
@@ -403,7 +429,7 @@ class Puppet::Module
403
429
  locales_path = File.absolute_path('locales', path)
404
430
 
405
431
  begin
406
- GettextSetup.initialize(locales_path)
432
+ Puppet::GettextConfig.initialize(locales_path, :po)
407
433
  Puppet.debug "#{module_name} initialized for i18n: #{GettextSetup.translation_repositories[module_name]}"
408
434
  rescue
409
435
  config_path = File.absolute_path('config.yaml', locales_path)
@@ -414,7 +440,12 @@ class Puppet::Module
414
440
  private
415
441
 
416
442
  def i18n_initialized?(module_name)
417
- GettextSetup.translation_repositories.has_key? module_name
443
+ begin
444
+ GettextSetup.translation_repositories.has_key? module_name
445
+ rescue NameError
446
+ # GettextSetup not yet initialized
447
+ false
448
+ end
418
449
  end
419
450
 
420
451
  def wanted_manifests_from(pattern)
@@ -0,0 +1,90 @@
1
+ require 'json'
2
+ require 'puppet/util/logging'
3
+
4
+ class Puppet::Module
5
+ class Task
6
+ class Error < Puppet::Error; end
7
+ class InvalidName < Error; end
8
+ class InvalidFile < Error; end
9
+ class TaskNotFound < Error; end
10
+
11
+ FORBIDDEN_EXTENSIONS = %w{.conf .md}
12
+
13
+ def self.is_task_name?(name)
14
+ return true if name =~ /^[a-z][a-z0-9_]*$/
15
+ return false
16
+ end
17
+
18
+ # Determine whether a file has a legal name for either a task's executable or metadata file.
19
+ def self.is_tasks_filename?(path)
20
+ name_less_extension = File.basename(path, '.*')
21
+ return false if not is_task_name?(name_less_extension)
22
+ FORBIDDEN_EXTENSIONS.each do |ext|
23
+ return false if path.end_with?(ext)
24
+ end
25
+ return true
26
+ end
27
+
28
+ def self.is_tasks_metadata_filename?(name)
29
+ is_tasks_filename?(name) && name.end_with?('.json')
30
+ end
31
+
32
+ def self.is_tasks_executable_filename?(name)
33
+ is_tasks_filename?(name) && !name.end_with?('.json')
34
+ end
35
+
36
+ def self.tasks_in_module(pup_module)
37
+ Dir.glob(File.join(pup_module.tasks_directory, '*'))
38
+ .keep_if { |f| is_tasks_filename?(f) }
39
+ .group_by { |f| task_name_from_path(f) }
40
+ .map { |task, files| new_with_files(pup_module, task, files) }
41
+ end
42
+
43
+ attr_reader :name, :module, :metadata_file, :files
44
+
45
+ def initialize(pup_module, task_name, files, metadata_file = nil)
46
+ if !Puppet::Module::Task.is_task_name?(task_name)
47
+ raise InvalidName, _("Task names must start with a lowercase letter and be composed of only lowercase letters, numbers, and underscores")
48
+ end
49
+
50
+ all_files = metadata_file.nil? ? files : files + [metadata_file]
51
+ all_files.each do |f|
52
+ if !f.start_with?(pup_module.tasks_directory)
53
+ msg = _("The file '%{path}' is not located in the %{module_name} module's tasks directory") %
54
+ {path: f.to_s, module_name: pup_module.name}
55
+
56
+ # we can include some extra context for the log message:
57
+ Puppet.err(msg + " (#{pup_module.tasks_directory})")
58
+ raise InvalidFile, msg
59
+ end
60
+ end
61
+
62
+ name = task_name == "init" ? pup_module.name : "#{pup_module.name}::#{task_name}"
63
+
64
+ @module = pup_module
65
+ @name = name
66
+ @metadata_file = metadata_file if metadata_file
67
+ @files = files
68
+ end
69
+
70
+ def ==(other)
71
+ self.name == other.name &&
72
+ self.module == other.module
73
+ end
74
+
75
+ private
76
+
77
+ def self.new_with_files(pup_module, name, tasks_files)
78
+ files = tasks_files.map do |filename|
79
+ File.join(pup_module.tasks_directory, File.basename(filename))
80
+ end
81
+
82
+ metadata_files, exe_files = files.partition { |f| is_tasks_metadata_filename?(f) }
83
+ Puppet::Module::Task.new(pup_module, name, exe_files, metadata_files.first)
84
+ end
85
+
86
+ def self.task_name_from_path(path)
87
+ return File.basename(path, '.*')
88
+ end
89
+ end
90
+ end
@@ -70,6 +70,6 @@ class Puppet::Parser::AST::Regex < Puppet::Parser::AST::Leaf
70
70
  end
71
71
 
72
72
  def to_s
73
- "/#{@value.source}/"
73
+ Puppet::Pops::Types::PRegexpType.regexp_to_s_with_delimiters(@value)
74
74
  end
75
75
  end
@@ -3,7 +3,8 @@ Puppet::Parser::Functions::newfunction(
3
3
  :type => :rvalue,
4
4
  :arity => -1,
5
5
  :doc => <<-DOC
6
- Returns a value for a sequence of given keys/indexes into a structure.
6
+ Returns a value for a sequence of given keys/indexes into a structure, such as
7
+ an array or hash.
7
8
  This function is used to "dig into" a complex data structure by
8
9
  using a sequence of keys / indexes to access a value from which
9
10
  the next key/index is accessed recursively.
@@ -13,15 +14,23 @@ The first encountered `undef` value or key stops the "dig" and `undef` is return
13
14
  An error is raised if an attempt is made to "dig" into
14
15
  something other than an `undef` (which immediately returns `undef`), an `Array` or a `Hash`.
15
16
 
17
+
18
+
16
19
  **Example:** Using `dig`
17
20
 
18
21
  ```puppet
19
22
  $data = {a => { b => [{x => 10, y => 20}, {x => 100, y => 200}]}}
20
- notice $data.dig(a, b, 1, x)
23
+ notice $data.dig('a', 'b', 1, 'x')
21
24
  ```
22
25
 
23
26
  Would notice the value 100.
24
27
 
28
+ This is roughly equivalent to `$data['a']['b'][1]['x']`. However, a standard
29
+ index will return an error and cause catalog compilation failure if any parent
30
+ of the final key (`'x'`) is `undef`. The `dig` function will return undef,
31
+ rather than failing catalog compilation. This allows you to check if data
32
+ exists in a structure without mandating that it always exists.
33
+
25
34
  * Since 4.5.0
26
35
  DOC
27
36
  ) do |args|